OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /w11/tags/w11a_V0.7/tools/src/librw11
    from Rev 32 to Rev 33
    Reverse comparison

Rev 32 → Rev 33

/Rw11CntlTM11.hpp
0,0 → 1,180
// $Id: Rw11CntlTM11.hpp 690 2015-06-07 18:23:51Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CntlTM11.hpp 690 2015-06-07 18:23:51Z mueller $
\brief Declaration of class Rw11CntlTM11.
*/
 
#ifndef included_Retro_Rw11CntlTM11
#define included_Retro_Rw11CntlTM11 1
 
#include "Rw11CntlBase.hpp"
#include "Rw11UnitTM11.hpp"
#include "Rw11Rdma.hpp"
 
namespace Retro {
 
class Rw11CntlTM11 : public Rw11CntlBase<Rw11UnitTM11,4> {
public:
 
Rw11CntlTM11();
~Rw11CntlTM11();
 
void Config(const std::string& name, uint16_t base, int lam);
 
virtual void Start();
 
virtual bool BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart);
 
virtual void UnitSetup(size_t ind);
 
void SetChunkSize(size_t chunk);
size_t ChunkSize() const;
 
const Rstats& RdmaStats() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kIbaddr = 0172520; //!< TM11 default address
static const int kLam = 7; //!< TM11 default lam
 
static const uint16_t kTMSR = 000; //!< TMSR reg offset
static const uint16_t kTMCR = 002; //!< TMCR reg offset
static const uint16_t kTMBC = 004; //!< TMBC reg offset
static const uint16_t kTMBA = 006; //!< TMBA reg offset
static const uint16_t kTMDB = 010; //!< TMDB reg offset
static const uint16_t kTMRL = 012; //!< TMRL reg offset
 
static const uint16_t kProbeOff = kTMCR; //!< probe address offset (tmcr)
static const bool kProbeInt = true; //!< probe int active
static const bool kProbeRem = true; //!< probr rem active
 
static const uint16_t kTMSR_M_ICMD = kWBit15; //!< ICMD: invalid cmd
static const uint16_t kTMSR_M_EOF = kWBit14; //!< EOF: end-of-file seen
static const uint16_t kTMSR_M_PAE = kWBit12; //!< PAE: parity error
static const uint16_t kTMSR_M_EOT = kWBit10; //!< EOT: end-of-tape seen
static const uint16_t kTMSR_M_RLE = kWBit09; //!< RLE: record lgth error
static const uint16_t kTMSR_M_BTE = kWBit08; //!< BTE: bad tape error
static const uint16_t kTMSR_M_NXM = kWBit07; //!< NXM: non-existent mem
static const uint16_t kTMSR_M_ONL = kWBit06; //!< ONL: online
static const uint16_t kTMSR_M_BOT = kWBit05; //!< BOT: at begin-of-tape
static const uint16_t kTMSR_M_WRL = kWBit02; //!< WRL: write locked
static const uint16_t kTMSR_M_REW = kWBit01; //!< REW: tape rewound
static const uint16_t kTMSR_M_TUR = kWBit00; //!< TUR: unit ready
 
static const uint16_t kTMCR_V_ERR = 15;
static const uint16_t kTMCR_V_DEN = 13;
static const uint16_t kTMCR_B_DEN = 0003;
static const uint16_t kTMCR_V_UNIT = 8;
static const uint16_t kTMCR_B_UNIT = 0007;
static const uint16_t kTMCR_M_RDY = kWBit07;
static const uint16_t kTMCR_V_EA = 4;
static const uint16_t kTMCR_B_EA = 0003;
static const uint16_t kTMCR_V_FUNC = 1;
static const uint16_t kTMCR_B_FUNC = 0007;
static const uint16_t kTMCR_M_GO = kWBit00;
 
static const uint16_t kFUNC_UNLOAD = 0;
static const uint16_t kFUNC_READ = 1;
static const uint16_t kFUNC_WRITE = 2;
static const uint16_t kFUNC_WEOF = 3;
static const uint16_t kFUNC_SFORW = 4;
static const uint16_t kFUNC_SBACK = 5;
static const uint16_t kFUNC_WEIRG = 6;
static const uint16_t kFUNC_REWIND = 7;
// remote function codes
static const uint16_t kRFUNC_WUNIT = 1;
static const uint16_t kRFUNC_DONE = 2;
 
// cr usage or rem func=wunit
static const uint16_t kTMCR_V_RUNIT = 4;
static const uint16_t kTMCR_B_RUNIT = 0003;
// cr usage or rem func=done
static const uint16_t kTMCR_M_RICMD = kWBit15;
static const uint16_t kTMCR_M_RPAE = kWBit12;
static const uint16_t kTMCR_M_RRLE = kWBit09;
static const uint16_t kTMCR_M_RBTE = kWBit08;
static const uint16_t kTMCR_M_RNXM = kWBit07;
static const uint16_t kTMCR_M_REAENA = kWBit06;
static const uint16_t kTMCR_V_REA = 4;
static const uint16_t kTMCR_B_REA = 0003;
 
// rem usage of TMRL (used to access unit specific TMSR fields)
static const uint16_t kTMRL_M_EOF = kWBit10; //!< EOF: end-of-file seen
static const uint16_t kTMRL_M_EOT = kWBit09; //!< EOT: end-of-tape seen
static const uint16_t kTMRL_M_ONL = kWBit08; //!< ONL: online
static const uint16_t kTMRL_M_BOT = kWBit07; //!< BOT: at begin-of-tape
static const uint16_t kTMRL_M_WRL = kWBit06; //!< WRL: write locked
static const uint16_t kTMRL_M_REW = kWBit05; //!< REW: tape rewinding
 
// statistics counter indices
enum stats {
kStatNFuncUnload= Rw11Cntl::kDimStat, //!< func UNLOAD
kStatNFuncRead, //!< func READ
kStatNFuncWrite, //!< func WRITE
kStatNFuncWeof, //!< func WEOF
kStatNFuncSforw, //!< func SFORW
kStatNFuncSback, //!< func SBACK
kStatNFuncWrteg, //!< func WRTEG
kStatNFuncRewind, //!< func REWIND
kDimStat
};
 
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
void RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
RlinkCommandList& clist);
void RdmaPostExecCB(int stat, size_t ndone,
RlinkCommandList& clist, size_t ncmd);
void AddErrorExit(RlinkCommandList& clist, uint16_t tmcr);
void AddFastExit(RlinkCommandList& clist, int opcode,
size_t ndone);
void AddNormalExit(RlinkCommandList& clist, size_t ndone,
uint16_t tmcr=0);
void WriteLog(const char* func, RerrMsg& emsg);
 
protected:
size_t fPC_tmcr; //!< PrimClist: tmcr index
size_t fPC_tmsr; //!< PrimClist: tmsr index
size_t fPC_tmbc; //!< PrimClist: tmbc index
size_t fPC_tmba; //!< PrimClist: tmba index
 
uint16_t fRd_tmcr; //!< Rdma: request tmcr
uint16_t fRd_tmsr; //!< Rdma: request tmsr
uint16_t fRd_tmbc; //!< Rdma: request tmbc
uint16_t fRd_tmba; //!< Rdma: request tmba
uint32_t fRd_bc; //!< Rdma: request bc
uint32_t fRd_addr; //!< Rdma: current addr
uint32_t fRd_nwrd; //!< Rdma: current nwrd
uint16_t fRd_fu; //!< Rdma: request fu code
int fRd_opcode; //!< Rdma: read opcode
std::vector<uint16_t> fBuf; //!< data buffer
Rw11Rdma fRdma; //!< Rdma controller
};
} // end namespace Retro
 
#include "Rw11CntlTM11.ipp"
 
#endif
/Rw11CntlTM11.cpp
0,0 → 1,649
// $Id: Rw11CntlTM11.cpp 690 2015-06-07 18:23:51Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
// Other credits:
// the boot code is from the simh project and Copyright Robert M Supnik
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-06 690 1.0.1 BUGFIX: AddFastExit() check for Virt() defined
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlTM11.cpp 690 2015-06-07 18:23:51Z mueller $
\brief Implemenation of Rw11CntlTM11.
*/
 
#include "boost/bind.hpp"
#include "boost/foreach.hpp"
#define foreach_ BOOST_FOREACH
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintBvi.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
#include "librtools/RlogMsg.hpp"
 
#include "Rw11CntlTM11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11CntlTM11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11CntlTM11::kIbaddr;
const int Rw11CntlTM11::kLam;
 
const uint16_t Rw11CntlTM11::kTMSR;
const uint16_t Rw11CntlTM11::kTMCR;
const uint16_t Rw11CntlTM11::kTMBC;
const uint16_t Rw11CntlTM11::kTMBA;
const uint16_t Rw11CntlTM11::kTMDB;
const uint16_t Rw11CntlTM11::kTMRL;
 
const uint16_t Rw11CntlTM11::kProbeOff;
const bool Rw11CntlTM11::kProbeInt;
const bool Rw11CntlTM11::kProbeRem;
 
const uint16_t Rw11CntlTM11::kTMSR_M_ICMD;
const uint16_t Rw11CntlTM11::kTMSR_M_EOF;
const uint16_t Rw11CntlTM11::kTMSR_M_PAE;
const uint16_t Rw11CntlTM11::kTMSR_M_EOT;
const uint16_t Rw11CntlTM11::kTMSR_M_RLE;
const uint16_t Rw11CntlTM11::kTMSR_M_BTE;
const uint16_t Rw11CntlTM11::kTMSR_M_NXM;
const uint16_t Rw11CntlTM11::kTMSR_M_ONL;
const uint16_t Rw11CntlTM11::kTMSR_M_BOT;
const uint16_t Rw11CntlTM11::kTMSR_M_WRL;
const uint16_t Rw11CntlTM11::kTMSR_M_REW;
const uint16_t Rw11CntlTM11::kTMSR_M_TUR;
 
const uint16_t Rw11CntlTM11::kTMCR_V_ERR;
const uint16_t Rw11CntlTM11::kTMCR_V_DEN;
const uint16_t Rw11CntlTM11::kTMCR_B_DEN;
const uint16_t Rw11CntlTM11::kTMCR_V_UNIT;
const uint16_t Rw11CntlTM11::kTMCR_B_UNIT;
const uint16_t Rw11CntlTM11::kTMCR_M_RDY;
const uint16_t Rw11CntlTM11::kTMCR_V_EA;
const uint16_t Rw11CntlTM11::kTMCR_B_EA;
const uint16_t Rw11CntlTM11::kTMCR_V_FUNC;
const uint16_t Rw11CntlTM11::kTMCR_B_FUNC;
const uint16_t Rw11CntlTM11::kTMCR_M_GO;
 
const uint16_t Rw11CntlTM11::kFUNC_UNLOAD;
const uint16_t Rw11CntlTM11::kFUNC_READ;
const uint16_t Rw11CntlTM11::kFUNC_WRITE ;
const uint16_t Rw11CntlTM11::kFUNC_WEOF;
const uint16_t Rw11CntlTM11::kFUNC_SFORW;
const uint16_t Rw11CntlTM11::kFUNC_SBACK;
const uint16_t Rw11CntlTM11::kFUNC_WEIRG;
const uint16_t Rw11CntlTM11::kFUNC_REWIND;
 
const uint16_t Rw11CntlTM11::kRFUNC_WUNIT;
const uint16_t Rw11CntlTM11::kRFUNC_DONE;
 
const uint16_t Rw11CntlTM11::kTMCR_M_RICMD;
const uint16_t Rw11CntlTM11::kTMCR_M_RPAE;
const uint16_t Rw11CntlTM11::kTMCR_M_RRLE;
const uint16_t Rw11CntlTM11::kTMCR_M_RBTE;
const uint16_t Rw11CntlTM11::kTMCR_M_RNXM;
const uint16_t Rw11CntlTM11::kTMCR_M_REAENA;
const uint16_t Rw11CntlTM11::kTMCR_V_REA;
const uint16_t Rw11CntlTM11::kTMCR_B_REA;
 
const uint16_t Rw11CntlTM11::kTMRL_M_EOF;
const uint16_t Rw11CntlTM11::kTMRL_M_EOT;
const uint16_t Rw11CntlTM11::kTMRL_M_ONL;
const uint16_t Rw11CntlTM11::kTMRL_M_BOT;
const uint16_t Rw11CntlTM11::kTMRL_M_WRL;
const uint16_t Rw11CntlTM11::kTMRL_M_REW;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11CntlTM11::Rw11CntlTM11()
: Rw11CntlBase<Rw11UnitTM11,4>("tm11"),
fPC_tmcr(0),
fPC_tmsr(0),
fPC_tmbc(0),
fPC_tmba(0),
fRd_tmcr(0),
fRd_tmsr(0),
fRd_tmbc(0),
fRd_tmba(0),
fRd_bc(0),
fRd_addr(0),
fRd_nwrd(0),
fRd_fu(0),
fRd_opcode(0),
fBuf(),
fRdma(this,
boost::bind(&Rw11CntlTM11::RdmaPreExecCB, this, _1, _2, _3, _4),
boost::bind(&Rw11CntlTM11::RdmaPostExecCB, this, _1, _2, _3, _4))
{
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
for (size_t i=0; i<NUnit(); i++) {
fspUnit[i].reset(new Rw11UnitTM11(this, i));
}
 
fStats.Define(kStatNFuncUnload , "NFuncUnload" , "func UNLOAD");
fStats.Define(kStatNFuncRead , "NFuncRead" , "func READ");
fStats.Define(kStatNFuncWrite , "NFuncWrite" , "func WRITE");
fStats.Define(kStatNFuncWeof , "NFuncWeof" , "func WEOF");
fStats.Define(kStatNFuncSforw , "NFuncSforw" , "func SFORW");
fStats.Define(kStatNFuncSback , "NFuncSback" , "func SBACK");
fStats.Define(kStatNFuncWrteg , "NFuncWrteg" , "func WRTEG");
fStats.Define(kStatNFuncRewind , "NFuncRewind" , "func REWIND");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11CntlTM11::~Rw11CntlTM11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::Config(const std::string& name, uint16_t base, int lam)
{
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::Start()
{
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
throw Rexception("Rw11CntlTM11::Start",
"Bad state: started, no lam, not enable, not found");
 
// add device register address ibus and rbus mappings
// done here because now Cntl bound to Cpu and Cntl probed
Cpu().AllIAddrMapInsert(Name()+".sr", Base() + kTMSR);
Cpu().AllIAddrMapInsert(Name()+".cr", Base() + kTMCR);
Cpu().AllIAddrMapInsert(Name()+".bc", Base() + kTMBC);
Cpu().AllIAddrMapInsert(Name()+".ba", Base() + kTMBA);
Cpu().AllIAddrMapInsert(Name()+".db", Base() + kTMDB);
Cpu().AllIAddrMapInsert(Name()+".rl", Base() + kTMRL);
 
// setup primary info clist
fPrimClist.Clear();
fPrimClist.AddAttn();
fPC_tmcr = Cpu().AddRibr(fPrimClist, fBase+kTMCR);
fPC_tmsr = Cpu().AddRibr(fPrimClist, fBase+kTMSR);
fPC_tmbc = Cpu().AddRibr(fPrimClist, fBase+kTMBC);
fPC_tmba = Cpu().AddRibr(fPrimClist, fBase+kTMBA);
 
// add attn handler
Server().AddAttnHandler(boost::bind(&Rw11CntlTM11::AttnHandler, this, _1),
uint16_t(1)<<fLam, (void*)this);
 
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::UnitSetup(size_t ind)
{
Rw11UnitTM11& unit = *fspUnit[ind];
Rw11Cpu& cpu = Cpu();
RlinkCommandList clist;
 
uint16_t tmds = 0;
if (unit.Virt()) { // file attached
tmds |= kTMRL_M_ONL;
if (unit.Virt()->WProt()) tmds |= kTMRL_M_WRL;
if (unit.Virt()->Bot()) tmds |= kTMRL_M_BOT;
}
unit.SetTmds(tmds);
cpu.AddWibr(clist, fBase+kTMCR, (uint16_t(ind)<<kTMCR_V_RUNIT)|
(kRFUNC_WUNIT<<kTMCR_V_FUNC) );
cpu.AddWibr(clist, fBase+kTMRL, tmds);
Server().Exec(clist);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11CntlTM11::BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart)
{
uint16_t kBOOT_START = 02000;
uint16_t bootcode[] = { // tm11 boot loader - from simh pdp11_tm.c (v3.9)
0046524, // boot_start: "TM"
0012706, kBOOT_START, // mov #boot_start, sp
0012700, uint16_t(unit), // mov #unit_num, r0
0012701, 0172526, // mov #172526, r1 ; #tmba
0005011, // clr (r1) ; tmba = 0
0012741, 0177777, // mov #-1, -(r1) ; tmbc = -1
0010002, // mov r0,r2
0000302, // swab r2
0062702, 0060011, // add #60011, r2
0010241, // mov r2, -(r1) ; tmcr = space + go
0105711, // tstb (r1) ; test tmcr.rdy
0100376, // bpl .-2
0010002, // mov r0,r2 ; note: tmbc=0 now
0000302, // swab r2
0062702, 0060003, // add #60003, r2 ; note: tmbc still = 0!
0010211, // mov r2, (r1) ; tmcr = read + go
0105711, // tstb (r1) ; test tmcr.rdy
0100376, // bpl .-2
0005002, // clr r2
0005003, // clr r3
0012704, uint16_t(kBOOT_START+020), // mov #boot_start+20, r4
0005005, // clr r5
0005007 // clr r7
};
code.clear();
foreach_ (uint16_t& w, bootcode) code.push_back(w);
aload = kBOOT_START;
astart = kBOOT_START+2;
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlTM11 @ " << this << endl;
os << bl << " fPC_tmcr: " << RosPrintf(fPC_tmcr,"d",6) << endl;
os << bl << " fPC_tmsr: " << RosPrintf(fPC_tmsr,"d",6) << endl;
os << bl << " fPC_tmbc: " << RosPrintf(fPC_tmbc,"d",6) << endl;
os << bl << " fPC_tmba: " << RosPrintf(fPC_tmba,"d",6) << endl;
os << bl << " fRd_tmcr: " << RosPrintBvi(fRd_tmcr,8) << endl;
os << bl << " fRd_tmsr: " << RosPrintBvi(fRd_tmsr,8) << endl;
os << bl << " fRd_tmbc: " << RosPrintBvi(fRd_tmbc,8) << endl;
os << bl << " fRd_tmba: " << RosPrintBvi(fRd_tmba,8) << endl;
os << bl << " fRd_bc: " << RosPrintf(fRd_bc,"d",6) << endl;
os << bl << " fRd_addr: " << RosPrintBvi(fRd_addr,8,18) << endl;
os << bl << " fRd_nwrd: " << RosPrintf(fRd_nwrd,"d",6) << endl;
os << bl << " fRd_fu: " << fRd_fu << endl;
os << bl << " fRd_opcode: " << fRd_opcode << endl;
os << bl << " fBuf.size() " << RosPrintf(fBuf.size(),"d",6) << endl;
fRdma.Dump(os, ind+2, "fRdma: ");
Rw11CntlBase<Rw11UnitTM11,4>::Dump(os, ind, " ^");
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11CntlTM11::AttnHandler(RlinkServer::AttnArgs& args)
{
fStats.Inc(kStatNAttnHdl);
Server().GetAttnInfo(args, fPrimClist);
 
uint16_t tmcr = fPrimClist[fPC_tmcr].Data();
uint16_t tmsr = fPrimClist[fPC_tmsr].Data();
uint16_t tmbc = fPrimClist[fPC_tmbc].Data();
uint16_t tmba = fPrimClist[fPC_tmba].Data();
 
uint16_t unum = (tmcr>>kTMCR_V_UNIT) & kTMCR_B_UNIT;
uint16_t ea = (tmcr>>kTMCR_V_EA) & kTMCR_B_EA;
uint16_t fu = (tmcr>>kTMCR_V_FUNC) & kTMCR_B_FUNC;
 
uint32_t addr = uint32_t(ea)<<16 | uint32_t(tmba);
 
// Note: a zero tmbc translates into nbyt=64k !
// correct behaviour, the boot loaded actually issues a read
// with tmbc=0 to read the boot block into memory !!
uint32_t nbyt = (~uint32_t(tmbc)&0xffff) + 1; // transfer size in bytes
 
//Rw11Cpu& cpu = Cpu();
RlinkCommandList clist;
 
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
static const char* fumnemo[8] =
{"un ","rd ","wr ","we ","sf ","sb ","wi ","re "};
lmsg << "-I TM11"
<< " fu=" << fumnemo[fu&07]
<< " un=" << unum
<< " cr=" << RosPrintBvi(tmcr,8)
<< " ad=" << RosPrintBvi(addr,8,18)
<< " bc=" << RosPrintBvi(tmbc,8)
<< " nb=";
if (nbyt==65536) lmsg << " (0)"; else lmsg << RosPrintf(nbyt,"d",5);
}
 
// check for spurious interrupts (either RDY=1 or RDY=0 and rdma busy)
if ((tmcr & kTMCR_M_RDY) || fRdma.IsActive()) {
RlogMsg lmsg(LogFile());
lmsg << "-E TM11 err "
<< " cr=" << RosPrintBvi(tmcr,8)
<< " spurious lam: "
<< (fRdma.IsActive() ? "RDY=0 and Rdma busy" : "RDY=1");
return 0;
}
 
// check for general abort conditions: invalid unit number
if (unum > NUnit()) {
AddErrorExit(clist, kTMCR_M_RICMD);
Server().Exec(clist);
return 0;
}
 
Rw11UnitTM11& unit = *fspUnit[unum];
 
// check for general abort conditions:
// - unit not attached
// - write to a write locked unit
bool wcmd = fu == kFUNC_WRITE ||
fu == kFUNC_WEIRG ||
fu == kFUNC_WEOF;
if ((!unit.Virt()) || (wcmd && unit.Virt()->WProt()) ) {
AddErrorExit(clist, kTMCR_M_RICMD);
Server().Exec(clist);
return 0;
}
 
// remember request parameters for call back and error exit handling
fRd_tmcr = tmcr;
fRd_tmsr = tmsr;
fRd_tmbc = tmbc;
fRd_tmba = tmba;
fRd_addr = addr;
fRd_fu = fu;
 
// now handle the functions
int opcode = Rw11VirtTape::kOpCodeOK;
RerrMsg emsg;
 
if (fu == kFUNC_UNLOAD) { // Unload ------------------------
fStats.Inc(kStatNFuncUnload);
unit.Detach();
AddFastExit(clist, opcode, 0);
RlogMsg lmsg(LogFile());
lmsg << "-I TM11"
<< " unit " << unum << "unload";
 
} else if (fu == kFUNC_READ) { // Read --------------------------
fStats.Inc(kStatNFuncRead);
size_t nwalloc = (nbyt+1)/2;
if (fBuf.size() < nwalloc) fBuf.resize(nwalloc);
size_t ndone;
bool rc = unit.VirtReadRecord(nbyt, reinterpret_cast<uint8_t*>(fBuf.data()),
ndone, fRd_opcode, emsg);
if (!rc) WriteLog("read", emsg);
if ((!rc) || ndone == 0) {
AddFastExit(clist, fRd_opcode, 0);
} else if (ndone&0x1) { // FIXME_code: add odd rlen handling
AddErrorExit(clist, kTMCR_M_RICMD|kTMSR_M_BTE); // now just bail out !!
} else {
size_t nwdma = ndone/2;
fRdma.QueueWMem(addr, fBuf.data(), nwdma,
Rw11Cpu::kCPAH_M_22BIT|Rw11Cpu::kCPAH_M_UBMAP);
}
 
} else if (fu == kFUNC_WRITE || // Write -------------------------
fu == kFUNC_WEIRG) {
fStats.Inc((fu==kFUNC_WRITE) ? kStatNFuncWrite : kStatNFuncWrteg);
size_t nwdma = (nbyt+1)/2;
if (fBuf.size() < nwdma) fBuf.resize(nwdma);
if (nbyt&0x1) { // FIXME_code: add odd rlen handling
AddErrorExit(clist, kTMCR_M_RICMD|kTMSR_M_BTE); // now just bail out !!
} else {
fRdma.QueueRMem(addr, fBuf.data(), nwdma,
Rw11Cpu::kCPAH_M_22BIT|Rw11Cpu::kCPAH_M_UBMAP);
}
 
} else if (fu == kFUNC_WEOF) { // Write Eof ---------------------
fStats.Inc(kStatNFuncWeof);
if (!unit.VirtWriteEof(emsg)) WriteLog("weof", emsg);
AddFastExit(clist, opcode, 0);
 
} else if (fu == kFUNC_SFORW) { // Space forward -----------------
fStats.Inc(kStatNFuncSforw);
size_t ndone;
if (!unit.VirtSpaceForw(nbyt, ndone, opcode, emsg)) WriteLog("sback", emsg);
AddFastExit(clist, opcode, ndone);
 
} else if (fu == kFUNC_SBACK) { // Space Backward ----------------
fStats.Inc(kStatNFuncSback);
size_t ndone;
if (!unit.VirtSpaceBack(nbyt, ndone, opcode, emsg)) WriteLog("sback", emsg);
AddFastExit(clist, opcode, ndone);
 
} else if (fu == kFUNC_REWIND) { // Rewind ------------------------
fStats.Inc(kStatNFuncRewind);
if (!unit.VirtRewind(opcode, emsg)) WriteLog("rewind", emsg);
AddFastExit(clist, opcode, 0);
}
 
if (clist.Size()) { // if handled directly
Server().Exec(clist); // doit
}
 
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
RlinkCommandList& clist)
{
// noop for TM11
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::RdmaPostExecCB(int stat, size_t ndone,
RlinkCommandList& clist, size_t ncmd)
{
if (stat == Rw11Rdma::kStatusBusy) return;
 
uint16_t tmcr = 0;
// handle Rdma aborts
if (stat == Rw11Rdma::kStatusFailRdma) tmcr |= kTMCR_M_RNXM;
 
// finally to TM11 register update
RlinkCommandList clist1;
AddNormalExit(clist1, ndone, tmcr);
Server().Exec(clist1);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::AddErrorExit(RlinkCommandList& clist, uint16_t tmcr)
{
Rw11Cpu& cpu = Cpu();
 
tmcr |= (kRFUNC_DONE<<kTMCR_V_FUNC);
cpu.AddWibr(clist, fBase+kTMCR, tmcr);
if (fTraceLevel>1) {
RlogMsg lmsg(LogFile());
lmsg << "-I TM11"
<< " err "
<< " "
<< " cr=" << RosPrintBvi(tmcr,8);
}
 
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::AddFastExit(RlinkCommandList& clist, int opcode, size_t ndone)
{
uint16_t unum = (fRd_tmcr>>kTMCR_V_UNIT) & kTMCR_B_UNIT;
Rw11UnitTM11& unit = *fspUnit[unum];
Rw11Cpu& cpu = Cpu();
 
uint16_t tmcr = 0;
uint16_t tmds = 0;
 
// AddFastExit() is also called after UNLOAD, which calls unit.Detach()
// So unlike in all other cases, Virt() may be 0, so check on this
if (unit.Virt()) {
tmds |= kTMRL_M_ONL;
if (unit.Virt()->WProt()) tmds |= kTMRL_M_WRL;
if (unit.Virt()->Bot()) tmds |= kTMRL_M_BOT;
if (unit.Virt()->Eot()) tmds |= kTMRL_M_EOT;
}
switch (opcode) {
 
case Rw11VirtTape::kOpCodeOK:
case Rw11VirtTape::kOpCodeBot:
break;
 
case Rw11VirtTape::kOpCodeEof:
tmds |= kTMRL_M_EOF;
break;
 
default:
tmcr |= kTMCR_M_RBTE;
break;
}
 
uint16_t tmbc = fRd_tmbc + uint16_t(ndone);
 
unit.SetTmds(tmds);
cpu.AddWibr(clist, fBase+kTMCR, (uint16_t(unum)<<kTMCR_V_RUNIT)|
(kRFUNC_WUNIT<<kTMCR_V_FUNC) );
cpu.AddWibr(clist, fBase+kTMRL, tmds);
if (ndone) cpu.AddWibr(clist, fBase+kTMBC, tmbc);
tmcr |= (kRFUNC_DONE<<kTMCR_V_FUNC);
cpu.AddWibr(clist, fBase+kTMCR, tmcr);
 
if (fTraceLevel>1) {
RlogMsg lmsg(LogFile());
bool err = tmcr & (kTMCR_M_RBTE);
lmsg << "-I TM11"
<< (err ? " err " :" ok ")
<< " un=" << unum
<< " cr=" << RosPrintBvi(tmcr,8)
<< " "
<< " bc=" << RosPrintBvi(tmbc,8)
<< " ds=" << RosPrintBvi(tmds,8);
}
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::AddNormalExit(RlinkCommandList& clist, size_t ndone,
uint16_t tmcr)
{
uint16_t unum = (fRd_tmcr>>kTMCR_V_UNIT) & kTMCR_B_UNIT;
Rw11UnitTM11& unit = *fspUnit[unum];
Rw11Cpu& cpu = Cpu();
 
uint16_t tmds = kTMRL_M_ONL;
if (unit.Virt()->WProt()) tmds |= kTMRL_M_WRL;
if (unit.Virt()->Bot()) tmds |= kTMRL_M_BOT;
if (unit.Virt()->Eot()) tmds |= kTMRL_M_EOT;
 
uint32_t addr = fRd_addr + 2*ndone;
uint16_t tmbc = fRd_tmbc + 2*uint16_t(ndone);
 
if (fRd_fu == kFUNC_READ) { // handle READ
switch (fRd_opcode) {
 
case Rw11VirtTape::kOpCodeOK:
break;
 
case Rw11VirtTape::kOpCodeRecLenErr:
tmcr |= kTMCR_M_RRLE;
break;
 
case Rw11VirtTape::kOpCodeBadParity:
tmcr |= kTMCR_M_RPAE;
break;
 
default:
tmcr |= kTMCR_M_RBTE;
break;
}
 
} else { // handle WRITE or WEIRG
int opcode;
RerrMsg emsg;
size_t nbyt = 2*ndone;
if (!unit.VirtWriteRecord(nbyt, reinterpret_cast<uint8_t*>(fBuf.data()),
opcode, emsg))
WriteLog("write", emsg);
}
 
uint16_t tmba = uint16_t(addr & 0xfffe);
uint16_t ea = uint16_t((addr>>16)&0x0003);
tmcr |= kTMCR_M_REAENA | (ea<<kTMCR_V_REA);
 
unit.SetTmds(tmds);
cpu.AddWibr(clist, fBase+kTMCR, (uint16_t(unum)<<kTMCR_V_RUNIT)|
(kRFUNC_WUNIT<<kTMCR_V_FUNC) );
cpu.AddWibr(clist, fBase+kTMRL, tmds);
cpu.AddWibr(clist, fBase+kTMBC, tmbc);
cpu.AddWibr(clist, fBase+kTMBA, tmba);
tmcr |= (kRFUNC_DONE<<kTMCR_V_FUNC);
cpu.AddWibr(clist, fBase+kTMCR, tmcr);
 
if (fTraceLevel>1) {
RlogMsg lmsg(LogFile());
bool err = tmcr & (kTMCR_M_RPAE|kTMCR_M_RRLE|kTMCR_M_RBTE|kTMCR_M_RNXM);
lmsg << "-I TM11"
<< (err ? " err " :" ok ")
<< " un=" << unum
<< " cr=" << RosPrintBvi(tmcr,8)
<< " ad=" << RosPrintBvi(addr,8,18)
<< " bc=" << RosPrintBvi(tmbc,8)
<< " ds=" << RosPrintBvi(tmds,8);
}
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlTM11::WriteLog(const char* func, RerrMsg& emsg)
{
RlogMsg lmsg(LogFile());
lmsg << "-E TM11"
<< " error for func=" << func
<< ":" << emsg;
 
return;
}
 
 
} // end namespace Retro
/Rw11UnitTM11.hpp
0,0 → 1,53
// $Id: Rw11UnitTM11.hpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-17 683 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitTM11.hpp 686 2015-06-04 21:08:08Z mueller $
\brief Declaration of class Rw11UnitTM11.
*/
 
#ifndef included_Retro_Rw11UnitTM11
#define included_Retro_Rw11UnitTM11 1
 
#include "Rw11UnitTapeBase.hpp"
 
namespace Retro {
 
class Rw11CntlTM11; // forw decl to avoid circular incl
 
class Rw11UnitTM11 : public Rw11UnitTapeBase<Rw11CntlTM11> {
public:
Rw11UnitTM11(Rw11CntlTM11* pcntl, size_t index);
~Rw11UnitTM11();
 
void SetTmds(uint16_t tmds);
uint16_t Tmds() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
uint16_t fTmds;
};
} // end namespace Retro
 
#include "Rw11UnitTM11.ipp"
 
#endif
/Rw11UnitTapeBase.ipp
0,0 → 1,99
// $Id: Rw11UnitTapeBase.ipp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitTapeBase.ipp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation (inline) of Rw11UnitTapeBase.
*/
 
#include "Rw11UnitTapeBase.hpp"
 
/*!
\class Retro::Rw11UnitTapeBase
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
template <class TC>
Rw11UnitTapeBase<TC>::Rw11UnitTapeBase(TC* pcntl, size_t index)
: Rw11UnitTape(pcntl, index),
fpCntl(pcntl)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
template <class TC>
Rw11UnitTapeBase<TC>::~Rw11UnitTapeBase()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
inline TC& Rw11UnitTapeBase<TC>::Cntl() const
{
return *fpCntl;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitTapeBase<TC>::Dump(std::ostream& os, int ind,
const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitTapeBase @ " << this << std::endl;
os << bl << " fpCntl: " << fpCntl << std::endl;
Rw11UnitTape::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitTapeBase<TC>::AttachDone()
{
// transfer, if defined, wprot and capacity from unit to virt
if (WProt()) Virt()->SetWProt(true);
if (Capacity()!=0 && Virt()->Capacity()==0) Virt()->SetCapacity(Capacity());
Cntl().UnitSetup(Index());
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitTapeBase<TC>::DetachDone()
{
Cntl().UnitSetup(Index());
return;
}
 
} // end namespace Retro
/Rw11CntlRK11.cpp
0,0 → 1,639
// $Id: Rw11CntlRK11.cpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
// Other credits:
// the boot code is from the simh project and Copyright Robert M Supnik
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 2.0.2 check for spurious lams
// 2015-02-17 647 2.0.1 use Nwrd2Nblk(); BUGFIX: revise RdmaPostExecCB()
// 2015-01-04 628 2.0 use Rw11RdmaDisk
// 2014-12-30 625 1.2 adopt to Rlink V4 attn logic
// 2014-12-25 621 1.1 adopt to 4k word ibus window
// 2014-06-14 562 1.0.1 Add stats
// 2013-04-20 508 1.0 Initial version
// 2013-02-10 485 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlRK11.cpp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation of Rw11CntlRK11.
*/
 
#include "boost/bind.hpp"
#include "boost/foreach.hpp"
#define foreach_ BOOST_FOREACH
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintBvi.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
#include "librtools/RlogMsg.hpp"
 
#include "Rw11CntlRK11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11CntlRK11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11CntlRK11::kIbaddr;
const int Rw11CntlRK11::kLam;
 
const uint16_t Rw11CntlRK11::kRKDS;
const uint16_t Rw11CntlRK11::kRKER;
const uint16_t Rw11CntlRK11::kRKCS;
const uint16_t Rw11CntlRK11::kRKWC;
const uint16_t Rw11CntlRK11::kRKBA;
const uint16_t Rw11CntlRK11::kRKDA;
const uint16_t Rw11CntlRK11::kRKMR;
 
const uint16_t Rw11CntlRK11::kProbeOff;
const bool Rw11CntlRK11::kProbeInt;
const bool Rw11CntlRK11::kProbeRem;
 
const uint16_t Rw11CntlRK11::kRKDS_M_ID;
const uint16_t Rw11CntlRK11::kRKDS_V_ID;
const uint16_t Rw11CntlRK11::kRKDS_B_ID;
const uint16_t Rw11CntlRK11::kRKDS_M_HDEN;
const uint16_t Rw11CntlRK11::kRKDS_M_DRU;
const uint16_t Rw11CntlRK11::kRKDS_M_SIN;
const uint16_t Rw11CntlRK11::kRKDS_M_SOK;
const uint16_t Rw11CntlRK11::kRKDS_M_DRY;
const uint16_t Rw11CntlRK11::kRKDS_M_ADRY;
const uint16_t Rw11CntlRK11::kRKDS_M_WPS;
const uint16_t Rw11CntlRK11::kRKDS_B_SC;
 
const uint16_t Rw11CntlRK11::kRKER_M_DRE;
const uint16_t Rw11CntlRK11::kRKER_M_OVR;
const uint16_t Rw11CntlRK11::kRKER_M_WLO;
const uint16_t Rw11CntlRK11::kRKER_M_PGE;
const uint16_t Rw11CntlRK11::kRKER_M_NXM;
const uint16_t Rw11CntlRK11::kRKER_M_NXD;
const uint16_t Rw11CntlRK11::kRKER_M_NXC;
const uint16_t Rw11CntlRK11::kRKER_M_NXS;
const uint16_t Rw11CntlRK11::kRKER_M_CSE;
const uint16_t Rw11CntlRK11::kRKER_M_WCE;
 
const uint16_t Rw11CntlRK11::kRKCS_M_MAINT;
const uint16_t Rw11CntlRK11::kRKCS_M_IBA;
const uint16_t Rw11CntlRK11::kRKCS_M_FMT;
const uint16_t Rw11CntlRK11::kRKCS_M_RWA;
const uint16_t Rw11CntlRK11::kRKCS_M_SSE;
const uint16_t Rw11CntlRK11::kRKCS_M_RDY;
const uint16_t Rw11CntlRK11::kRKCS_M_MEX;
const uint16_t Rw11CntlRK11::kRKCS_V_MEX;
const uint16_t Rw11CntlRK11::kRKCS_B_MEX;
const uint16_t Rw11CntlRK11::kRKCS_V_FUNC;
const uint16_t Rw11CntlRK11::kRKCS_B_FUNC;
const uint16_t Rw11CntlRK11::kRKCS_M_GO;
 
const uint16_t Rw11CntlRK11::kFUNC_CRESET;
const uint16_t Rw11CntlRK11::kFUNC_WRITE;
const uint16_t Rw11CntlRK11::kFUNC_READ;
const uint16_t Rw11CntlRK11::kFUNC_WCHK;
const uint16_t Rw11CntlRK11::kFUNC_SEEK;
const uint16_t Rw11CntlRK11::kFUNC_RCHK;
const uint16_t Rw11CntlRK11::kFUNC_DRESET;
const uint16_t Rw11CntlRK11::kFUNC_WLOCK;
 
const uint16_t Rw11CntlRK11::kRKDA_M_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_V_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_B_DRSEL;
const uint16_t Rw11CntlRK11::kRKDA_M_CYL;
const uint16_t Rw11CntlRK11::kRKDA_V_CYL;
const uint16_t Rw11CntlRK11::kRKDA_B_CYL;
const uint16_t Rw11CntlRK11::kRKDA_M_SUR;
const uint16_t Rw11CntlRK11::kRKDA_V_SUR;
const uint16_t Rw11CntlRK11::kRKDA_B_SUR;
const uint16_t Rw11CntlRK11::kRKDA_B_SC;
 
const uint16_t Rw11CntlRK11::kRKMR_M_RID;
const uint16_t Rw11CntlRK11::kRKMR_V_RID;
const uint16_t Rw11CntlRK11::kRKMR_M_CRDONE;
const uint16_t Rw11CntlRK11::kRKMR_M_SBCLR;
const uint16_t Rw11CntlRK11::kRKMR_M_CRESET;
const uint16_t Rw11CntlRK11::kRKMR_M_FDONE;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11CntlRK11::Rw11CntlRK11()
: Rw11CntlBase<Rw11UnitRK11,8>("rk11"),
fPC_rkwc(0),
fPC_rkba(0),
fPC_rkda(0),
fPC_rkmr(0),
fPC_rkcs(0),
fRd_rkcs(0),
fRd_rkda(0),
fRd_addr(0),
fRd_lba(0),
fRd_nwrd(0),
fRd_fu(0),
fRd_ovr(false),
fRdma(this,
boost::bind(&Rw11CntlRK11::RdmaPreExecCB, this, _1, _2, _3, _4),
boost::bind(&Rw11CntlRK11::RdmaPostExecCB, this, _1, _2, _3, _4))
{
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
for (size_t i=0; i<NUnit(); i++) {
fspUnit[i].reset(new Rw11UnitRK11(this, i));
}
 
fStats.Define(kStatNFuncCreset , "NFuncCreset" , "func CRESET");
fStats.Define(kStatNFuncWrite , "NFuncWrite" , "func WRITE");
fStats.Define(kStatNFuncRead , "NFuncRead" , "func READ");
fStats.Define(kStatNFuncWchk , "NFuncWchk" , "func WCHK");
fStats.Define(kStatNFuncSeek , "NFuncSeek" , "func SEEK");
fStats.Define(kStatNFuncRchk , "NFuncRchk" , "func RCHK");
fStats.Define(kStatNFuncDreset , "NFuncDreset" , "func DRESET");
fStats.Define(kStatNFuncWlock , "NFuncWlock " , "func WLOCK");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11CntlRK11::~Rw11CntlRK11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::Config(const std::string& name, uint16_t base, int lam)
{
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::Start()
{
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
throw Rexception("Rw11CntlRK11::Start",
"Bad state: started, no lam, not enable, not found");
 
// add device register address ibus and rbus mappings
// done here because now Cntl bound to Cpu and Cntl probed
Cpu().AllIAddrMapInsert(Name()+".ds", Base() + kRKDS);
Cpu().AllIAddrMapInsert(Name()+".er", Base() + kRKER);
Cpu().AllIAddrMapInsert(Name()+".cs", Base() + kRKCS);
Cpu().AllIAddrMapInsert(Name()+".wc", Base() + kRKWC);
Cpu().AllIAddrMapInsert(Name()+".ba", Base() + kRKBA);
Cpu().AllIAddrMapInsert(Name()+".da", Base() + kRKDA);
Cpu().AllIAddrMapInsert(Name()+".mr", Base() + kRKMR);
 
// setup primary info clist
fPrimClist.Clear();
fPrimClist.AddAttn();
fPC_rkwc = Cpu().AddRibr(fPrimClist, fBase+kRKWC);
fPC_rkba = Cpu().AddRibr(fPrimClist, fBase+kRKBA);
fPC_rkda = Cpu().AddRibr(fPrimClist, fBase+kRKDA);
fPC_rkmr = Cpu().AddRibr(fPrimClist, fBase+kRKMR); // read to monitor CRDONE
fPC_rkcs = Cpu().AddRibr(fPrimClist, fBase+kRKCS);
 
// add attn handler
Server().AddAttnHandler(boost::bind(&Rw11CntlRK11::AttnHandler, this, _1),
uint16_t(1)<<fLam, (void*)this);
 
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::UnitSetup(size_t ind)
{
Rw11UnitRK11& unit = *fspUnit[ind];
Rw11Cpu& cpu = Cpu();
RlinkCommandList clist;
 
uint16_t rkds = ind<<kRKDS_V_ID;
if (unit.Virt()) { // file attached
rkds |= kRKDS_M_HDEN; // always high density
rkds |= kRKDS_M_SOK; // always sector counter OK ?FIXME?
rkds |= kRKDS_M_DRY; // drive available
rkds |= kRKDS_M_ADRY; // access available
if (unit.WProt()) // in case write protected
rkds |= kRKDS_M_WPS;
}
unit.SetRkds(rkds);
cpu.AddWibr(clist, fBase+kRKDS, rkds);
Server().Exec(clist);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11CntlRK11::BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart)
{
uint16_t kBOOT_START = 02000;
uint16_t bootcode[] = { // rk11 boot loader - from simh pdp11_rk.c (v3.9)
0042113, // "KD"
0012706, kBOOT_START, // MOV #boot_start, SP
0012700, uint16_t(unit), // MOV #unit, R0 ; unit number
0010003, // MOV R0, R3
0000303, // SWAB R3
0006303, // ASL R3
0006303, // ASL R3
0006303, // ASL R3
0006303, // ASL R3
0006303, // ASL R3
0012701, 0177412, // MOV #RKDA, R1 ; rkda
0010311, // MOV R3, (R1) ; load da
0005041, // CLR -(R1) ; clear ba
0012741, 0177000, // MOV #-256.*2, -(R1) ; load wc
0012741, 0000005, // MOV #READ+GO, -(R1) ; read & go
0005002, // CLR R2
0005003, // CLR R3
0012704, uint16_t(kBOOT_START+020), // MOV #START+20, R4 ; ?? unclear ??
0005005, // CLR R5
0105711, // TSTB (R1)
0100376, // BPL .-4
0105011, // CLRB (R1)
0005007 // CLR PC (5007)
};
code.clear();
foreach_ (uint16_t& w, bootcode) code.push_back(w);
aload = kBOOT_START;
astart = kBOOT_START+2;
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlRK11 @ " << this << endl;
os << bl << " fPC_rkwc: " << fPC_rkwc << endl;
os << bl << " fPC_rkba: " << fPC_rkba << endl;
os << bl << " fPC_rkda: " << fPC_rkda << endl;
os << bl << " fPC_rkmr: " << fPC_rkmr << endl;
os << bl << " fPC_rkcs: " << fPC_rkcs << endl;
os << bl << " fRd_rkcs: " << fRd_rkcs << endl;
os << bl << " fRd_rkda: " << fRd_rkda << endl;
os << bl << " fRd_addr: " << fRd_addr << endl;
os << bl << " fRd_lba: " << fRd_lba << endl;
os << bl << " fRd_nwrd: " << fRd_nwrd << endl;
os << bl << " fRd_fu: " << fRd_fu << endl;
os << bl << " fRd_ovr: " << fRd_ovr << endl;
fRdma.Dump(os, ind+2, "fRdma: ");
Rw11CntlBase<Rw11UnitRK11,8>::Dump(os, ind, " ^");
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11CntlRK11::AttnHandler(RlinkServer::AttnArgs& args)
{
fStats.Inc(kStatNAttnHdl);
Server().GetAttnInfo(args, fPrimClist);
 
uint16_t rkwc = fPrimClist[fPC_rkwc].Data();
uint16_t rkba = fPrimClist[fPC_rkba].Data();
uint16_t rkda = fPrimClist[fPC_rkda].Data();
//uint16_t rkmr = fPrimClist[fPC_rkmr].Data();
uint16_t rkcs = fPrimClist[fPC_rkcs].Data();
 
uint16_t se = rkda & kRKDA_B_SC;
uint16_t hd = (rkda>>kRKDA_V_SUR) & kRKDA_B_SUR;
uint16_t cy = (rkda>>kRKDA_V_CYL) & kRKDA_B_CYL;
uint16_t dr = (rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
bool go = rkcs & kRKCS_M_GO;
uint16_t fu = (rkcs>>kRKCS_V_FUNC) & kRKCS_B_FUNC;
uint16_t mex = (rkcs>>kRKCS_V_MEX) & kRKCS_B_MEX;
uint32_t addr = uint32_t(mex)<<16 | uint32_t(rkba);
 
// Note: apparently are operands first promoted to 32 bit -> mask after ~ !
uint32_t nwrd = (~uint32_t(rkwc)&0xffff) + 1; // transfer size in words
 
if (!go) {
RlogMsg lmsg(LogFile());
lmsg << "-I RK11 cs=" << RosPrintBvi(rkcs,8)
<< " go=0, spurious attn, dropped";
return 0;
}
// all 8 units are always available, but check anyway
if (dr > NUnit())
throw Rexception("Rw11CntlRK11::AttnHandler","Bad state: dr > NUnit()");
 
Rw11UnitRK11& unit = *fspUnit[dr];
Rw11Cpu& cpu = Cpu();
RlinkCommandList clist;
 
uint32_t lba = unit.Chs2Lba(cy,hd,se);
uint32_t nblk = unit.Nwrd2Nblk(nwrd);
 
uint16_t rker = 0;
uint16_t rkds = unit.Rkds();
 
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
static const char* fumnemo[8] = {"cr","w ","r ","wc","sk","rc","dr","wl"};
lmsg << "-I RK11 cs=" << RosPrintBvi(rkcs,8)
<< " da=" << RosPrintBvi(rkda,8)
<< " ad=" << RosPrintBvi(addr,8,18)
<< " fu=" << fumnemo[fu&0x7]
<< " pa=" << dr
<< "," << RosPrintf(cy,"d",3)
<< "," << hd
<< "," << RosPrintf(se,"d",2)
<< " la,nw=" << RosPrintf(lba,"d",4)
<< "," << RosPrintf(nwrd,"d",5);
}
 
// check for spurious interrupts (either RDY=1 or RDY=0 and rdma busy)
if ((rkcs & kRKCS_M_RDY) || fRdma.IsActive()) {
RlogMsg lmsg(LogFile());
lmsg << "-E RK11 err "
<< " cr=" << RosPrintBvi(rkcs,8)
<< " spurious lam: "
<< (fRdma.IsActive() ? "RDY=0 and Rdma busy" : "RDY=1");
return 0;
}
 
// check for general abort conditions
if (fu != kFUNC_CRESET && // function not control reset
(!unit.Virt())) { // and drive not attached
rker = kRKER_M_NXD; // --> abort with NXD error
 
} else if (fu != kFUNC_WRITE && // function neither write
fu != kFUNC_READ && // nor read
(rkcs & (kRKCS_M_FMT|kRKCS_M_RWA))) { // and FMT or RWA set
rker = kRKER_M_PGE; // --> abort with PGE error
} else if (rkcs & kRKCS_M_RWA) { // RWA not supported
rker = kRKER_M_DRE; // --> abort with DRE error
}
if (rker) {
cpu.AddWibr(clist, fBase+kRKER, rker);
if (fu == kFUNC_SEEK || fu == kFUNC_DRESET)
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_SBCLR | (1u<<dr));
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
LogRker(rker);
Server().Exec(clist);
return 0;
}
 
// check for overrun (read/write beyond cylinder 203)
// if found, truncate request length
bool ovr = lba + nblk > unit.NBlock();
if (ovr) nwrd = (unit.NBlock()-lba) * (unit.BlockSize()/2);
 
// remember request parameters for call back
fRd_rkcs = rkcs;
fRd_rkda = rkda;
fRd_addr = addr;
fRd_lba = lba;
fRd_nwrd = nwrd;
fRd_ovr = ovr;
fRd_fu = fu;
 
// now handle the functions
if (fu == kFUNC_CRESET) { // Control reset -----------------
fStats.Inc(kStatNFuncCreset);
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_CRESET);
 
} else if (fu == kFUNC_WRITE) { // Write -------------------------
// Note: WRITE+FMT is just WRITE
fStats.Inc(kStatNFuncWrite);
if (se >= unit.NSector()) rker |= kRKER_M_NXS;
if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
if (unit.WProt()) rker |= kRKER_M_WLO;
if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE; // IBA not supported
if (rker) {
AddErrorExit(clist, rker);
} else {
fRdma.QueueDiskWrite(addr, nwrd,
Rw11Cpu::kCPAH_M_22BIT|Rw11Cpu::kCPAH_M_UBMAP,
lba, &unit);
}
 
} else if (fu == kFUNC_READ) { // Read --------------------------
fStats.Inc(kStatNFuncRead);
if (se >= unit.NSector()) rker |= kRKER_M_NXS;
if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE; // IBA not supported
if (rker) {
AddErrorExit(clist, rker);
} else {
fRdma.QueueDiskRead(addr, nwrd,
Rw11Cpu::kCPAH_M_22BIT|Rw11Cpu::kCPAH_M_UBMAP,
lba, &unit);
}
 
} else if (fu == kFUNC_WCHK) { // Write Check -------------------
fStats.Inc(kStatNFuncWchk);
if (se >= unit.NSector()) rker |= kRKER_M_NXS;
if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE; // IBA not supported
if (rker) {
AddErrorExit(clist, rker);
} else {
fRdma.QueueDiskWriteCheck(addr, nwrd,
Rw11Cpu::kCPAH_M_22BIT|Rw11Cpu::kCPAH_M_UBMAP,
lba, &unit);
}
 
} else if (fu == kFUNC_SEEK) { // Seek --------------------------
fStats.Inc(kStatNFuncSeek);
if (se >= unit.NSector()) rker |= kRKER_M_NXS;
if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
if (rker) {
cpu.AddWibr(clist, fBase+kRKER, rker);
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_SBCLR | (1u<<dr));
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
LogRker(rker);
} else {
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
rkds &= ~kRKDS_B_SC; // replace current sector number
rkds |= se;
unit.SetRkds(rkds);
cpu.AddWibr(clist, fBase+kRKDS, rkds);
cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr); // issue seek done
}
 
} else if (fu == kFUNC_RCHK) { // Read Check --------------------
fStats.Inc(kStatNFuncRchk);
if (se >= unit.NSector()) rker |= kRKER_M_NXS;
if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE; // IBA not supported
if (rker) {
AddErrorExit(clist, rker);
} else {
AddNormalExit(clist, nwrd, 0); // no action, virt disks don't err
}
} else if (fu == kFUNC_DRESET) { // Drive Reset -------------------
fStats.Inc(kStatNFuncDreset);
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr); // issue seek done
} else if (fu == kFUNC_WLOCK) { // Write Lock --------------------
fStats.Inc(kStatNFuncWlock);
rkds |= kRKDS_M_WPS; // set RKDS write protect flag
unit.SetRkds(rkds);
unit.SetWProt(true);
cpu.AddWibr(clist, fBase+kRKDS, rkds);
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
}
 
if (clist.Size()) { // if handled directly
Server().Exec(clist); // doit
}
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
RlinkCommandList& clist)
{
// if last chunk and not doing WCHK add a labo and normal exit csr update
if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kFUNC_WCHK) {
clist.AddLabo();
AddNormalExit(clist, nwdone+nwnext, 0);
}
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::RdmaPostExecCB(int stat, size_t ndone,
RlinkCommandList& clist, size_t ncmd)
{
if (stat == Rw11Rdma::kStatusBusy) return;
 
uint16_t rker = 0;
 
// handle write check
if (fRd_fu == kFUNC_WCHK) {
size_t nwcok = fRdma.WriteCheck(ndone);
if (nwcok != ndone) { // if mismatch found
rker |= kRKER_M_WCE; // set error flag
if (fRd_rkcs & kRKCS_M_SSE) { // if 'stop-on-soft' requested
ndone = nwcok; // truncate word count
}
}
}
// handle Rdma aborts
if (stat == Rw11Rdma::kStatusFailRdma) rker |= kRKER_M_NXM;
 
// check for fused csr updates
if (clist.Size() > ncmd) {
uint8_t ccode = clist[ncmd].Command();
uint16_t cdata = clist[ncmd].Data();
if (ccode != RlinkCommand::kCmdLabo || (rker != 0 && cdata == 0))
throw Rexception("Rw11CntlRK11::RdmaPostExecCB",
"Bad state: Labo not found or missed abort");
if (cdata == 0) return;
}
 
// finally to RK11 register update
RlinkCommandList clist1;
AddNormalExit(clist1, ndone, rker);
Server().Exec(clist1);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::LogRker(uint16_t rker)
{
RlogMsg lmsg(LogFile());
lmsg << "-E RK11 er=" << RosPrintBvi(rker,8) << " ERROR ABORT";
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::AddErrorExit(RlinkCommandList& clist, uint16_t rker)
{
Rw11Cpu& cpu = Cpu();
cpu.AddWibr(clist, fBase+kRKER, rker);
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
LogRker(rker);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRK11::AddNormalExit(RlinkCommandList& clist, size_t ndone,
uint16_t rker)
{
Rw11Cpu& cpu = Cpu();
uint16_t dr = (fRd_rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
Rw11UnitRK11& unit = *fspUnit[dr];
 
size_t nblk = unit.Nwrd2Nblk(ndone);
 
uint32_t addr = fRd_addr + 2*ndone;
size_t lba = fRd_lba + nblk;
uint32_t nrest = fRd_nwrd - ndone;
 
uint16_t ba = addr & 0177776; // get lower 16 bits
uint16_t mex = (addr>>16) & 03; // get upper 2 bits
uint16_t cs = (fRd_rkcs & ~kRKCS_M_MEX) | (mex << kRKCS_V_MEX);
uint16_t se;
uint16_t hd;
uint16_t cy;
unit.Lba2Chs(lba, cy,hd,se);
uint16_t da = (fRd_rkda & kRKDA_M_DRSEL) | (cy<<kRKDA_V_CYL) |
(hd<<kRKDA_V_SUR) | se;
 
if (fRd_ovr) rker |= kRKER_M_OVR;
 
if (rker) {
cpu.AddWibr(clist, fBase+kRKER, rker);
LogRker(rker);
}
cpu.AddWibr(clist, fBase+kRKWC, uint16_t((-nrest)&0177777));
cpu.AddWibr(clist, fBase+kRKBA, ba);
cpu.AddWibr(clist, fBase+kRKDA, da);
if (cs != fRd_rkcs)
cpu.AddWibr(clist, fBase+kRKCS, cs);
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
 
return;
}
 
 
} // end namespace Retro
/Rw11CntlBase.hpp
0,0 → 1,57
// $Id: Rw11CntlBase.hpp 682 2015-05-15 18:35:29Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-14 488 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CntlBase.hpp 682 2015-05-15 18:35:29Z mueller $
\brief Declaration of class Rw11CntlBase.
*/
 
#ifndef included_Retro_Rw11CntlBase
#define included_Retro_Rw11CntlBase 1
 
#include "boost/shared_ptr.hpp"
 
#include "Rw11Cntl.hpp"
 
namespace Retro {
 
template <class TU, size_t NU>
class Rw11CntlBase : public Rw11Cntl {
public:
 
explicit Rw11CntlBase(const std::string& type);
~Rw11CntlBase();
 
virtual size_t NUnit() const;
TU& Unit(size_t index) const;
const boost::shared_ptr<TU>& UnitSPtr(size_t index) const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
boost::shared_ptr<TU> fspUnit[NU];
};
} // end namespace Retro
 
#include "Rw11CntlBase.ipp"
 
#endif
/Makefile
0,0 → 1,78
# $Id: Makefile 685 2015-05-25 12:18:36Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2013-02-01 479 1.0.1 correct so name; use checkpath_cpp.mk
# 2013-01-27 478 1.0 Initial version
#---
#
# Name of the sharable library
#
SONAME = rw11
SOMAJV = 1
SOMINV = 0
#
# Compile and Link search paths
#
include ../checkpath_cpp.mk
#
INCLFLAGS = -I${RETROBASE}/tools/src -I${BOOSTINC}
LDLIBS = -L${RETROBASE}/tools/lib -lrtools -lrlink
#
# Object files to be included
#
OBJ_all = Rw11.o Rw11Cpu.o Rw11CpuW11a.o
OBJ_all += Rw11Probe.o
OBJ_all += Rw11Cntl.o Rw11Unit.o
OBJ_all += Rw11UnitTerm.o
OBJ_all += Rw11UnitDisk.o
OBJ_all += Rw11UnitTape.o
OBJ_all += Rw11UnitStream.o
OBJ_all += Rw11CntlDL11.o Rw11UnitDL11.o
OBJ_all += Rw11CntlLP11.o Rw11UnitLP11.o
OBJ_all += Rw11CntlPC11.o Rw11UnitPC11.o
OBJ_all += Rw11CntlRL11.o Rw11UnitRL11.o
OBJ_all += Rw11CntlRK11.o Rw11UnitRK11.o
OBJ_all += Rw11CntlRHRP.o Rw11UnitRHRP.o
OBJ_all += Rw11CntlTM11.o Rw11UnitTM11.o
OBJ_all += Rw11Virt.o
OBJ_all += Rw11VirtTerm.o Rw11VirtTermPty.o Rw11VirtTermTcp.o
OBJ_all += Rw11VirtDisk.o Rw11VirtDiskFile.o
OBJ_all += Rw11VirtTape.o Rw11VirtTapeTap.o
OBJ_all += Rw11VirtStream.o
OBJ_all += Rw11Rdma.o Rw11RdmaDisk.o
#
DEP_all = $(OBJ_all:.o=.dep)
#
#- generic part ----------------------------------------------------------------
#
SOFILE = lib$(SONAME).so
SOFILEV = lib$(SONAME).so.$(SOMAJV)
SOFILEVV = lib$(SONAME).so.$(SOMAJV).$(SOMINV)
#
include $(RETROBASE)/tools/make/generic_cpp.mk
include $(RETROBASE)/tools/make/generic_dep.mk
include $(RETROBASE)/tools/make/generic_so.mk
include $(RETROBASE)/tools/make/dontincdep.mk
#
# The magic auto-dependency include
#
ifndef DONTINCDEP
include $(DEP_all)
endif
#
# cleanup phonies:
#
.PHONY : clean cleandep distclean
clean :
@ rm -f $(OBJ_all)
@ echo "Object files removed"
#
cleandep :
@ rm -f $(DEP_all)
@ echo "Dependency files removed"
#
distclean : clean cleandep
@ rm -f $(SOPATH)/lib$(SONAME).a $(SOPATH)/lib$(SONAME).so*
@ echo "Libraries removed"
#
/Rw11UnitTape.cpp
0,0 → 1,249
// $Id: Rw11UnitTape.cpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitTape.cpp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation of Rw11UnitTape.
*/
 
#include "librtools/Rexception.hpp"
 
#include "Rw11UnitTape.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitTape
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitTape::Rw11UnitTape(Rw11Cntl* pcntl, size_t index)
: Rw11UnitVirt<Rw11VirtTape>(pcntl, index),
fType(),
fEnabled(false),
fWProt(false),
fCapacity(0)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitTape::~Rw11UnitTape()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTape::SetType(const std::string& type)
{
throw Rexception("Rw11UnitTape::SetType",
string("Bad args: only type '") + fType + "' supported");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTape::SetWProt(bool wprot)
{
if (Virt()) throw Rexception("Rw11UnitTape::SetWProt",
"not allowed when tape attached");
fWProt = wprot;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTape::SetCapacity(size_t nbyte)
{
if (Virt()) throw Rexception("Rw11UnitTape::SetCapacity",
"not allowed when tape attached");
fCapacity = nbyte;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTape::SetPosFile(int posfile)
{
if (!Virt()) throw Rexception("Rw11UnitTape::SetPosFile",
"no tape attached");
Virt()->SetPosFile(posfile);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTape::SetPosRecord(int posrec)
{
if (!Virt()) throw Rexception("Rw11UnitTape::SetPosRecord",
"no tape attached");
Virt()->SetPosRecord(posrec);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::Bot() const
{
if (!Virt()) return false;
return Virt()->Bot();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::Eot() const
{
if (!Virt()) return false;
return Virt()->Eot();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::Eom() const
{
if (!Virt()) return false;
return Virt()->Eom();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11UnitTape::PosFile() const
{
if (!Virt()) return -1;
return Virt()->PosFile();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11UnitTape::PosRecord() const
{
if (!Virt()) return -1;
return Virt()->PosRecord();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::VirtReadRecord(size_t nbyte, uint8_t* data, size_t& ndone,
int& opcode, RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitTape::VirtReadRecord", "no tape attached");
return false;
}
return Virt()->ReadRecord(nbyte, data, ndone, opcode, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::VirtWriteRecord(size_t nbyte, const uint8_t* data,
int& opcode, RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitTape::VirtWriteRecord", "no tape attached");
return false;
}
return Virt()->WriteRecord(nbyte, data, opcode, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::VirtWriteEof(RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitTape::VirtWriteEof", "no tape attached");
return false;
}
return Virt()->WriteEof(emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::VirtSpaceForw(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitTape::VirtSpaceForw", "no tape attached");
return false;
}
return Virt()->SpaceForw(nrec, ndone, opcode, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::VirtSpaceBack(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitTape::VirtSpaceBack", "no tape attached");
return false;
}
return Virt()->SpaceBack(nrec, ndone, opcode, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTape::VirtRewind(int& opcode, RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitTape::VirtRewind", "no tape attached");
return false;
}
return Virt()->Rewind(opcode, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTape::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitTape @ " << this << endl;
os << bl << " fType: " << fType << endl;
os << bl << " fEnabled: " << fEnabled << endl;
os << bl << " fWProt: " << fWProt << endl;
os << bl << " fCapacity: " << fCapacity << endl;
 
Rw11UnitVirt<Rw11VirtTape>::Dump(os, ind, " ^");
return;
}
 
 
} // end namespace Retro
/Rw11CntlRHRP.cpp
0,0 → 1,684
// $Id: Rw11CntlRHRP.cpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
// Other credits:
// the boot code is from the simh project and Copyright Robert M Supnik
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0.2 check for spurious lams
// 2015-05-24 684 1.0.1 fixed rpcs2 update for wcheck and nem aborts
// 2015-05-14 680 1.0 Initial version
// 2015-03-21 659 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlRHRP.cpp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation of Rw11CntlRHRP.
*/
 
#include "boost/bind.hpp"
#include "boost/foreach.hpp"
#define foreach_ BOOST_FOREACH
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintBvi.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
#include "librtools/RlogMsg.hpp"
 
#include "Rw11CntlRHRP.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11CntlRHRP
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11CntlRHRP::kIbaddr;
const int Rw11CntlRHRP::kLam;
 
const uint16_t Rw11CntlRHRP::kRPCS1;
const uint16_t Rw11CntlRHRP::kRPWC;
const uint16_t Rw11CntlRHRP::kRPBA;
const uint16_t Rw11CntlRHRP::kRPDA;
const uint16_t Rw11CntlRHRP::kRPCS2;
const uint16_t Rw11CntlRHRP::kRPDS;
const uint16_t Rw11CntlRHRP::kRPER1;
const uint16_t Rw11CntlRHRP::kRPAS;
const uint16_t Rw11CntlRHRP::kRPLA;
const uint16_t Rw11CntlRHRP::kRPDB;
const uint16_t Rw11CntlRHRP::kRPMR1;
const uint16_t Rw11CntlRHRP::kRPDT;
const uint16_t Rw11CntlRHRP::kRPSN;
const uint16_t Rw11CntlRHRP::kRPOF;
const uint16_t Rw11CntlRHRP::kRPDC;
const uint16_t Rw11CntlRHRP::kRxM13;
const uint16_t Rw11CntlRHRP::kRxM14;
const uint16_t Rw11CntlRHRP::kRxM15;
const uint16_t Rw11CntlRHRP::kRPEC1;
const uint16_t Rw11CntlRHRP::kRPEC2;
const uint16_t Rw11CntlRHRP::kRPBAE;
const uint16_t Rw11CntlRHRP::kRPCS3;
 
const uint16_t Rw11CntlRHRP::kProbeOff;
const bool Rw11CntlRHRP::kProbeInt;
const bool Rw11CntlRHRP::kProbeRem;
 
const uint16_t Rw11CntlRHRP::kRPCS1_M_SC;
const uint16_t Rw11CntlRHRP::kRPCS1_M_TRE;
const uint16_t Rw11CntlRHRP::kRPCS1_M_DVA;
const uint16_t Rw11CntlRHRP::kRPCS1_M_BAE;
const uint16_t Rw11CntlRHRP::kRPCS1_V_BAE;
const uint16_t Rw11CntlRHRP::kRPCS1_B_BAE;
const uint16_t Rw11CntlRHRP::kRPCS1_M_RDY;
const uint16_t Rw11CntlRHRP::kRPCS1_M_IE;
const uint16_t Rw11CntlRHRP::kRPCS1_V_FUNC;
const uint16_t Rw11CntlRHRP::kRPCS1_B_FUNC;
const uint16_t Rw11CntlRHRP::kRPCS1_M_GO;
 
const uint16_t Rw11CntlRHRP::kFUNC_WCD;
const uint16_t Rw11CntlRHRP::kFUNC_WCHD;
const uint16_t Rw11CntlRHRP::kFUNC_WRITE;
const uint16_t Rw11CntlRHRP::kFUNC_WHD;
const uint16_t Rw11CntlRHRP::kFUNC_READ;
const uint16_t Rw11CntlRHRP::kFUNC_RHD;
 
const uint16_t Rw11CntlRHRP::kRFUNC_WUNIT;
const uint16_t Rw11CntlRHRP::kRFUNC_CUNIT;
const uint16_t Rw11CntlRHRP::kRFUNC_DONE;
const uint16_t Rw11CntlRHRP::kRFUNC_WIDLY;
 
const uint16_t Rw11CntlRHRP::kRPCS1_V_RUNIT;
const uint16_t Rw11CntlRHRP::kRPCS1_B_RUNIT;
const uint16_t Rw11CntlRHRP::kRPCS1_M_RATA;
const uint16_t Rw11CntlRHRP::kRPCS1_V_RIDLY;
const uint16_t Rw11CntlRHRP::kRPCS1_B_RIDLY;
 
const uint16_t Rw11CntlRHRP::kRPDA_V_TA;
const uint16_t Rw11CntlRHRP::kRPDA_B_TA;
const uint16_t Rw11CntlRHRP::kRPDA_B_SA;
 
const uint16_t Rw11CntlRHRP::kRPCS2_M_RWCO;
const uint16_t Rw11CntlRHRP::kRPCS2_M_WCE;
const uint16_t Rw11CntlRHRP::kRPCS2_M_NED;
const uint16_t Rw11CntlRHRP::kRPCS2_M_NEM;
const uint16_t Rw11CntlRHRP::kRPCS2_M_PGE;
const uint16_t Rw11CntlRHRP::kRPCS2_M_MXF;
const uint16_t Rw11CntlRHRP::kRPCS2_M_OR;
const uint16_t Rw11CntlRHRP::kRPCS2_M_IR;
const uint16_t Rw11CntlRHRP::kRPCS2_M_CLR;
const uint16_t Rw11CntlRHRP::kRPCS2_M_PAT;
const uint16_t Rw11CntlRHRP::kRPCS2_M_BAI;
const uint16_t Rw11CntlRHRP::kRPCS2_M_UNIT2;
const uint16_t Rw11CntlRHRP::kRPCS2_B_UNIT;
 
const uint16_t Rw11CntlRHRP::kRPDS_M_ATA;
const uint16_t Rw11CntlRHRP::kRPDS_M_ERP;
const uint16_t Rw11CntlRHRP::kRPDS_M_MOL;
const uint16_t Rw11CntlRHRP::kRPDS_M_WRL;
const uint16_t Rw11CntlRHRP::kRPDS_M_LBT;
const uint16_t Rw11CntlRHRP::kRPDS_M_DPR;
const uint16_t Rw11CntlRHRP::kRPDS_M_DRY;
const uint16_t Rw11CntlRHRP::kRPDS_M_VV;
const uint16_t Rw11CntlRHRP::kRPDS_M_OM ;
 
const uint16_t Rw11CntlRHRP::kRPER1_M_UNS;
const uint16_t Rw11CntlRHRP::kRPER1_M_WLE;
const uint16_t Rw11CntlRHRP::kRPER1_M_IAE;
const uint16_t Rw11CntlRHRP::kRPER1_M_AOE;
const uint16_t Rw11CntlRHRP::kRPER1_M_RMR;
const uint16_t Rw11CntlRHRP::kRPER1_M_ILF;
 
const uint16_t Rw11CntlRHRP::kRPDC_B_CA;
 
const uint16_t Rw11CntlRHRP::kRPCS3_M_IE;
const uint16_t Rw11CntlRHRP::kRPCS3_M_RSEARDONE;
const uint16_t Rw11CntlRHRP::kRPCS3_M_RPACKDONE;
const uint16_t Rw11CntlRHRP::kRPCS3_M_RPOREDONE;
const uint16_t Rw11CntlRHRP::kRPCS3_M_RSEEKDONE;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11CntlRHRP::Rw11CntlRHRP()
: Rw11CntlBase<Rw11UnitRHRP,4>("rhrp"),
fPC_rpcs1(0),
fPC_rpcs2(0),
fPC_rpcs3(0),
fPC_rpwc(0),
fPC_rpba(0),
fPC_rpbae(0),
fPC_cunit(0),
fPC_rpds(0),
fPC_rpda(0),
fPC_rpdc(0),
fRd_rpcs1(0),
fRd_rpcs2(0),
fRd_rpcs3(0),
fRd_rpwc(0),
fRd_rpba(0),
fRd_rpbae(0),
fRd_rpds(0),
fRd_rpda(0),
fRd_rpdc(0),
fRd_addr(0),
fRd_lba(0),
fRd_nwrd(0),
fRd_fu(0),
fRd_ovr(false),
fRdma(this,
boost::bind(&Rw11CntlRHRP::RdmaPreExecCB, this, _1, _2, _3, _4),
boost::bind(&Rw11CntlRHRP::RdmaPostExecCB, this, _1, _2, _3, _4))
{
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
for (size_t i=0; i<NUnit(); i++) {
fspUnit[i].reset(new Rw11UnitRHRP(this, i));
}
 
fStats.Define(kStatNFuncWchk , "NFuncWchk" , "func WCHK");
fStats.Define(kStatNFuncWrite , "NFuncWrite" , "func WRITE");
fStats.Define(kStatNFuncRead , "NFuncRead" , "func READ");
fStats.Define(kStatNFuncSear , "NFuncSear" , "func SEARCH (loc)");
fStats.Define(kStatNFuncPack , "NFuncPack" , "func PACK ACK (loc)");
fStats.Define(kStatNFuncPore , "NFuncPore" , "func PORT REL (loc)");
fStats.Define(kStatNFuncSeek , "NFuncSeek" , "func SEEK (loc)");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11CntlRHRP::~Rw11CntlRHRP()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRHRP::Config(const std::string& name, uint16_t base, int lam)
{
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRHRP::Start()
{
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
throw Rexception("Rw11CntlRHRP::Start",
"Bad state: started, no lam, not enable, not found");
 
// add device register address ibus and rbus mappings
// done here because now Cntl bound to Cpu and Cntl probed
Cpu().AllIAddrMapInsert(Name()+".cs1", Base() + kRPCS1);
Cpu().AllIAddrMapInsert(Name()+".wc", Base() + kRPWC);
Cpu().AllIAddrMapInsert(Name()+".ba", Base() + kRPBA);
Cpu().AllIAddrMapInsert(Name()+".da", Base() + kRPDA);
Cpu().AllIAddrMapInsert(Name()+".cs2", Base() + kRPCS2);
Cpu().AllIAddrMapInsert(Name()+".ds", Base() + kRPDS);
Cpu().AllIAddrMapInsert(Name()+".er1", Base() + kRPER1);
Cpu().AllIAddrMapInsert(Name()+".as", Base() + kRPAS);
Cpu().AllIAddrMapInsert(Name()+".la", Base() + kRPLA);
Cpu().AllIAddrMapInsert(Name()+".db", Base() + kRPDB);
Cpu().AllIAddrMapInsert(Name()+".mr1", Base() + kRPMR1);
Cpu().AllIAddrMapInsert(Name()+".dt", Base() + kRPDT);
Cpu().AllIAddrMapInsert(Name()+".sn", Base() + kRPSN);
Cpu().AllIAddrMapInsert(Name()+".of", Base() + kRPOF);
Cpu().AllIAddrMapInsert(Name()+".dc", Base() + kRPDC);
Cpu().AllIAddrMapInsert(Name()+".m13", Base() + kRxM13);
Cpu().AllIAddrMapInsert(Name()+".m14", Base() + kRxM14);
Cpu().AllIAddrMapInsert(Name()+".m15", Base() + kRxM15);
Cpu().AllIAddrMapInsert(Name()+".ec1", Base() + kRPEC1);
Cpu().AllIAddrMapInsert(Name()+".ec2", Base() + kRPEC2);
Cpu().AllIAddrMapInsert(Name()+".bae", Base() + kRPBAE);
Cpu().AllIAddrMapInsert(Name()+".cs3", Base() + kRPCS3);
 
// setup primary info clist
fPrimClist.Clear();
fPrimClist.AddAttn();
fPC_rpcs1 = Cpu().AddRibr(fPrimClist, fBase+kRPCS1);
fPC_rpcs2 = Cpu().AddRibr(fPrimClist, fBase+kRPCS2);
fPC_rpcs3 = Cpu().AddRibr(fPrimClist, fBase+kRPCS3);
fPC_rpwc = Cpu().AddRibr(fPrimClist, fBase+kRPWC);
fPC_rpba = Cpu().AddRibr(fPrimClist, fBase+kRPBA);
fPC_rpbae = Cpu().AddRibr(fPrimClist, fBase+kRPBAE);
 
fPC_cunit = Cpu().AddWibr(fPrimClist, fBase+kRPCS1,
(kRFUNC_CUNIT << kRPCS1_V_FUNC) );
 
fPC_rpds = Cpu().AddRibr(fPrimClist, fBase+kRPDS);
fPC_rpda = Cpu().AddRibr(fPrimClist, fBase+kRPDA);
fPC_rpdc = Cpu().AddRibr(fPrimClist, fBase+kRPDC);
 
// add attn handler
Server().AddAttnHandler(boost::bind(&Rw11CntlRHRP::AttnHandler, this, _1),
uint16_t(1)<<fLam, (void*)this);
 
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRHRP::UnitSetup(size_t ind)
{
Rw11UnitRHRP& unit = *fspUnit[ind];
RlinkCommandList clist;
Rw11Cpu& cpu = Cpu();
 
// only two mayor drive states are used
// power medium wlock : ds flags
// off --- --- : dpr=0 mol=0 wrl=0 (disabled, type=off)
// on off --- : dpr=1 mol=0 wrl=0 (enabled, no file attached)
// on on no : dpr=1 mol=1 wrl=0 (file attached)
// on on yes : dpr=1 mol=1 wrl=1 (file attached + wlock)
 
uint16_t rpds = 0;
 
if (unit.Type() != "off") { // is enabled
rpds |= kRPDS_M_DPR;
if (unit.Virt()) { // file attached
rpds |= kRPDS_M_MOL; // -> set MOL
rpds |= kRPDS_M_ERP; // -> clear ER1 via ERP=1
if (unit.WProt()) rpds |= kRPDS_M_WRL; // in case write protected
}
if ((unit.Rpds() ^ rpds) & kRPDS_M_MOL) { // mol state change ?
rpds |= kRPDS_M_ATA; // cause attentions
rpds |= kRPDS_M_VV; // reset volume valid
}
}
unit.SetRpds(rpds); // remember new DS
cpu.AddWibr(clist, fBase+kRPCS1, // setup unit
(ind << kRPCS1_V_RUNIT) |
(kRFUNC_WUNIT << kRPCS1_V_FUNC) );
cpu.AddWibr(clist, fBase+kRPDT, unit.Rpdt()); // setup DT
cpu.AddWibr(clist, fBase+kRPDS, rpds); // setup DS
Server().Exec(clist);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11CntlRHRP::BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart)
{
uint16_t kBOOT_START = 02000;
uint16_t bootcode[] = { // rh/rp boot loader - from simh pdp11_rp.c (v3.9)
0042102, // "BD"
0012706, kBOOT_START, // mov #boot_start, sp
0012700, uint16_t(unit), // mov #unit, r0
0012701, 0176700, // mov #RPCS1, r1
0012761, 0000040, 0000010, // mov #CS2_CLR, 10(r1) ; reset
0010061, 0000010, // mov r0, 10(r1) ; set unit
0012711, 0000021, // mov #RIP+GO, (r1) ; pack ack
0012761, 0010000, 0000032, // mov #FMT16B, 32(r1) ; 16b mode
0012761, 0177000, 0000002, // mov #-512., 2(r1) ; set wc
0005061, 0000004, // clr 4(r1) ; clr ba
0005061, 0000006, // clr 6(r1) ; clr da
0005061, 0000034, // clr 34(r1) ; clr cyl
0012711, 0000071, // mov #READ+GO, (r1) ; read
0105711, // tstb (r1) ; wait
0100376, // bpl .-2
0005002, // clr R2
0005003, // clr R3
0012704, uint16_t(kBOOT_START+020), // mov #start+020, r4
0005005, // clr R5
0105011, // clrb (r1)
0005007 // clr PC
};
code.clear();
foreach_ (uint16_t& w, bootcode) code.push_back(w);
aload = kBOOT_START;
astart = kBOOT_START+2;
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRHRP::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlRHRP @ " << this << endl;
os << bl << " fPC_rpcs1: " << RosPrintf(fPC_rpcs1,"d",6) << endl;
os << bl << " fPC_rpcs2: " << RosPrintf(fPC_rpcs2,"d",6) << endl;
os << bl << " fPC_rpcs3: " << RosPrintf(fPC_rpcs3,"d",6) << endl;
os << bl << " fPC_rpwc: " << RosPrintf(fPC_rpwc,"d",6) << endl;
os << bl << " fPC_rpba: " << RosPrintf(fPC_rpba,"d",6) << endl;
os << bl << " fPC_rpbae: " << RosPrintf(fPC_rpbae,"d",6) << endl;
os << bl << " fPC_cunit: " << RosPrintf(fPC_cunit,"d",6) << endl;
os << bl << " fPC_rpds: " << RosPrintf(fPC_rpds,"d",6) << endl;
os << bl << " fPC_rpda: " << RosPrintf(fPC_rpda,"d",6) << endl;
os << bl << " fPC_rpdc: " << RosPrintf(fPC_rpdc,"d",6) << endl;
os << bl << " fRd_rpcs1: " << RosPrintBvi(fRd_rpcs1) << endl;
os << bl << " fRd_rpcs2: " << RosPrintBvi(fRd_rpcs2) << endl;
os << bl << " fRd_rpcs3: " << RosPrintBvi(fRd_rpcs3) << endl;
os << bl << " fRd_rpwc: " << RosPrintBvi(fRd_rpwc) << endl;
os << bl << " fRd_rpba: " << RosPrintBvi(fRd_rpba) << endl;
os << bl << " fRd_rpbae: " << RosPrintBvi(fRd_rpbae) << endl;
os << bl << " fRd_rpds: " << RosPrintBvi(fRd_rpds) << endl;
os << bl << " fRd_rpda: " << RosPrintBvi(fRd_rpda) << endl;
os << bl << " fRd_rpdc: " << RosPrintBvi(fRd_rpdc) << endl;
os << bl << " fRd_addr: " << RosPrintBvi(fRd_addr,8,22) << endl;
os << bl << " fRd_lba: " << RosPrintf(fRd_lba,"d",6) << endl;
os << bl << " fRd_nwrd: " << RosPrintf(fRd_nwrd,"d",6) << endl;
os << bl << " fRd_fu: " << RosPrintf(fRd_fu,"d",6) << endl;
os << bl << " fRd_ovr: " << fRd_ovr << endl;
fRdma.Dump(os, ind+2, "fRdma: ");
Rw11CntlBase<Rw11UnitRHRP,4>::Dump(os, ind, " ^");
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11CntlRHRP::AttnHandler(RlinkServer::AttnArgs& args)
{
fStats.Inc(kStatNAttnHdl);
Server().GetAttnInfo(args, fPrimClist);
 
uint16_t rpcs1 = fPrimClist[fPC_rpcs1].Data();
uint16_t rpcs2 = fPrimClist[fPC_rpcs2].Data();
uint16_t rpcs3 = fPrimClist[fPC_rpcs3].Data();
uint16_t rpwc = fPrimClist[fPC_rpwc ].Data();
uint16_t rpba = fPrimClist[fPC_rpba ].Data();
uint16_t rpbae = fPrimClist[fPC_rpbae].Data();
uint16_t rpds = fPrimClist[fPC_rpds ].Data();
uint16_t rpda = fPrimClist[fPC_rpda ].Data();
uint16_t rpdc = fPrimClist[fPC_rpdc ].Data();
uint16_t unum = rpcs2 & kRPCS2_B_UNIT;
uint16_t fu = (rpcs1>>kRPCS1_V_FUNC) & kRPCS1_B_FUNC;
 
uint32_t addr = uint32_t(rpbae)<<16 | uint32_t(rpba);
 
uint16_t sa = rpda & kRPDA_B_SA;
uint16_t ta = (rpda>>kRPDA_V_TA) & kRPDA_B_TA;
uint16_t ca = rpdc & kRPDC_B_CA;
 
uint32_t nwrd = (~uint32_t(rpwc)&0xffff) + 1; // transfer size in words
 
// all 4 units are always available, but check anyway
if (unum > NUnit())
throw Rexception("Rw11CntlRHRP::AttnHandler","Bad state: unum > NUnit()");
 
Rw11UnitRHRP& unit = *fspUnit[unum];
//Rw11Cpu& cpu = Cpu();
RlinkCommandList clist;
 
uint32_t lba = unit.Chs2Lba(ca,ta,sa);
uint32_t nblk = unit.Nwrd2Nblk(nwrd);
 
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
static const char* fumnemo[32] =
{"00 ","01 ","02 ","03 ","04 ","05 ","06 ","07 ", // 00---
"10 ","11 ","12 ","13 ","14 ","15 ","16 ","17 ", // 01---
"20 ","21 ","22 ","23 ","wc ","wch","26 ","27 ", // 10---
"wr ","wrh","32 ","33 ","rd ","rdh","36 ","37 "}; // 11---
lmsg << "-I RHRP"
<< " fu=" << fumnemo[fu&037]
<< " cs=" << RosPrintBvi(rpcs1,8)
<< "," << RosPrintBvi(rpcs2,8)
<< " ad=" << RosPrintBvi(addr,8,22)
<< " pa=" << unum
<< "," << RosPrintf(ca,"d",3)
<< "," << RosPrintf(ta,"d",2)
<< "," << RosPrintf(sa,"d",2)
<< " la,nw=" << RosPrintf(lba,"d",6)
<< ",";
if (nwrd==65536) lmsg << " (0)"; else lmsg << RosPrintf(nwrd,"d",5);
}
 
// handle cs3 done flags, just count them
if (rpcs3 & kRPCS3_M_RSEARDONE) fStats.Inc(kStatNFuncSear);
if (rpcs3 & kRPCS3_M_RPOREDONE) fStats.Inc(kStatNFuncPore);
if (rpcs3 & kRPCS3_M_RPACKDONE) fStats.Inc(kStatNFuncPack);
if (rpcs3 & kRPCS3_M_RSEEKDONE) fStats.Inc(kStatNFuncSeek);
 
// check for spurious interrupts (either RDY=1 or RDY=0 and rdma busy)
if ((rpcs1 & kRPCS1_M_RDY) || fRdma.IsActive()) {
RlogMsg lmsg(LogFile());
lmsg << "-E RHRP err "
<< " cs=" << RosPrintBvi(rpcs1,8)
<< " spurious lam: "
<< (fRdma.IsActive() ? "RDY=0 and Rdma busy" : "RDY=1");
return 0;
}
 
// check for overrun (read/write beyond last track
// if found, truncate request length
bool ovr = lba + nblk > unit.NBlock();
if (ovr) nwrd = (unit.NBlock()-lba) * (unit.BlockSize()/2);
 
// remember request parameters for call back and error exit handling
 
fRd_rpcs1 = rpcs1;
fRd_rpcs2 = rpcs2;
fRd_rpcs3 = rpcs3;
fRd_rpwc = rpwc;
fRd_rpba = rpba;
fRd_rpbae = rpbae;
fRd_rpds = rpds;
fRd_rpda = rpda;
fRd_rpdc = rpdc;
fRd_addr = addr;
fRd_lba = lba;
fRd_nwrd = nwrd;
fRd_fu = fu;
fRd_ovr = ovr;
 
// check for general abort conditions
// note: only 'data transfer' functions handled via backend
// SEEK and others are done in ibdr_rhrp autonomously
 
// not attached --> signal drive unsave status
if (! unit.Virt()) { // not attached
AddErrorExit(clist, kRPER1_M_UNS); // signal UNS (drive unsafe)
Server().Exec(clist); // doit
return 0;
}
 
// invalid disk address
if (ca > unit.NCylinder() || ta > unit.NHead() || sa > unit.NSector()) {
AddErrorExit(clist, kRPER1_M_IAE); // signal IAE (invalid address err)
Server().Exec(clist); // doit
return 0;
}
// now handle the functions
if (fu == kFUNC_WRITE) { // Write -------------------------
fStats.Inc(kStatNFuncWrite);
if (unit.WProt()) { // write on write locked drive ?
AddErrorExit(clist, kRPER1_M_WLE); // signal WLE (write lock error)
} else {
fRdma.QueueDiskWrite(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
}
 
} else if (fu == kFUNC_WCD) { // Write Check -------------------
fStats.Inc(kStatNFuncWchk );
fRdma.QueueDiskWriteCheck(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
} else if (fu == kFUNC_READ ) { // Read --------------------------
fStats.Inc(kStatNFuncRead);
fRdma.QueueDiskRead(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
 
} else {
// FIXME: handle other special functions (currently simply error out !!)
AddErrorExit(clist, kRPER1_M_ILF); // signal ILF (invalid function)
Server().Exec(clist); // doit
return 0;
}
 
if (clist.Size()) { // if handled directly
Server().Exec(clist); // doit
}
 
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRHRP::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
RlinkCommandList& clist)
{
// if last chunk and not doing WCD add a labo and normal exit csr update
if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kFUNC_WCD) {
clist.AddLabo();
AddNormalExit(clist, nwdone+nwnext, 0, 0);
}
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRHRP::RdmaPostExecCB(int stat, size_t ndone,
RlinkCommandList& clist, size_t ncmd)
{
if (stat == Rw11Rdma::kStatusBusy) return;
 
uint16_t rper1 = 0;
uint16_t rpcs2 = 0;
 
if (fRd_fu == kFUNC_WCD) {
size_t nwcok = fRdma.WriteCheck(ndone);
if (nwcok != ndone) { // if mismatch found
rpcs2 |= kRPCS2_M_WCE;
if (ndone & 0x1) rpcs2 |= kRPCS2_M_RWCO; // failed in odd word !
ndone = nwcok; // truncate word count
}
}
 
// handle Rdma aborts
if (stat == Rw11Rdma::kStatusFailRdma) rpcs2 |= kRPCS2_M_NEM;
 
// check for fused csr updates
if (clist.Size() > ncmd) {
uint8_t ccode = clist[ncmd].Command();
uint16_t cdata = clist[ncmd].Data();
if (ccode != RlinkCommand::kCmdLabo || (rper1 != 0 && cdata == 0))
throw Rexception("Rw11CntlRHRP::RdmaPostExecCB",
"Bad state: Labo not found or missed abort");
if (cdata == 0) return;
}
 
// finally to RHRP register update
RlinkCommandList clist1;
AddNormalExit(clist1, ndone, rper1, rpcs2);
Server().Exec(clist1);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRHRP::AddErrorExit(RlinkCommandList& clist, uint16_t rper1)
{
Rw11Cpu& cpu = Cpu();
cpu.AddWibr(clist, fBase+kRPCS1, (kRFUNC_CUNIT<<kRPCS1_V_FUNC) );
cpu.AddWibr(clist, fBase+kRPER1, rper1);
 
// use ATA termination ! Comes late, but should be ok
cpu.AddWibr(clist, fBase+kRPCS1, kRPCS1_M_RATA|(kRFUNC_DONE<<kRPCS1_V_FUNC) );
 
if (fTraceLevel>1) {
RlogMsg lmsg(LogFile());
lmsg << "-I RHRP"
<< " err "
<< " cs1=" << RosPrintBvi(fRd_rpcs1,8)
<< " er1=" << RosPrintBvi(rper1,2,16);
}
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRHRP::AddNormalExit(RlinkCommandList& clist, size_t ndone,
uint16_t rper1, uint16_t rpcs2)
{
Rw11Cpu& cpu = Cpu();
uint16_t unum = fRd_rpcs2 & kRPCS2_B_UNIT;
Rw11UnitRHRP& unit = *fspUnit[unum];
 
size_t nblk = unit.Nwrd2Nblk(ndone);
uint32_t addr = fRd_addr + 2*ndone;
size_t lba = fRd_lba + nblk;
 
uint16_t ba = addr & 0177776; // get lower 16 bits
uint16_t bae = (addr>>16) & 077; // get upper 6 bits
 
uint16_t sa;
uint16_t ta;
uint16_t ca;
unit.Lba2Chs(lba, ca,ta,sa);
uint16_t da = (ta<<kRPDA_V_TA) | sa;
uint16_t wc = fRd_rpwc + uint16_t(ndone);
 
if (fRd_ovr) rper1 |= kRPER1_M_AOE;
 
cpu.AddWibr(clist, fBase+kRPWC, wc);
cpu.AddWibr(clist, fBase+kRPBA, ba);
cpu.AddWibr(clist, fBase+kRPBAE, bae);
 
cpu.AddWibr(clist, fBase+kRPCS1, (kRFUNC_CUNIT<<kRPCS1_V_FUNC) );
cpu.AddWibr(clist, fBase+kRPDA, da);
cpu.AddWibr(clist, fBase+kRPDC, ca);
 
if (rper1) cpu.AddWibr(clist, fBase+kRPER1, rper1);
if (rpcs2) cpu.AddWibr(clist, fBase+kRPER1, rpcs2);
 
cpu.AddWibr(clist, fBase+kRPCS1, (kRFUNC_DONE<<kRPCS1_V_FUNC) );
 
if (fTraceLevel>1) {
RlogMsg lmsg(LogFile());
if (rper1 || rpcs2) {
lmsg << "-I RHRP"
<< " err "
<< " er1=" << RosPrintBvi(rper1,2,16)
<< " cs2=" << RosPrintBvi(rpcs2,2,8)
<< endl;
}
lmsg << "-I RHRP"
<< (rper1==0 ? " ok " :" err ")
<< " we=" << RosPrintBvi(wc,8) << "," << RosPrintBvi(rper1,8)
<< " ad=" << RosPrintBvi(addr,8,22)
<< " pa=" << unum
<< "," << RosPrintf(ca,"d",3)
<< "," << RosPrintf(ta,"d",2)
<< "," << RosPrintf(sa,"d",2)
<< " ca,da=" << RosPrintBvi(ca,8,10) << "," << RosPrintBvi(da,8);
}
 
return;
}
 
} // end namespace Retro
/Rw11UnitTape.ipp
0,0 → 1,62
// $Id: Rw11UnitTape.ipp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitTape.ipp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation (inline) of Rw11UnitTape.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const std::string& Rw11UnitTape::Type() const
{
return fType;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11UnitTape::Enabled() const
{
return fEnabled;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11UnitTape::WProt() const
{
return Virt() ? Virt()->WProt() : fWProt;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11UnitTape::Capacity() const
{
return Virt() ? Virt()->Capacity() : fCapacity;
}
 
 
} // end namespace Retro
/Rw11VirtTape.hpp
0,0 → 1,112
// $Id: Rw11VirtTape.hpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11VirtTape.hpp 686 2015-06-04 21:08:08Z mueller $
\brief Declaration of class Rw11VirtTape.
*/
 
#ifndef included_Retro_Rw11VirtTape
#define included_Retro_Rw11VirtTape 1
 
#include "Rw11Virt.hpp"
 
namespace Retro {
 
class Rw11VirtTape : public Rw11Virt {
public:
explicit Rw11VirtTape(Rw11Unit* punit);
~Rw11VirtTape();
 
void SetWProt(bool wprot);
void SetCapacity(size_t nbyte);
bool WProt() const;
size_t Capacity() const;
 
virtual bool ReadRecord(size_t nbyte, uint8_t* data, size_t& ndone,
int& opcode, RerrMsg& emsg) = 0;
virtual bool WriteRecord(size_t nbyte, const uint8_t* data,
int& opcode, RerrMsg& emsg) = 0;
virtual bool WriteEof(RerrMsg& emsg) = 0;
virtual bool SpaceForw(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg) = 0;
virtual bool SpaceBack(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg) = 0;
virtual bool Rewind(int& opcode, RerrMsg& emsg) = 0;
 
void SetPosFile(int posfile);
void SetPosRecord(int posrec);
 
bool Bot() const;
bool Eot() const;
bool Eom() const;
 
int PosFile() const;
int PosRecord() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
static Rw11VirtTape* New(const std::string& url, Rw11Unit* punit,
RerrMsg& emsg);
 
// statistics counter indices
enum stats {
kStatNVTReadRec = Rw11Virt::kDimStat,
kStatNVTReadByt,
kStatNVTReadEof,
kStatNVTReadEom,
kStatNVTReadPErr,
kStatNVTReadLErr,
kStatNVTWriteRec,
kStatNVTWriteByt,
kStatNVTWriteEof,
kStatNVTSpaForw,
kStatNVTSpaBack,
kStatNVTRewind,
kDimStat
};
 
// operation code
enum OpCode {
kOpCodeOK = 0, //<! operation OK
kOpCodeBot, //<! ended at BOT
kOpCodeEof, //<! ended at EOF
kOpCodeEom, //<! ended at EOM
kOpCodeRecLenErr, //<! record length error
kOpCodeBadParity, //<! record with parity error
kOpCodeBadFormat //<! file format error
};
 
protected:
bool fWProt; //<! write protected
size_t fCapacity; //<! capacity in byte (0=unlimited)
bool fBot; //<! tape at bot
bool fEot; //<! tape beyond eot
bool fEom; //<! tape beyond medium
int fPosFile; //<! tape pos: #files (-1=unknown)
int fPosRecord; //<! tape pos: #record (-1=unknown)
};
} // end namespace Retro
 
#include "Rw11VirtTape.ipp"
 
#endif
/Rw11Cntl.hpp
0,0 → 1,117
// $Id: Rw11Cntl.hpp 682 2015-05-15 18:35:29Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-15 680 1.1.1 add NUnit() as virtual
// 2014-12-30 625 1.1 adopt to Rlink V4 attn logic
// 2013-03-06 495 1.0 Initial version
// 2013-02-05 483 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11Cntl.hpp 682 2015-05-15 18:35:29Z mueller $
\brief Declaration of class Rw11Cntl.
*/
 
#ifndef included_Retro_Rw11Cntl
#define included_Retro_Rw11Cntl 1
 
#include <string>
 
#include "boost/utility.hpp"
 
#include "librtools/Rstats.hpp"
#include "librlink/RlinkConnect.hpp"
#include "librlink/RlinkServer.hpp"
#include "Rw11Probe.hpp"
 
#include "librtools/Rbits.hpp"
#include "Rw11Cpu.hpp"
 
namespace Retro {
 
class Rw11Cntl : public Rbits, private boost::noncopyable {
public:
 
explicit Rw11Cntl(const std::string& type);
virtual ~Rw11Cntl();
 
void SetCpu(Rw11Cpu* pcpu);
Rw11Cpu& Cpu() const;
Rw11& W11() const;
RlinkServer& Server() const;
RlinkConnect& Connect() const;
RlogFile& LogFile() const;
 
const std::string& Type() const;
const std::string& Name() const;
uint16_t Base() const;
int Lam() const;
 
void SetEnable(bool ena);
bool Enable() const;
 
virtual bool Probe();
const Rw11Probe& ProbeStatus() const;
 
virtual void Start();
bool IsStarted() const;
 
virtual size_t NUnit() const;
virtual bool BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart);
 
void SetTraceLevel(uint32_t level);
uint32_t TraceLevel() const;
 
std::string UnitName(size_t index) const;
 
const Rstats& Stats() const;
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// statistics counter indices
enum stats {
kStatNAttnHdl = 0,
kStatNAttnNoAct,
kDimStat
};
 
protected:
void ConfigCntl(const std::string& name, uint16_t base, int lam,
uint16_t probeoff, bool probeint, bool proberem);
 
private:
Rw11Cntl() {} //!< default ctor blocker
 
protected:
Rw11Cpu* fpCpu; //!< cpu back pointer
std::string fType; //!< controller type
std::string fName; //!< controller name
uint16_t fBase; //!< controller base address
int fLam; //!< attn bit number (-1 of none)
bool fEnable; //!< enable flag
bool fStarted; //!< true if Start() called
Rw11Probe fProbe; //!< controller probe context
uint32_t fTraceLevel; //!< trace level; 0=off;1=cntl
RlinkCommandList fPrimClist; //!< clist for attn primary info
Rstats fStats; //!< statistics
};
} // end namespace Retro
 
#include "Rw11Cntl.ipp"
 
#endif
/Rw11VirtTapeTap.hpp
0,0 → 1,90
// $Id: Rw11VirtTapeTap.hpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11VirtTapeTap.hpp 686 2015-06-04 21:08:08Z mueller $
\brief Declaration of class Rw11VirtTapeTap.
*/
 
#ifndef included_Retro_Rw11VirtTapeTap
#define included_Retro_Rw11VirtTapeTap 1
 
#include "Rw11VirtTape.hpp"
 
namespace Retro {
 
class Rw11VirtTapeTap : public Rw11VirtTape {
public:
 
explicit Rw11VirtTapeTap(Rw11Unit* punit);
~Rw11VirtTapeTap();
 
bool Open(const std::string& url, RerrMsg& emsg);
 
virtual bool ReadRecord(size_t nbyt, uint8_t* data, size_t& ndone,
int& opcode, RerrMsg& emsg);
virtual bool WriteRecord(size_t nbyt, const uint8_t* data,
int& opcode, RerrMsg& emsg);
virtual bool WriteEof(RerrMsg& emsg);
virtual bool SpaceForw(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg);
virtual bool SpaceBack(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg);
virtual bool Rewind(int& opcode, RerrMsg& emsg);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint32_t kMetaEof = 0x00000000; //!< EOF marker
static const uint32_t kMetaEom = 0xffffffff; //!< EOM marker
static const uint32_t kMeta_M_Perr = 0x80000000;
static const uint32_t kMeta_M_Mbz = 0x7fff0000;
static const uint32_t kMeta_B_Rlen = 0x0000ffff;
 
protected:
bool Seek(size_t seekpos, int dir, RerrMsg& emsg);
bool Read(size_t nbyt, uint8_t* data, RerrMsg& emsg);
bool Write(size_t nbyt, const uint8_t* data, bool back,
RerrMsg& emsg);
bool CheckSizeForw(size_t nbyt, const char* text, RerrMsg& emsg);
bool CheckSizeBack(size_t nbyt, const char* text, RerrMsg& emsg);
void UpdatePos(size_t nbyt, int dir);
bool ParseMeta(uint32_t meta, size_t& rlen, bool& perr,
RerrMsg& emsg);
size_t BytePadding(size_t rlen);
bool SetBad();
bool BadTapeMsg(const char* meth, RerrMsg& emsg);
void IncPosRecord(int delta);
 
protected:
int fFd; //!< file number
size_t fSize; //!< file size
size_t fPos; //!< file position
bool fBad; //!< BAD file format flag
bool fPadOdd; //!< do odd byte padding
bool fTruncPend; //!< truncate on next write
};
} // end namespace Retro
 
#include "Rw11VirtTapeTap.ipp"
 
#endif
/Rw11UnitTM11.cpp
0,0 → 1,73
// $Id: Rw11UnitTM11.cpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-17 683 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitTM11.cpp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation of Rw11UnitTM11.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/RosFill.hpp"
#include "Rw11CntlTM11.hpp"
 
#include "Rw11UnitTM11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitTM11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitTM11::Rw11UnitTM11(Rw11CntlTM11* pcntl, size_t index)
: Rw11UnitTapeBase<Rw11CntlTM11>(pcntl, index),
fTmds(0)
{
// setup disk geometry: only rk05 supported, no rk05f !
fType = "tu10";
fEnabled = true;
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitTM11::~Rw11UnitTM11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTM11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitTM11 @ " << this << endl;
os << bl << " fTmds: " << fTmds << endl;
 
Rw11UnitTapeBase<Rw11CntlTM11>::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11Cpu.cpp
0,0 → 1,848
// $Id: Rw11Cpu.cpp 682 2015-05-15 18:35:29Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-15 682 1.2.4 BUGFIX: Boot(): extract unit number properly
// Boot(): stop cpu before load, check unit number
// 2015-05-08 675 1.2.3 w11a start/stop/suspend overhaul
// 2015-04-25 668 1.2.2 add AddRbibr(), AddWbibr()
// 2015-04-03 661 1.2.1 add kStat_M_* defs
// 2015-03-21 659 1.2 add RAddrMap
// 2015-01-01 626 1.1 Adopt for rlink v4 and 4k ibus window
// 2014-12-21 617 1.0.3 use kStat_M_RbTout for rbus timeout
// 2014-08-02 576 1.0.2 adopt rename of LastExpect->SetLastExpect
// 2013-04-14 506 1.0.1 add AddLalh(),AddRMem(),AddWMem()
// 2013-04-12 504 1.0 Initial version
// 2013-01-27 478 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Cpu.cpp 682 2015-05-15 18:35:29Z mueller $
\brief Implemenation of Rw11Cpu.
*/
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
 
#include <vector>
#include <map>
#include <algorithm>
 
#include "boost/date_time/posix_time/posix_time_types.hpp"
 
#include "librtools/Rexception.hpp"
#include "librtools/RlogMsg.hpp"
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/RosPrintBvi.hpp"
#include "Rw11Cntl.hpp"
 
#include "Rw11Cpu.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11Cpu
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11Cpu::kCPCONF;
const uint16_t Rw11Cpu::kCPCNTL;
const uint16_t Rw11Cpu::kCPSTAT;
const uint16_t Rw11Cpu::kCPPSW;
const uint16_t Rw11Cpu::kCPAL;
const uint16_t Rw11Cpu::kCPAH;
const uint16_t Rw11Cpu::kCPMEM;
const uint16_t Rw11Cpu::kCPMEMI;
const uint16_t Rw11Cpu::kCPR0;
const uint16_t Rw11Cpu::kCPPC;
const uint16_t Rw11Cpu::kCPMEMBE;
 
const uint16_t Rw11Cpu::kCPFUNC_NOOP;
const uint16_t Rw11Cpu::kCPFUNC_START;
const uint16_t Rw11Cpu::kCPFUNC_STOP;
const uint16_t Rw11Cpu::kCPFUNC_STEP;
const uint16_t Rw11Cpu::kCPFUNC_CRESET;
const uint16_t Rw11Cpu::kCPFUNC_BRESET;
const uint16_t Rw11Cpu::kCPFUNC_SUSPEND;
const uint16_t Rw11Cpu::kCPFUNC_RESUME;
 
const uint16_t Rw11Cpu::kCPSTAT_M_SuspExt;
const uint16_t Rw11Cpu::kCPSTAT_M_SuspInt;
const uint16_t Rw11Cpu::kCPSTAT_M_CpuRust;
const uint16_t Rw11Cpu::kCPSTAT_V_CpuRust;
const uint16_t Rw11Cpu::kCPSTAT_B_CpuRust;
const uint16_t Rw11Cpu::kCPSTAT_M_CpuSusp;
const uint16_t Rw11Cpu::kCPSTAT_M_CpuGo;
const uint16_t Rw11Cpu::kCPSTAT_M_CmdMErr;
const uint16_t Rw11Cpu::kCPSTAT_M_CmdErr;
 
const uint16_t Rw11Cpu::kCPURUST_INIT;
const uint16_t Rw11Cpu::kCPURUST_HALT;
const uint16_t Rw11Cpu::kCPURUST_RESET;
const uint16_t Rw11Cpu::kCPURUST_STOP;
const uint16_t Rw11Cpu::kCPURUST_STEP;
const uint16_t Rw11Cpu::kCPURUST_SUSP;
const uint16_t Rw11Cpu::kCPURUST_RUNS;
const uint16_t Rw11Cpu::kCPURUST_VECFET;
const uint16_t Rw11Cpu::kCPURUST_RECRSV;
const uint16_t Rw11Cpu::kCPURUST_SFAIL;
const uint16_t Rw11Cpu::kCPURUST_VFAIL;
 
const uint16_t Rw11Cpu::kCPAH_M_ADDR;
const uint16_t Rw11Cpu::kCPAH_M_22BIT;
const uint16_t Rw11Cpu::kCPAH_M_UBMAP;
 
const uint16_t Rw11Cpu::kCPMEMBE_M_STICK;
const uint16_t Rw11Cpu::kCPMEMBE_M_BE;
 
const uint8_t Rw11Cpu::kStat_M_CmdErr;
const uint8_t Rw11Cpu::kStat_M_CmdMErr;
const uint8_t Rw11Cpu::kStat_M_CpuHalt;
const uint8_t Rw11Cpu::kStat_M_CpuGo;
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11Cpu::Rw11Cpu(const std::string& type)
: fpW11(nullptr),
fType(type),
fIndex(0),
fBase(0),
fIBase(0x4000),
fCpuGo(0),
fCpuStat(0),
fCpuGoMutex(),
fCpuGoCond(),
fCntlMap(),
fIAddrMap(),
fRAddrMap(),
fStats()
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11Cpu::~Rw11Cpu()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::Setup(Rw11* pw11)
{
fpW11 = pw11;
// add control port address rbus mappings
AllRAddrMapInsert("conf" , Base()+kCPCONF);
AllRAddrMapInsert("cntl" , Base()+kCPCNTL);
AllRAddrMapInsert("stat" , Base()+kCPSTAT);
AllRAddrMapInsert("psw" , Base()+kCPPSW);
AllRAddrMapInsert("al" , Base()+kCPAL);
AllRAddrMapInsert("ah" , Base()+kCPAH);
AllRAddrMapInsert("mem" , Base()+kCPMEM);
AllRAddrMapInsert("memi" , Base()+kCPMEMI);
AllRAddrMapInsert("r0" , Base()+kCPR0);
AllRAddrMapInsert("r1" , Base()+kCPR0+1);
AllRAddrMapInsert("r2" , Base()+kCPR0+2);
AllRAddrMapInsert("r3" , Base()+kCPR0+3);
AllRAddrMapInsert("r4" , Base()+kCPR0+4);
AllRAddrMapInsert("r5" , Base()+kCPR0+5);
AllRAddrMapInsert("sp" , Base()+kCPR0+6);
AllRAddrMapInsert("pc" , Base()+kCPR0+7);
AllRAddrMapInsert("membe",Base()+kCPMEMBE);
 
// add cpu register address ibus and rbus mappings
AllIAddrMapInsert("psw" , 0177776);
AllIAddrMapInsert("stklim" , 0177774);
AllIAddrMapInsert("pirq" , 0177772);
AllIAddrMapInsert("mbrk" , 0177770);
AllIAddrMapInsert("cpuerr" , 0177766);
AllIAddrMapInsert("sysid" , 0177764);
AllIAddrMapInsert("hisize" , 0177762);
AllIAddrMapInsert("losize" , 0177760);
 
AllIAddrMapInsert("hm" , 0177752);
AllIAddrMapInsert("maint" , 0177750);
AllIAddrMapInsert("cntrl" , 0177746);
AllIAddrMapInsert("syserr" , 0177744);
AllIAddrMapInsert("hiaddr" , 0177742);
AllIAddrMapInsert("loaddr" , 0177740);
 
AllIAddrMapInsert("ssr2" , 0177576);
AllIAddrMapInsert("ssr1" , 0177574);
AllIAddrMapInsert("ssr0" , 0177572);
 
AllIAddrMapInsert("sdreg" , 0177570);
 
AllIAddrMapInsert("ssr3" , 0172516);
 
// add mmu segment register files
string sdr = "sdr";
string sar = "sar";
for (char i=0; i<8; i++) {
char ichar = '0'+i;
AllIAddrMapInsert(sdr+"ki."+ichar, 0172300+2*i);
AllIAddrMapInsert(sdr+"kd."+ichar, 0172320+2*i);
AllIAddrMapInsert(sar+"ki."+ichar, 0172340+2*i);
AllIAddrMapInsert(sar+"kd."+ichar, 0172360+2*i);
AllIAddrMapInsert(sdr+"si."+ichar, 0172200+2*i);
AllIAddrMapInsert(sdr+"sd."+ichar, 0172220+2*i);
AllIAddrMapInsert(sar+"si."+ichar, 0172240+2*i);
AllIAddrMapInsert(sar+"sd."+ichar, 0172260+2*i);
AllIAddrMapInsert(sdr+"ui."+ichar, 0177600+2*i);
AllIAddrMapInsert(sdr+"ud."+ichar, 0177620+2*i);
AllIAddrMapInsert(sar+"ui."+ichar, 0177640+2*i);
AllIAddrMapInsert(sar+"ud."+ichar, 0177660+2*i);
}
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::AddCntl(const boost::shared_ptr<Rw11Cntl>& spcntl)
{
if (!spcntl)
throw Rexception("Rw11Cpu::AddCntl","Bad args: spcntl == 0");
 
string name(spcntl->Name());
if (fCntlMap.find(name) != fCntlMap.end())
throw Rexception("Rw11Cpu::AddCntl",
"Bad state: duplicate controller name");;
 
fCntlMap.insert(cmap_val_t(name, spcntl));
spcntl->SetCpu(this);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Cpu::TestCntl(const std::string& name) const
{
return fCntlMap.find(name) != fCntlMap.end();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::ListCntl(std::vector<std::string>& list) const
{
list.clear();
for (cmap_cit_t it=fCntlMap.begin(); it!=fCntlMap.end(); it++) {
list.push_back((it->second)->Name());
}
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
Rw11Cntl& Rw11Cpu::Cntl(const std::string& name) const
{
cmap_cit_t it=fCntlMap.find(name);
if (it == fCntlMap.end())
throw Rexception("Rw11Cpu::Cntl()",
"Bad args: controller name '" + name + "' unknown");
return *(it->second);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::Start()
{
for (cmap_cit_t it=fCntlMap.begin(); it!=fCntlMap.end(); it++) {
Rw11Cntl& cntl(*(it->second));
cntl.Probe();
if (cntl.ProbeStatus().Found() && cntl.Enable()) {
cntl.Start();
}
}
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
std::string Rw11Cpu::NextCntlName(const std::string& base) const
{
for (char let='a'; let<='z'; let++) {
string name = base + let;
if (fCntlMap.find(name) == fCntlMap.end()) return name;
}
throw Rexception("Rw11Cpu::NextCntlName",
"Bad args: all controller letters used for '" + base + "'");
return "";
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11Cpu::AddMembe(RlinkCommandList& clist, uint16_t be, bool stick)
{
uint16_t data = be & kCPMEMBE_M_BE;
if (stick) data |= kCPMEMBE_M_STICK;
return clist.AddWreg(fBase+kCPMEMBE, data);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11Cpu::AddRibr(RlinkCommandList& clist, uint16_t ibaddr)
{
if ((ibaddr & 0160001) != 0160000)
throw Rexception("Rw11Cpu::AddRibr", "ibaddr out of IO page or odd");
return clist.AddRreg(IbusRemoteAddr(ibaddr));
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11Cpu::AddWibr(RlinkCommandList& clist, uint16_t ibaddr, uint16_t data)
{
if ((ibaddr & 0160001) != 0160000)
throw Rexception("Rw11Cpu::AddWibr", "ibaddr out of IO page or odd");
 
return clist.AddWreg(IbusRemoteAddr(ibaddr), data);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
int Rw11Cpu::AddRbibr(RlinkCommandList& clist, uint16_t ibaddr, size_t size)
{
if ((ibaddr & 0160001) != 0160000)
throw Rexception("Rw11Cpu::AddRbibr", "ibaddr out of IO page or odd");
return clist.AddRblk(IbusRemoteAddr(ibaddr), size);
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
int Rw11Cpu::AddWbibr(RlinkCommandList& clist, uint16_t ibaddr,
std::vector<uint16_t> block)
{
if ((ibaddr & 0160001) != 0160000)
throw Rexception("Rw11Cpu::AddWbibr", "ibaddr out of IO page or odd");
return clist.AddWblk(IbusRemoteAddr(ibaddr), block);
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11Cpu::AddLalh(RlinkCommandList& clist, uint32_t addr, uint16_t mode)
{
uint16_t al = uint16_t(addr);
uint16_t ah = uint16_t(addr>>16) & kCPAH_M_ADDR;
ah |= mode & (kCPAH_M_22BIT|kCPAH_M_UBMAP);
int ind = clist.AddWreg(fBase+kCPAL, al);
clist.AddWreg(fBase+kCPAH, ah);
return ind;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11Cpu::AddRMem(RlinkCommandList& clist, uint32_t addr, uint16_t* buf,
size_t size, uint16_t mode, bool singleblk)
{
size_t blkmax = Connect().BlockSizeMax();
if (singleblk && size > blkmax)
throw Rexception("Rw11Cpu::AddRMem",
"Bad args: singleblk==true && size > BlockSizeMax()");
 
int ind = AddLalh(clist, addr, mode);
while (size > 0) {
size_t bsize = (size>blkmax) ? blkmax : size;
clist.AddRblk(fBase+kCPMEMI, buf, bsize);
buf += bsize;
size -= bsize;
}
return ind;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11Cpu::AddWMem(RlinkCommandList& clist, uint32_t addr,
const uint16_t* buf, size_t size,
uint16_t mode, bool singleblk)
{
size_t blkmax = Connect().BlockSizeMax();
if (singleblk && size > blkmax)
throw Rexception("Rw11Cpu::AddWMem",
"Bad args: singleblk==true && size > BlockSizeMax()");
 
int ind = AddLalh(clist, addr, mode);
while (size > 0) {
size_t bsize = (size>blkmax) ? blkmax : size;
clist.AddWblk(fBase+kCPMEMI, buf, bsize);
buf += bsize;
size -= bsize;
}
return ind;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Cpu::MemRead(uint16_t addr, std::vector<uint16_t>& data,
size_t nword, RerrMsg& emsg)
{
size_t blkmax = Connect().BlockSizePrudent();
data.resize(nword);
size_t ndone = 0;
while (nword>ndone) {
size_t nblk = min(blkmax, nword-ndone);
RlinkCommandList clist;
clist.AddWreg(fBase+kCPAL, addr+2*ndone);
clist.AddRblk(fBase+kCPMEMI, data.data()+ndone, nblk);
if (!Server().Exec(clist, emsg)) return false;
ndone += nblk;
}
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Cpu::MemWrite(uint16_t addr, const std::vector<uint16_t>& data,
RerrMsg& emsg)
{
size_t blkmax = Connect().BlockSizePrudent();
size_t nword = data.size();
size_t ndone = 0;
while (nword>ndone) {
size_t nblk = min(blkmax, nword-ndone);
RlinkCommandList clist;
clist.AddWreg(fBase+kCPAL, addr+2*ndone);
clist.AddWblk(fBase+kCPMEMI, data.data()+ndone, nblk);
if (!Server().Exec(clist, emsg)) return false;
ndone += nblk;
}
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Cpu::ProbeCntl(Rw11Probe& dsc)
{
if (!(dsc.fProbeInt | dsc.fProbeRem) || dsc.fAddr == 0)
throw Rexception("Rw11Cpu::Probe",
"Bad args: fAddr == 0 or fProbeInt|fProbeRem == false");
 
if (!dsc.fProbeDone) {
RlinkCommandList clist;
int iib = -1;
int irb = -1;
if (dsc.fProbeInt) {
clist.AddWreg(fBase+kCPAL, dsc.fAddr);
iib = clist.AddRreg(fBase+kCPMEM);
clist.SetLastExpectStatus(0,0); // disable stat check
}
if (dsc.fProbeRem) {
irb = AddRibr(clist, dsc.fAddr);
clist.SetLastExpectStatus(0,0); // disable stat check
}
 
Server().Exec(clist);
 
if (dsc.fProbeInt) {
dsc.fFoundInt = (clist[iib].Status() &
(RlinkCommand::kStat_M_RbTout |
RlinkCommand::kStat_M_RbNak |
RlinkCommand::kStat_M_RbErr)) ==0;
}
if (dsc.fProbeRem) {
dsc.fFoundRem = (clist[irb].Status() &
(RlinkCommand::kStat_M_RbTout |
RlinkCommand::kStat_M_RbNak |
RlinkCommand::kStat_M_RbErr)) ==0;
}
dsc.fProbeDone = true;
}
 
return dsc.Found();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
// absolute binary format described in notes_ptape.txt
 
bool Rw11Cpu::LoadAbs(const std::string& fname, RerrMsg& emsg, bool trace)
{
int fd = open(fname.c_str(), O_RDONLY);
 
if (fd < 0) {
emsg.InitErrno("Rw11Cpu::LoadAbs()", string("open() for '") + fname +
"' failed: ", errno);
return false;
}
enum states {
s_chr0,
s_chr1,
s_cntlow,
s_cnthgh,
s_adrlow,
s_adrhgh,
s_data,
s_chksum
};
 
typedef std::map<uint16_t, uint16_t> obmap_t;
//typedef obmap_t::iterator obmap_it_t;
typedef obmap_t::const_iterator obmap_cit_t;
typedef obmap_t::value_type obmap_val_t;
 
obmap_t oddbyte; // odd byte cache
 
vector<uint16_t> data;
data.reserve(256);
int chrnum = -1; // char number in block
int blknum = 0; // block number
int bytcnt = 0; // byte count
uint16_t ldaddr = 0; // load address
uint8_t chksum = 0; // check sum
uint16_t addr = 0; // current address
uint16_t word = 0; // current word
 
bool ok = false;
bool go = true;
enum states state = s_chr0;
 
while (go) {
uint8_t byte;
int irc = read(fd, &byte, 1);
if (irc == 0) {
if (state == s_chr0) {
ok = true;
} else {
emsg.Init("Rw11Cpu::LoadAbs()", "unexpected EOF");
}
break;
} else if (irc < 0) {
emsg.InitErrno("Rw11Cpu::LoadAbs()", "read() failed: ", errno);
break;
}
 
chrnum += 1;
chksum += byte;
 
//cout << "+++1 " << blknum << "," << chrnum << " s=" << state << " : "
// << RosPrintBvi(byte,8) << endl;
 
switch (state) {
case s_chr0:
if (byte == 0) {
chrnum = -1;
state = s_chr0;
} else if (byte == 1) {
state = s_chr1;
} else {
emsg.InitPrintf("Rw11Cpu::LoadAbs()",
"unexpected start-of-block %3.3o", byte);
go = false;
}
break;
 
case s_chr1:
if (byte == 0) {
state = s_cntlow;
} else {
emsg.InitPrintf("Rw11Cpu::LoadAbs()",
"unexpected 2nd char %3.3o", byte);
go = false;
}
break;
case s_cntlow:
bytcnt = byte;
state = s_cnthgh;
break;
case s_cnthgh:
bytcnt |= uint16_t(byte) << 8;
state = s_adrlow;
break;
case s_adrlow:
ldaddr = byte;
state = s_adrhgh;
break;
case s_adrhgh:
ldaddr |= uint16_t(byte) << 8;
addr = ldaddr;
word = 0;
if ((addr & 0x01) == 1 && bytcnt > 6) {
obmap_cit_t it = oddbyte.find(addr);
if (it != oddbyte.end()) {
word = it->second;
} else {
if (trace) {
RlogMsg lmsg(LogFile());
lmsg << "LoadAbs-W: no low byte data for " << RosPrintBvi(addr,8);
}
}
}
if (trace) {
RlogMsg lmsg(Connect().LogFile());
lmsg << "LoadAbs-I: block " << RosPrintf(blknum,"d",3)
<< ", length " << RosPrintf(bytcnt-6,"d",5)
<< " byte, address " << RosPrintBvi(ldaddr,8)
<< ":" << RosPrintBvi(uint16_t(ldaddr+(bytcnt-6)-1),8);
}
state = (bytcnt == 6) ? s_chksum : s_data;
break;
case s_data:
if ((addr & 0x01) == 0) { // even (low) byte
word = byte;
} else { // odd (high) byte
word |= uint16_t(byte) << 8;
data.push_back(word);
}
addr += 1;
if (chrnum == bytcnt-1) state = s_chksum;
break;
case s_chksum:
if (chksum != 0) {
emsg.InitPrintf("Rw11Cpu::LoadAbs()", "check sum error %3.3o", chksum);
go = false;
} else if (bytcnt == 6) {
if (trace) {
RlogMsg lmsg(Connect().LogFile());
lmsg << "LoadAbs-I: start address " << RosPrintBvi(ldaddr,8);
}
go = false;
ok = true;
} else {
if ((addr & 0x01) == 1) { // high byte not yet seen
data.push_back(word); // zero fill high byte
oddbyte.insert(obmap_val_t(addr,word)); // store even byte for later
}
 
//cout << "+++2 " << RosPrintBvi(ldaddr,8)
// << " " << data.size() << endl;
if (!MemWrite(ldaddr, data, emsg)) {
go = false;
}
data.clear();
}
chrnum = -1;
blknum += 1;
state = s_chr0;
break;
 
} // switch(state)
} // while(go)
close(fd);
return ok;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Cpu::Boot(const std::string& uname, RerrMsg& emsg)
{
string cname;
size_t uind=0;
for (size_t i=0; i<uname.length(); i++) {
char c = uname[i];
if (c >= '0' && c <= '9') {
string unum = uname.substr(i);
uind = ::atoi(unum.c_str());
break;
} else {
cname.push_back(c);
}
}
 
if (!TestCntl(cname)) {
emsg.Init("Rw11Cpu::Boot", string("controller '") + cname + "' not known");
return false;
}
 
Rw11Cntl& cntl = Cntl(cname);
if (uind >= cntl.NUnit()) {
emsg.Init("Rw11Cpu::Boot", string("unit number '") + uname + "' invalid");
return false;
}
 
vector<uint16_t> code;
uint16_t aload = 0;
uint16_t astart = 0;
 
if (!cntl.BootCode(uind, code, aload, astart) || code.size()==0) {
emsg.Init("Rw11Cpu::Boot", string("boot not supported for controller '")
+ cname + "'");
return false;
}
 
// stop and reset cpu, just in case
RlinkCommandList clist;
clist.AddWreg(fBase+kCPCNTL, kCPFUNC_STOP); // stop cpu
clist.AddWreg(fBase+kCPCNTL, kCPFUNC_CRESET); // init cpu and bus
if (!Server().Exec(clist, emsg)) return false;
 
// load boot code
if (!MemWrite(aload, code, emsg)) return false;
// and start cpu at boot loader start address
clist.Clear();
clist.AddWreg(fBase+kCPPC, astart); // load PC
clist.AddWreg(fBase+kCPCNTL, kCPFUNC_START); // and start
SetCpuGoUp();
if (!Server().Exec(clist, emsg)) return false;
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::SetCpuGoUp()
{
boost::lock_guard<boost::mutex> lock(fCpuGoMutex);
fCpuGo = true;
fCpuStat = 0;
fCpuGoCond.notify_all();
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::SetCpuGoDown(uint16_t stat)
{
if ((stat & kCPSTAT_M_CpuGo) == 0) {
boost::lock_guard<boost::mutex> lock(fCpuGoMutex);
fCpuGo = false;
fCpuStat = stat;
fCpuGoCond.notify_all();
}
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
double Rw11Cpu::WaitCpuGoDown(double tout)
{
boost::system_time t0(boost::get_system_time());
boost::system_time timeout(boost::posix_time::max_date_time);
if (tout > 0.)
timeout = t0 + boost::posix_time::microseconds((long)1E6 * tout);
boost::unique_lock<boost::mutex> lock(fCpuGoMutex);
while (fCpuGo) {
if (!fCpuGoCond.timed_wait(lock, timeout)) return -1.;
}
boost::posix_time::time_duration dt = boost::get_system_time() - t0;
return double(dt.ticks()) / dt.ticks_per_second();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::AllIAddrMapInsert(const std::string& name, uint16_t ibaddr)
{
IAddrMapInsert(name, ibaddr);
uint16_t rbaddr = IbusRemoteAddr(ibaddr);
RAddrMapInsert(name, rbaddr);
 
// add ix. to name in common Connect AddrMap to keep name unique
string cname = "i";
cname += '0'+Index();
cname += '.';
cname += name;
Connect().AddrMapInsert(cname, rbaddr);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::AllRAddrMapInsert(const std::string& name, uint16_t rbaddr)
{
RAddrMapInsert(name, rbaddr);
 
// add cx. to name in common Connect AddrMap to keep name unique
string cname = "c";
cname += '0'+Index();
cname += '.';
cname += name;
Connect().AddrMapInsert(cname, rbaddr);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::W11AttnHandler()
{
RlinkCommandList clist;
clist.AddRreg(fBase+kCPSTAT);
Server().Exec(clist);
SetCpuGoDown(clist[0].Data());
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cpu::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11Cpu @ " << this << endl;
 
os << bl << " fpW11: " << fpW11 << endl;
os << bl << " fType: " << fType << endl;
os << bl << " fIndex: " << fIndex << endl;
os << bl << " fBase: " << RosPrintf(fBase,"$x0",4) << endl;
os << bl << " fIBase: " << RosPrintf(fIBase,"$x0",4) << endl;
os << bl << " fCpuGo: " << fCpuGo << endl;
os << bl << " fCpuStat: " << RosPrintf(fCpuStat,"$x0",4) << endl;
os << bl << " fCntlMap: " << endl;
for (cmap_cit_t it=fCntlMap.begin(); it!=fCntlMap.end(); it++) {
os << bl << " " << RosPrintf((it->first).c_str(), "-s",8)
<< " : " << it->second << endl;
}
fIAddrMap.Dump(os, ind+2, "fIAddrMap: ");
fRAddrMap.Dump(os, ind+2, "fRAddrMap: ");
fStats.Dump(os, ind+2, "fStats: ");
return;
}
 
} // end namespace Retro
/Rw11UnitTM11.ipp
0,0 → 1,52
// $Id: Rw11UnitTM11.ipp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-17 683 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitTM11.ipp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation (inline) of Rw11UnitTM11.
*/
 
#include "Rw11UnitTM11.hpp"
 
/*!
\class Retro::Rw11UnitTM11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitTM11::SetTmds(uint16_t tmds)
{
fTmds = tmds;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11UnitTM11::Tmds() const
{
return fTmds;
}
 
} // end namespace Retro
/Rw11UnitTapeBase.hpp
0,0 → 1,56
// $Id: Rw11UnitTapeBase.hpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-17 683 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitTapeBase.hpp 686 2015-06-04 21:08:08Z mueller $
\brief Declaration of class Rw11UnitTapeBase.
*/
 
#ifndef included_Retro_Rw11UnitTapeBase
#define included_Retro_Rw11UnitTapeBase 1
 
#include "Rw11UnitTape.hpp"
 
namespace Retro {
 
template <class TC>
class Rw11UnitTapeBase : public Rw11UnitTape {
public:
 
Rw11UnitTapeBase(TC* pcntl, size_t index);
~Rw11UnitTapeBase();
 
TC& Cntl() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
virtual void AttachDone();
virtual void DetachDone();
 
protected:
TC* fpCntl;
};
} // end namespace Retro
 
#include "Rw11UnitTapeBase.ipp"
 
#endif
/Rw11VirtDiskFile.cpp
0,0 → 1,175
// $Id: Rw11VirtDiskFile.cpp 684 2015-05-24 14:10:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-04-14 506 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtDiskFile.cpp 684 2015-05-24 14:10:59Z mueller $
\brief Implemenation of Rw11VirtDiskFile.
*/
 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
 
#include "librtools/RosFill.hpp"
 
#include "Rw11VirtDiskFile.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11VirtDiskFile
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11VirtDiskFile::Rw11VirtDiskFile(Rw11Unit* punit)
: Rw11VirtDisk(punit),
fFd(0)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11VirtDiskFile::~Rw11VirtDiskFile()
{
if (fFd > 2) ::close(fFd);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtDiskFile::Open(const std::string& url, RerrMsg& emsg)
{
if (!fUrl.Set(url, "|wpro|", emsg)) return false;
 
bool wpro = fUrl.FindOpt("wpro");
int fd = ::open(fUrl.Path().c_str(), wpro ? O_RDONLY : O_RDWR);
if (fd < 0) {
emsg.InitErrno("Rw11VirtDiskFile::Open()",
string("open() for '") + fUrl.Path() + "' failed: ", errno);
return false;
}
 
struct stat sbuf;
if (::fstat(fd, &sbuf) < 0) {
emsg.InitErrno("Rw11VirtDiskFile::Open()",
string("stat() for '") + fUrl.Path() + "' failed: ", errno);
return false;
}
 
fFd = fd;
fSize = sbuf.st_size;
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtDiskFile::Read(size_t lba, size_t nblk, uint8_t* data,
RerrMsg& emsg)
{
fStats.Inc(kStatNVDRead);
fStats.Inc(kStatNVDReadBlk, double(nblk));
 
size_t seekpos = fBlkSize * lba;
size_t nbyt = fBlkSize * nblk;
 
if (seekpos >= fSize) {
uint8_t* p = data;
for (size_t i=0; i<nbyt; i++) *p++ = 0;
return true;
}
 
if (!Seek(seekpos, emsg)) return false;
ssize_t irc = ::read(fFd, data, nbyt);
if (irc < 0) {
emsg.InitErrno("Rw11VirtDiskFile::Read()", "read() failed: ", errno);
return false;
}
 
if (irc < ssize_t(nbyt)) {
uint8_t* p = data+irc;
for (size_t i=irc; i<nbyt; i++) *p++ = 0;
}
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtDiskFile::Write(size_t lba, size_t nblk, const uint8_t* data,
RerrMsg& emsg)
{
fStats.Inc(kStatNVDWrite);
fStats.Inc(kStatNVDWriteBlk, double(nblk));
 
size_t seekpos = fBlkSize * lba;
size_t nbyt = fBlkSize * nblk;
 
if (!Seek(seekpos, emsg)) return false;
 
ssize_t irc = ::write(fFd, data, nbyt);
if (irc < ssize_t(nbyt)) {
emsg.InitErrno("Rw11VirtDiskFile::Write()", "write() failed: ", errno);
return false;
}
 
if (seekpos+nbyt > fSize) fSize = seekpos+nbyt;
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtDiskFile::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11VirtDiskFile @ " << this << endl;
 
os << bl << " fFd: " << fFd << endl;
os << bl << " fSize: " << fSize << endl;
Rw11VirtDisk::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtDiskFile::Seek(size_t seekpos, RerrMsg& emsg)
{
if (::lseek(fFd, seekpos, SEEK_SET) < 0) {
emsg.InitErrno("Rw11VirtDiskFile::Seek()", "seek() failed: ", errno);
return false;
}
 
return true;
}
 
} // end namespace Retro
/Rw11CntlRL11.cpp
0,0 → 1,767
// $Id: Rw11CntlRL11.cpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2014-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
// Other credits:
// the boot code is from the simh project and Copyright Robert M Supnik
// CalcCrc() is adopted from the simh project and Copyright Robert M Supnik
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0.2 check for spurious lams
// 2015-03-04 655 1.0.1 use original boot code again
// 2015-03-01 653 1.0 Initial version
// 2014-06-08 561 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlRL11.cpp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation of Rw11CntlRL11.
*/
 
#include "boost/bind.hpp"
#include "boost/foreach.hpp"
#define foreach_ BOOST_FOREACH
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintBvi.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
#include "librtools/RlogMsg.hpp"
 
#include "Rw11CntlRL11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11CntlRL11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11CntlRL11::kIbaddr;
const int Rw11CntlRL11::kLam;
 
const uint16_t Rw11CntlRL11::kRLCS;
const uint16_t Rw11CntlRL11::kRLBA;
const uint16_t Rw11CntlRL11::kRLDA;
const uint16_t Rw11CntlRL11::kRLMP;
 
const uint16_t Rw11CntlRL11::kProbeOff;
const bool Rw11CntlRL11::kProbeInt;
const bool Rw11CntlRL11::kProbeRem;
 
const uint16_t Rw11CntlRL11::kRLCS_M_ERR;
const uint16_t Rw11CntlRL11::kRLCS_M_DE;
const uint16_t Rw11CntlRL11::kRLCS_V_E;
const uint16_t Rw11CntlRL11::kRLCS_B_E;
const uint16_t Rw11CntlRL11::kRLCS_V_DS;
const uint16_t Rw11CntlRL11::kRLCS_B_DS;
const uint16_t Rw11CntlRL11::kRLCS_M_CRDY;
const uint16_t Rw11CntlRL11::kRLCS_M_IE;
const uint16_t Rw11CntlRL11::kRLCS_M_BAE;
const uint16_t Rw11CntlRL11::kRLCS_V_BAE;
const uint16_t Rw11CntlRL11::kRLCS_B_BAE;
const uint16_t Rw11CntlRL11::kRLCS_V_FUNC;
const uint16_t Rw11CntlRL11::kRLCS_B_FUNC;
const uint16_t Rw11CntlRL11::kRLCS_M_DRDY;
 
const uint16_t Rw11CntlRL11::kFUNC_NOOP;
const uint16_t Rw11CntlRL11::kFUNC_WCHK;
const uint16_t Rw11CntlRL11::kFUNC_GS;
const uint16_t Rw11CntlRL11::kFUNC_SEEK;
const uint16_t Rw11CntlRL11::kFUNC_RHDR;
const uint16_t Rw11CntlRL11::kFUNC_WRITE;
const uint16_t Rw11CntlRL11::kFUNC_READ;
const uint16_t Rw11CntlRL11::kFUNC_RNHC;
 
const uint16_t Rw11CntlRL11::kERR_M_DE;
const uint16_t Rw11CntlRL11::kERR_OPI;
const uint16_t Rw11CntlRL11::kERR_WCHK;
const uint16_t Rw11CntlRL11::kERR_HCRC;
const uint16_t Rw11CntlRL11::kERR_DLATE;
const uint16_t Rw11CntlRL11::kERR_HNFND;
const uint16_t Rw11CntlRL11::kERR_NXM;
 
const uint16_t Rw11CntlRL11::kRLCS_V_MPREM;
const uint16_t Rw11CntlRL11::kRLCS_B_MPREM;
const uint16_t Rw11CntlRL11::kRLCS_V_MPLOC;
const uint16_t Rw11CntlRL11::kRLCS_B_MPLOC;
const uint16_t Rw11CntlRL11::kRLCS_ENA_MPREM;
const uint16_t Rw11CntlRL11::kRLCS_ENA_MPLOC;
 
const uint16_t Rw11CntlRL11::kRFUNC_WCS;
const uint16_t Rw11CntlRL11::kRFUNC_WMP;
 
const uint16_t Rw11CntlRL11::kMPREM_M_MAP;
const uint16_t Rw11CntlRL11::kMPREM_M_SEQ;
const uint16_t Rw11CntlRL11::kMPREM_S_MP;
const uint16_t Rw11CntlRL11::kMPREM_S_STA;
const uint16_t Rw11CntlRL11::kMPREM_S_POS;
 
const uint16_t Rw11CntlRL11::kMPREM_MP;
const uint16_t Rw11CntlRL11::kMPREM_CRC;
const uint16_t Rw11CntlRL11::kMPREM_STA;
const uint16_t Rw11CntlRL11::kMPREM_POS;
 
const uint16_t Rw11CntlRL11::kMPREM_SEQ_MPSTAPOS;
 
const uint16_t Rw11CntlRL11::kMPLOC_MP;
const uint16_t Rw11CntlRL11::kMPLOC_STA;
const uint16_t Rw11CntlRL11::kMPLOC_POS;
const uint16_t Rw11CntlRL11::kMPLOC_ZERO;
const uint16_t Rw11CntlRL11::kMPLOC_CRC;
 
const uint16_t Rw11CntlRL11::kRLDA_SE_M_DF;
const uint16_t Rw11CntlRL11::kRLDA_SE_V_DF;
const uint16_t Rw11CntlRL11::kRLDA_SE_B_DF;
const uint16_t Rw11CntlRL11::kRLDA_SE_M_HS;
const uint16_t Rw11CntlRL11::kRLDA_SE_M_DIR;
const uint16_t Rw11CntlRL11::kRLDA_SE_X_MSK;
const uint16_t Rw11CntlRL11::kRLDA_SE_X_VAL;
 
const uint16_t Rw11CntlRL11::kRLDA_RW_M_CA;
const uint16_t Rw11CntlRL11::kRLDA_RW_V_CA;
const uint16_t Rw11CntlRL11::kRLDA_RW_B_CA;
const uint16_t Rw11CntlRL11::kRLDA_RW_M_HS;
const uint16_t Rw11CntlRL11::kRLDA_RW_V_HS;
const uint16_t Rw11CntlRL11::kRLDA_RW_B_HS;
const uint16_t Rw11CntlRL11::kRLDA_RW_B_SA;
 
const uint16_t Rw11CntlRL11::kRLDA_GS_M_RST;
const uint16_t Rw11CntlRL11::kRLDA_GS_X_MSK;
const uint16_t Rw11CntlRL11::kRLDA_GS_X_VAL;
 
const uint16_t Rw11CntlRL11::kSTA_M_WDE;
const uint16_t Rw11CntlRL11::kSTA_M_CHE;
const uint16_t Rw11CntlRL11::kSTA_M_WL;
const uint16_t Rw11CntlRL11::kSTA_M_STO;
const uint16_t Rw11CntlRL11::kSTA_M_SPE;
const uint16_t Rw11CntlRL11::kSTA_M_WGE;
const uint16_t Rw11CntlRL11::kSTA_M_VCE;
const uint16_t Rw11CntlRL11::kSTA_M_DSE;
const uint16_t Rw11CntlRL11::kSTA_M_DT;
const uint16_t Rw11CntlRL11::kSTA_M_HS;
const uint16_t Rw11CntlRL11::kSTA_M_CO;
const uint16_t Rw11CntlRL11::kSTA_M_HO;
const uint16_t Rw11CntlRL11::kSTA_M_BH;
const uint16_t Rw11CntlRL11::kSTA_B_ST;
 
const uint16_t Rw11CntlRL11::kST_LOAD;
const uint16_t Rw11CntlRL11::kST_SPIN;
const uint16_t Rw11CntlRL11::kST_BRUSH;
const uint16_t Rw11CntlRL11::kST_HLOAD;
const uint16_t Rw11CntlRL11::kST_SEEK;
const uint16_t Rw11CntlRL11::kST_LOCK;
const uint16_t Rw11CntlRL11::kST_UNL;
const uint16_t Rw11CntlRL11::kST_DOWN;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11CntlRL11::Rw11CntlRL11()
: Rw11CntlBase<Rw11UnitRL11,4>("rl11"),
fPC_rlcs(0),
fPC_rlba(0),
fPC_rlda(0),
fPC_imp(0),
fPC_wc(0),
fPC_sta(0),
fPC_pos(0),
fRd_rlcs(0),
fRd_rlda(0),
fRd_rlmp(0),
fRd_sta(0),
fRd_pos(0),
fRd_addr(0),
fRd_lba(0),
fRd_nwrd(0),
fRd_fu(0),
fRd_ovr(false),
fRdma(this,
boost::bind(&Rw11CntlRL11::RdmaPreExecCB, this, _1, _2, _3, _4),
boost::bind(&Rw11CntlRL11::RdmaPostExecCB, this, _1, _2, _3, _4))
{
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
for (size_t i=0; i<NUnit(); i++) {
fspUnit[i].reset(new Rw11UnitRL11(this, i));
}
 
fStats.Define(kStatNFuncWchk , "NFuncWchk" , "func WCHK");
fStats.Define(kStatNFuncRhdr , "NFuncRhdr" , "func RHDR");
fStats.Define(kStatNFuncWrite , "NFuncWrite" , "func WRITE");
fStats.Define(kStatNFuncRead , "NFuncRead" , "func READ");
fStats.Define(kStatNFuncRnhc , "NFuncRnhc" , "func RNHC");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11CntlRL11::~Rw11CntlRL11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::Config(const std::string& name, uint16_t base, int lam)
{
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::Start()
{
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
throw Rexception("Rw11CntlRL11::Start",
"Bad state: started, no lam, not enable, not found");
 
// add device register address ibus and rbus mappings
// done here because now Cntl bound to Cpu and Cntl probed
Cpu().AllIAddrMapInsert(Name()+".cs", Base() + kRLCS);
Cpu().AllIAddrMapInsert(Name()+".ba", Base() + kRLBA);
Cpu().AllIAddrMapInsert(Name()+".da", Base() + kRLDA);
Cpu().AllIAddrMapInsert(Name()+".mp", Base() + kRLMP);
 
// setup primary info clist
fPrimClist.Clear();
fPrimClist.AddAttn();
fPC_rlcs = Cpu().AddRibr(fPrimClist, fBase+kRLCS);
fPC_rlba = Cpu().AddRibr(fPrimClist, fBase+kRLBA);
fPC_rlda = Cpu().AddRibr(fPrimClist, fBase+kRLDA);
fPC_imp = Cpu().AddWibr(fPrimClist, fBase+kRLCS,
(kMPREM_SEQ_MPSTAPOS << kRLCS_V_MPREM) |
kRLCS_ENA_MPREM |
(kRFUNC_WMP << kRLCS_V_FUNC) );
fPC_wc = Cpu().AddRibr(fPrimClist, fBase+kRLMP);
fPC_sta = Cpu().AddRibr(fPrimClist, fBase+kRLMP);
fPC_pos = Cpu().AddRibr(fPrimClist, fBase+kRLMP);
 
// add attn handler
Server().AddAttnHandler(boost::bind(&Rw11CntlRL11::AttnHandler, this, _1),
uint16_t(1)<<fLam, (void*)this);
 
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::UnitSetup(size_t ind)
{
Rw11UnitRL11& unit = *fspUnit[ind];
RlinkCommandList clist;
 
// only two mayor drive states are used
// on: st=lock; ho=1; bh=1; co=0; wl=? ( file attached)
// off: st=load; ho=0; bh=1; co=1; (no file attached)
 
uint16_t sta = 0;
if (unit.Type() == "rl02") // is it RL02
sta |= kSTA_M_DT; // set DT bit (1=RL02,0=RL01)
 
if (unit.Virt()) { // file attached
sta |= kSTA_M_HO | kSTA_M_BH | kST_LOCK; // HO=1; BH=1; ST=LOCK
if (unit.WProt()) // in case write protected
sta |= kSTA_M_WL; // WL=1
} else { // no file attached
sta |= kSTA_M_CO | kSTA_M_BH | kST_LOAD; // CO=1; BH=1; ST=LOAD
AddSetPosition(clist, ind, 0); // well defined value to pos
}
 
unit.SetRlsta(sta);
AddSetStatus(clist, ind, sta);
Server().Exec(clist);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs ????
 
bool Rw11CntlRL11::BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart)
{
uint16_t kBOOT_START = 02000;
uint16_t bootcode[] = { // rl11 boot loader - from simh pdp11_rl.c (v3.9)
0042114, // "LD"
0012706, kBOOT_START, // MOV #boot_start, SP
0012700, uint16_t(unit), // MOV #unit, R0
0010003, // MOV R0, R3
0000303, // SWAB R3
0012701, 0174400, // MOV #RLCS, R1 ; csr
0012761, 0000013, 0000004, // MOV #13, 4(R1) ; clr err
0052703, 0000004, // BIS #4, R3 ; unit+gstat
0010311, // MOV R3, (R1) ; issue cmd
0105711, // TSTB (R1) ; wait
0100376, // BPL .-2
0105003, // CLRB R3
0052703, 0000010, // BIS #10, R3 ; unit+rdhdr
0010311, // MOV R3, (R1) ; issue cmd
0105711, // TSTB (R1) ; wait
0100376, // BPL .-2
0016102, 0000006, // MOV 6(R1), R2 ; get hdr
0042702, 0000077, // BIC #077, R2 ; clr head+sector
0005202, // INC R2 ; magic bit
0010261, 0000004, // MOV R2, 4(R1) ; seek to 0
0105003, // CLRB R3
0052703, 0000006, // BIS #6, R3 ; unit+seek
0010311, // MOV R3, (R1) ; issue cmd
0105711, // TSTB (R1) ; wait
0100376, // BPL .-2
0005061, 0000002, // CLR 2(R1) ; clr ba
0005061, 0000004, // CLR 4(R1) ; clr da
0012761, 0177000, 0000006, // MOV #-512., 6(R1) ; set wc
0105003, // CLRB R3
0052703, 0000014, // BIS #14, R3 ; unit+read
0010311, // MOV R3, (R1) ; issue cmd
0105711, // TSTB (R1) ; wait
0100376, // BPL .-2
0042711, 0000377, // BIC #377, (R1)
0005002, // CLR R2
0005003, // CLR R3
0012704, uint16_t(kBOOT_START+020), // MOV #START+20, R4 ; load #rlcs
0005005, // CLR R5
0005007 // CLR PC
};
code.clear();
foreach_ (uint16_t& w, bootcode) code.push_back(w);
aload = kBOOT_START;
astart = kBOOT_START+2;
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlRL11 @ " << this << endl;
os << bl << " fPC_rlcs: " << RosPrintf(fPC_rlcs,"d",6) << endl;
os << bl << " fPC_rlba: " << RosPrintf(fPC_rlba,"d",6) << endl;
os << bl << " fPC_rlda: " << RosPrintf(fPC_rlda,"d",6) << endl;
os << bl << " fPC_imp: " << RosPrintf(fPC_imp,"d",6) << endl;
os << bl << " fPC_wc: " << RosPrintf(fPC_wc,"d",6) << endl;
os << bl << " fPC_sta: " << RosPrintf(fPC_sta,"d",6) << endl;
os << bl << " fPC_pos: " << RosPrintf(fPC_pos,"d",6) << endl;
os << bl << " fRd_rlcs: " << RosPrintBvi(fRd_rlcs,8) << endl;
os << bl << " fRd_rlda: " << RosPrintBvi(fRd_rlda,8) << endl;
os << bl << " fRd_rlmp: " << RosPrintBvi(fRd_rlmp,8) << endl;
os << bl << " fRd_sta: " << RosPrintBvi(fRd_sta,8) << endl;
os << bl << " fRd_pos: " << RosPrintBvi(fRd_pos,8) << endl;
os << bl << " fRd_addr: " << RosPrintBvi(fRd_addr,8,22) << endl;
os << bl << " fRd_lba: " << RosPrintf(fRd_lba,"d",6) << endl;
os << bl << " fRd_nwrd: " << RosPrintf(fRd_nwrd,"d",6) << endl;
os << bl << " fRd_fu: " << RosPrintf(fRd_fu,"d",6) << endl;
os << bl << " fRd_ovr: " << fRd_ovr << endl;
fRdma.Dump(os, ind+2, "fRdma: ");
Rw11CntlBase<Rw11UnitRL11,4>::Dump(os, ind, " ^");
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11CntlRL11::AttnHandler(RlinkServer::AttnArgs& args)
{
fStats.Inc(kStatNAttnHdl);
Server().GetAttnInfo(args, fPrimClist);
 
uint16_t rlcs = fPrimClist[fPC_rlcs].Data();
uint16_t rlba = fPrimClist[fPC_rlba].Data();
uint16_t rlda = fPrimClist[fPC_rlda].Data();
uint16_t wc = fPrimClist[fPC_wc ].Data();
uint16_t sta = fPrimClist[fPC_sta ].Data();
uint16_t pos = fPrimClist[fPC_pos ].Data();
 
uint16_t ds = (rlcs>>kRLCS_V_DS) & kRLCS_B_DS;
uint16_t fu = (rlcs>>kRLCS_V_FUNC) & kRLCS_B_FUNC;
uint16_t bae = (rlcs>>kRLCS_V_BAE) & kRLCS_B_BAE;
 
uint32_t addr = uint32_t(bae)<<16 | uint32_t(rlba);
 
uint16_t sa = rlda & kRLDA_RW_B_SA;
uint16_t hs = (rlda>>kRLDA_RW_V_HS) & kRLDA_RW_B_HS;
uint16_t ca = (rlda>>kRLDA_RW_V_CA) & kRLDA_RW_B_CA;
 
uint32_t nwrd = (~uint32_t(wc)&0xffff) + 1; // transfer size in words
 
// all 4 units are always available, but check anyway
if (ds > NUnit())
throw Rexception("Rw11CntlRL11::AttnHandler","Bad state: ds > NUnit()");
 
Rw11UnitRL11& unit = *fspUnit[ds];
Rw11Cpu& cpu = Cpu();
RlinkCommandList clist;
 
uint32_t lba = unit.Chs2Lba(ca,hs,sa);
uint32_t nblk = unit.Nwrd2Nblk(nwrd);
 
// check for overrun (read/write beyond track)
// if found, truncate request length
bool ovr = false;
if (fu==kFUNC_WRITE || fu==kFUNC_WCHK || fu==kFUNC_READ || fu==kFUNC_RNHC) {
ovr = sa + nblk > unit.NSector();
if (ovr) nwrd = (unit.NSector()-sa) * (unit.BlockSize()/2);
}
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
static const char* fumnemo[8] = {"no","wc","gs","se","rh","w ","r ","rn"};
lmsg << "-I RL11 cs=" << RosPrintBvi(rlcs,8)
<< " da=" << RosPrintBvi(rlda,8)
<< " ad=" << RosPrintBvi(addr,8,18)
<< " fu=" << fumnemo[fu&0x7]
<< " pa=" << ds
<< "," << RosPrintf(ca,"d",3)
<< "," << hs
<< "," << RosPrintf(sa,"d",2)
<< " la,nw=" << RosPrintf(lba,"d",5)
<< ",";
if (nwrd==65536) lmsg << " (0)"; else lmsg << RosPrintf(nwrd,"d",4);
if (ovr) lmsg << "!";
}
 
// check for spurious interrupts (either RDY=1 or RDY=0 and rdma busy)
if ((rlcs & kRLCS_M_CRDY) || fRdma.IsActive()) {
RlogMsg lmsg(LogFile());
lmsg << "-E RL11 err "
<< " cr=" << RosPrintBvi(rlcs,8)
<< " spurious lam: "
<< (fRdma.IsActive() ? "RDY=0 and Rdma busy" : "RDY=1");
return 0;
}
 
// remember request parameters for call back and error exit handling
fRd_rlcs = rlcs;
fRd_rlda = rlda;
fRd_rlmp = wc;
fRd_sta = sta;
fRd_pos = pos;
fRd_addr = addr;
fRd_lba = lba;
fRd_nwrd = nwrd;
fRd_ovr = ovr;
fRd_fu = fu;
 
// check for general abort conditions
// note: only 'data transfer' functions handled via backend
// SEEK and GSTA are done in ibdr_rl11 autonomously
 
// not attached --> assumed Offline, status = load
if (! unit.Virt()) { // not attached
AddErrorExit(clist, kERR_OPI); // just signal OPI
// drive stat is LOAD anyway
Server().Exec(clist); // doit
return 0;
}
 
// handle Read Header
// no data transfer, done here to keep crc calc out of firmware
if (fu == kFUNC_RHDR) {
fStats.Inc(kStatNFuncRhdr);
uint16_t buf[2] = {pos, 0};
uint16_t crc = CalcCrc(2, buf);
 
cpu.AddWibr(clist, fBase+kRLCS,
(kMPREM_CRC << kRLCS_V_MPREM) |
(kMPLOC_POS << kRLCS_V_MPLOC) |
kRLCS_ENA_MPREM |
kRLCS_ENA_MPLOC |
(kRFUNC_WMP << kRLCS_V_FUNC));
cpu.AddWibr(clist, fBase+kRLMP, crc);
 
// simulate rotation, inc sector number, wrap at end of track
uint16_t sa = (pos & kRLDA_RW_B_SA) + 1;
if (sa >= unit.NSector()) sa = 0; // wrap to begin of track
uint16_t posn = (pos & (kRLDA_RW_M_CA|kRLDA_RW_M_HS)) + sa;
AddSetPosition(clist, ds, posn);
 
uint16_t cs = kRLCS_M_CRDY | // signal command done
(rlcs & kRLCS_M_BAE) | // keep BAE
(kRFUNC_WCS << kRLCS_V_FUNC);
 
cpu.AddWibr(clist, fBase+kRLCS, cs);
 
if (fTraceLevel>1) {
RlogMsg lmsg(LogFile());
lmsg << "-I RL11 ok "
<< " cs=" << RosPrintBvi(cs,8)
<< " mp=" << RosPrintBvi(crc,8)
<< " pos=" << RosPrintBvi(pos,8)
<< "->" << RosPrintBvi(posn,8);
}
Server().Exec(clist); // doit
return 0;
}
 
// now only data transfer functions to handle
 
// check track number and proper head positioning
bool poserr = sa >= unit.NSector(); // track number valid ?
if (fu != kFUNC_RNHC) { // unless RNHC: check proper head pos
uint16_t pos_ch = pos & (kRLDA_RW_M_CA|kRLDA_RW_M_HS); // pos: cyl+hd
uint16_t rlda_ch = rlda & (kRLDA_RW_M_CA|kRLDA_RW_M_HS); // da: cyl+hd
poserr |= pos_ch != rlda_ch;
}
if (true && poserr) {
AddErrorExit(clist, kERR_HNFND);
Server().Exec(clist); // doit
return 0;
}
 
// now handle the functions
if (fu == kFUNC_WRITE) { // Write -------------------------
fStats.Inc(kStatNFuncWrite);
if (unit.WProt()) { // write on write locked drive ?
AddSetStatus(clist, ds, sta | kSTA_M_WGE);
AddErrorExit(clist, kERR_M_DE);
} else {
fRdma.QueueDiskWrite(addr, nwrd,
Rw11Cpu::kCPAH_M_22BIT|Rw11Cpu::kCPAH_M_UBMAP,
lba, &unit);
}
 
} else if (fu == kFUNC_WCHK) { // Write Check -------------------
fStats.Inc(kStatNFuncWchk );
fRdma.QueueDiskWriteCheck(addr, nwrd,
Rw11Cpu::kCPAH_M_22BIT|Rw11Cpu::kCPAH_M_UBMAP,
lba, &unit);
} else if (fu == kFUNC_READ || // Read or
fu == kFUNC_RNHC) { // Read No Header Check ----------
fStats.Inc(fu==kFUNC_READ ? kStatNFuncRead : kStatNFuncRnhc);
 
fRdma.QueueDiskRead(addr, nwrd,
Rw11Cpu::kCPAH_M_22BIT|Rw11Cpu::kCPAH_M_UBMAP,
lba, &unit);
}
 
if (clist.Size()) { // if handled directly
Server().Exec(clist); // doit
}
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
RlinkCommandList& clist)
{
// if last chunk and not doing WCHK add a labo and normal exit csr update
if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kFUNC_WCHK) {
clist.AddLabo();
AddNormalExit(clist, nwdone+nwnext, 0);
}
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::RdmaPostExecCB(int stat, size_t ndone,
RlinkCommandList& clist, size_t ncmd)
{
if (stat == Rw11Rdma::kStatusBusy) return;
 
uint16_t rlerr = 0;
 
// handle write check
if (fRd_fu == kFUNC_WCHK) {
size_t nwcok = fRdma.WriteCheck(ndone);
if (nwcok != ndone) { // if mismatch found
rlerr = kERR_WCHK; // set error
ndone = nwcok; // truncate word count
}
}
 
// handle Rdma aborts
if (stat == Rw11Rdma::kStatusFailRdma && rlerr == 0) rlerr = kERR_NXM;
 
// check for fused csr updates
if (clist.Size() > ncmd) {
uint8_t ccode = clist[ncmd].Command();
uint16_t cdata = clist[ncmd].Data();
if (ccode != RlinkCommand::kCmdLabo || (rlerr != 0 && cdata == 0))
throw Rexception("Rw11CntlRL11::RdmaPostExecCB",
"Bad state: Labo not found or missed abort");
if (cdata == 0) return;
}
 
// finally to RL11 register update
RlinkCommandList clist1;
AddNormalExit(clist1, ndone, rlerr);
Server().Exec(clist1);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs ????
 
void Rw11CntlRL11::LogRler(uint16_t rlerr)
{
RlogMsg lmsg(LogFile());
lmsg << "-E RL11 err=" << RosPrintBvi(rlerr,2,5) << " ERROR ABORT";
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::AddSetPosition(RlinkCommandList& clist, size_t ind,
uint16_t pos)
{
Rw11Cpu& cpu = Cpu();
cpu.AddWibr(clist, fBase+kRLCS,
((kMPREM_POS+ind)<<kRLCS_V_MPREM) | // address pos(unit)
kRLCS_ENA_MPREM | // update MPREM
(kRFUNC_WMP << kRLCS_V_FUNC) ); // write MP
cpu.AddWibr(clist, fBase+kRLMP, pos);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::AddSetStatus(RlinkCommandList& clist, size_t ind,
uint16_t sta)
{
Rw11Cpu& cpu = Cpu();
cpu.AddWibr(clist, fBase+kRLCS,
((kMPREM_STA+ind)<<kRLCS_V_MPREM) | // address sta(unit)
kRLCS_ENA_MPREM | // update MPREM
(kRFUNC_WMP << kRLCS_V_FUNC) ); // write MP
cpu.AddWibr(clist, fBase+kRLMP, sta);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::AddErrorExit(RlinkCommandList& clist, uint16_t rlerr)
{
Rw11Cpu& cpu = Cpu();
uint16_t cs = kRLCS_M_ERR | // set ERR flag
(rlerr << kRLCS_V_E) | // set DE and E fields
kRLCS_M_CRDY | // signal command done
(fRd_rlcs & kRLCS_M_BAE) | // keep BAE
(kRFUNC_WCS << kRLCS_V_FUNC); // write CS
cpu.AddWibr(clist, fBase+kRLCS, cs);
 
if (fTraceLevel>1) {
RlogMsg lmsg(LogFile());
lmsg << "-I RL11 err"
<< " cs=" << RosPrintBvi(cs,8)
<< " err=" << RosPrintBvi(rlerr,2,5)
<< " pos=" << RosPrintBvi(fRd_pos,8);
}
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlRL11::AddNormalExit(RlinkCommandList& clist, size_t ndone,
uint16_t rlerr)
{
Rw11Cpu& cpu = Cpu();
uint16_t ds = (fRd_rlcs>>kRLCS_V_DS) & kRLCS_B_DS;
Rw11UnitRL11& unit = *fspUnit[ds];
 
size_t nblk = unit.Nwrd2Nblk(ndone);
 
uint32_t addr = fRd_addr + 2*ndone;
 
uint16_t ba = addr & 0177776; // get lower 16 bits
uint16_t bae = (addr>>16) & 03; // get upper 2 bits
 
uint16_t da = fRd_rlda+uint16_t(nblk);
 
uint16_t rlmp = fRd_rlmp + uint16_t(ndone);
 
if (fRd_ovr && rlerr == 0) rlerr = kERR_HNFND;
 
cpu.AddWibr(clist, fBase+kRLBA, ba);
cpu.AddWibr(clist, fBase+kRLDA, da);
cpu.AddWibr(clist, fBase+kRLCS,
(kMPREM_MP << kRLCS_V_MPREM) |
(kMPLOC_MP << kRLCS_V_MPLOC) |
kRLCS_ENA_MPREM |
kRLCS_ENA_MPLOC |
(kRFUNC_WMP << kRLCS_V_FUNC));
cpu.AddWibr(clist, fBase+kRLMP, rlmp);
 
// set drive position to one sector past the last the read sector
// Note: take sa from rlda, and ca+hs from fRd_pos (controller context!)
// in case of errors this probably the best solution
uint16_t sa = (fRd_rlda & kRLDA_RW_B_SA) + uint16_t(nblk);
if (sa >= unit.NSector()) sa = 0; // wrap to begin of track
uint16_t posn = (fRd_pos & (kRLDA_RW_M_CA|kRLDA_RW_M_HS)) + sa;
AddSetPosition(clist, ds, posn);
 
uint16_t cs = kRLCS_M_CRDY |
(bae << kRLCS_V_BAE) |
(kRFUNC_WCS << kRLCS_V_FUNC);
if (rlerr) cs |= (rlerr << kRLCS_V_E);
cpu.AddWibr(clist, fBase+kRLCS, cs);
 
if (fTraceLevel>1) {
RlogMsg lmsg(LogFile());
lmsg << "-I RL11 " << (rlerr==0 ? " ok" : "err")
<< " cs=" << RosPrintBvi(cs,8)
<< " ba=" << RosPrintBvi(ba,8)
<< " da=" << RosPrintBvi(da,8)
<< " mp=" << RosPrintBvi(rlmp,8);
if (rlerr) lmsg << " err=" << RosPrintBvi(rlerr,2,5);
lmsg << " pos=" << RosPrintBvi(fRd_pos,8)
<< "->" << RosPrintBvi(posn,8);
}
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
// Note:
// CalcCrc() is adopted from the simh project and Copyright Robert M Supnik
 
uint16_t Rw11CntlRL11::CalcCrc(size_t size, const uint16_t* data)
{
uint32_t crc=0;
 
for (size_t i = 0; i < size; i++) {
uint32_t d = *data++;
/* cribbed from KG11-A */
for (size_t j = 0; j < 16; j++) {
crc = (crc & ~01) | ((crc & 01) ^ (d & 01));
crc = (crc & 01) ? (crc >> 1) ^ 0120001 : crc >> 1;
d >>= 1;
}
}
return crc;
}
 
} // end namespace Retro
/Rw11CntlRK11.hpp
0,0 → 1,185
// $Id: Rw11CntlRK11.hpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-01-03 627 2.0 use Rw11RdmaDisk
// 2014-12-29 623 1.1 adopt to Rlink V4 attn logic
// 2014-06-14 562 1.0.1 Add stats definitions
// 2013-04-20 508 1.0 Initial version
// 2013-02-10 485 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CntlRK11.hpp 686 2015-06-04 21:08:08Z mueller $
\brief Declaration of class Rw11CntlRK11.
*/
 
#ifndef included_Retro_Rw11CntlRK11
#define included_Retro_Rw11CntlRK11 1
 
#include "Rw11CntlBase.hpp"
#include "Rw11UnitRK11.hpp"
#include "Rw11RdmaDisk.hpp"
 
namespace Retro {
 
class Rw11CntlRK11 : public Rw11CntlBase<Rw11UnitRK11,8> {
public:
 
Rw11CntlRK11();
~Rw11CntlRK11();
 
void Config(const std::string& name, uint16_t base, int lam);
 
virtual void Start();
 
virtual bool BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart);
 
virtual void UnitSetup(size_t ind);
 
void SetChunkSize(size_t chunk);
size_t ChunkSize() const;
 
const Rstats& RdmaStats() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kIbaddr = 0177400; //!< RK11 default address
static const int kLam = 4; //!< RK11 default lam
 
static const uint16_t kRKDS = 000; //!< RKDS reg offset
static const uint16_t kRKER = 002; //!< RKER reg offset
static const uint16_t kRKCS = 004; //!< RKCS reg offset
static const uint16_t kRKWC = 006; //!< RKWC reg offset
static const uint16_t kRKBA = 010; //!< RKBA reg offset
static const uint16_t kRKDA = 012; //!< RKDA reg offset
static const uint16_t kRKMR = 014; //!< RKMR reg offset
 
static const uint16_t kProbeOff = kRKCS; //!< probe address offset (rkcs)
static const bool kProbeInt = true; //!< probe int active
static const bool kProbeRem = true; //!< probr rem active
 
static const uint16_t kRKDS_M_ID = 0160000; //!< ID: drive number
static const uint16_t kRKDS_V_ID = 13;
static const uint16_t kRKDS_B_ID = 0007;
static const uint16_t kRKDS_M_HDEN = kWBit11; //!< HDEN: high density drv
static const uint16_t kRKDS_M_DRU = kWBit10; //!< DRU: drive unsafe
static const uint16_t kRKDS_M_SIN = kWBit09; //!< SIN: seek incomplete
static const uint16_t kRKDS_M_SOK = kWBit08; //!< SOK: sector counter OK
static const uint16_t kRKDS_M_DRY = kWBit07; //!< DRY: drive ready
static const uint16_t kRKDS_M_ADRY = kWBit06; //!< ADRY: access ready
static const uint16_t kRKDS_M_WPS = kWBit05; //!< WPS: write protect
static const uint16_t kRKDS_B_SC = 0017; //!< SC: sector counter
 
static const uint16_t kRKER_M_DRE = kWBit15;
static const uint16_t kRKER_M_OVR = kWBit14;
static const uint16_t kRKER_M_WLO = kWBit13;
static const uint16_t kRKER_M_PGE = kWBit11;
static const uint16_t kRKER_M_NXM = kWBit10;
static const uint16_t kRKER_M_NXD = kWBit07;
static const uint16_t kRKER_M_NXC = kWBit06;
static const uint16_t kRKER_M_NXS = kWBit05;
static const uint16_t kRKER_M_CSE = kWBit01;
static const uint16_t kRKER_M_WCE = kWBit00;
 
static const uint16_t kRKCS_M_MAINT= kWBit12;
static const uint16_t kRKCS_M_IBA = kWBit11;
static const uint16_t kRKCS_M_FMT = kWBit10;
static const uint16_t kRKCS_M_RWA = kWBit09;
static const uint16_t kRKCS_M_SSE = kWBit08;
static const uint16_t kRKCS_M_RDY = kWBit07;
static const uint16_t kRKCS_M_MEX = 000060;
static const uint16_t kRKCS_V_MEX = 4;
static const uint16_t kRKCS_B_MEX = 0003;
static const uint16_t kRKCS_V_FUNC = 1;
static const uint16_t kRKCS_B_FUNC = 0007;
static const uint16_t kRKCS_M_GO = kWBit00;
 
static const uint16_t kFUNC_CRESET = 0;
static const uint16_t kFUNC_WRITE = 1;
static const uint16_t kFUNC_READ = 2;
static const uint16_t kFUNC_WCHK = 3;
static const uint16_t kFUNC_SEEK = 4;
static const uint16_t kFUNC_RCHK = 5;
static const uint16_t kFUNC_DRESET = 6;
static const uint16_t kFUNC_WLOCK = 7;
 
static const uint16_t kRKDA_M_DRSEL= 0160000;
static const uint16_t kRKDA_V_DRSEL= 13;
static const uint16_t kRKDA_B_DRSEL= 0007;
static const uint16_t kRKDA_M_CYL = 0017740;
static const uint16_t kRKDA_V_CYL = 5;
static const uint16_t kRKDA_B_CYL = 0377;
static const uint16_t kRKDA_M_SUR = 0000020;
static const uint16_t kRKDA_V_SUR = 4;
static const uint16_t kRKDA_B_SUR = 0001;
static const uint16_t kRKDA_B_SC = 0017;
 
static const uint16_t kRKMR_M_RID = 0160000;
static const uint16_t kRKMR_V_RID = 13;
static const uint16_t kRKMR_M_CRDONE= kWBit11;
static const uint16_t kRKMR_M_SBCLR = kWBit10;
static const uint16_t kRKMR_M_CRESET= kWBit09;
static const uint16_t kRKMR_M_FDONE = kWBit08;
 
// statistics counter indices
enum stats {
kStatNFuncCreset = Rw11Cntl::kDimStat, //!< func CRESET
kStatNFuncWrite, //!< func WRITE
kStatNFuncRead, //!< func READ
kStatNFuncWchk, //!< func WCHK
kStatNFuncSeek, //!< func SEEK
kStatNFuncRchk, //!< func RCHK
kStatNFuncDreset, //!< func DRESET
kStatNFuncWlock, //!< func WLOCK
kDimStat
};
 
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
void RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
RlinkCommandList& clist);
void RdmaPostExecCB(int stat, size_t ndone,
RlinkCommandList& clist, size_t ncmd);
void LogRker(uint16_t rker);
void AddErrorExit(RlinkCommandList& clist, uint16_t rker);
void AddNormalExit(RlinkCommandList& clist, size_t ndone,
uint16_t rker=0);
 
protected:
size_t fPC_rkwc; //!< PrimClist: rkwc index
size_t fPC_rkba; //!< PrimClist: rkba index
size_t fPC_rkda; //!< PrimClist: rkda index
size_t fPC_rkmr; //!< PrimClist: rkmr index
size_t fPC_rkcs; //!< PrimClist: rkcs index
 
uint16_t fRd_rkcs; //!< Rdma: request rkcs
uint16_t fRd_rkda; //!< Rdma: request rkda
uint32_t fRd_addr; //!< Rdma: current addr
uint32_t fRd_lba; //!< Rdma: current lba
uint32_t fRd_nwrd; //!< Rdma: current nwrd
uint16_t fRd_fu; //!< Rdma: request fu code
bool fRd_ovr; //!< Rdma: overrun condition found
Rw11RdmaDisk fRdma; //!< Rdma controller
};
} // end namespace Retro
 
#include "Rw11CntlRK11.ipp"
 
#endif
/Rw11CntlTM11.ipp
0,0 → 1,55
// $Id: Rw11CntlTM11.ipp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-17 683 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlTM11.ipp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation (inline) of Rw11CntlTM11.
*/
 
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11CntlTM11::SetChunkSize(size_t chunk)
{
fRdma.SetChunkSize(chunk);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11CntlTM11::ChunkSize() const
{
return fRdma.ChunkSize();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11CntlTM11::RdmaStats() const
{
return fRdma.Stats();
}
 
 
} // end namespace Retro
/Rw11UnitTape.hpp
0,0 → 1,85
// $Id: Rw11UnitTape.hpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitTape.hpp 686 2015-06-04 21:08:08Z mueller $
\brief Declaration of class Rw11UnitTape.
*/
 
#ifndef included_Retro_Rw11UnitTape
#define included_Retro_Rw11UnitTape 1
 
#include "Rw11VirtTape.hpp"
 
#include "Rw11UnitVirt.hpp"
 
namespace Retro {
 
class Rw11UnitTape : public Rw11UnitVirt<Rw11VirtTape> {
public:
Rw11UnitTape(Rw11Cntl* pcntl, size_t index);
~Rw11UnitTape();
 
virtual void SetType(const std::string& type);
 
const std::string& Type() const;
virtual bool Enabled() const;
 
void SetWProt(bool wprot);
void SetCapacity(size_t nbyte);
bool WProt() const;
size_t Capacity() const;
 
void SetPosFile(int posfile);
void SetPosRecord(int posrec);
 
bool Bot() const;
bool Eot() const;
bool Eom() const;
 
int PosFile() const;
int PosRecord() const;
 
bool VirtReadRecord(size_t nbyte, uint8_t* data, size_t& ndone,
int& opcode, RerrMsg& emsg);
bool VirtWriteRecord(size_t nbyte, const uint8_t* data,
int& opcode, RerrMsg& emsg);
bool VirtWriteEof(RerrMsg& emsg);
bool VirtSpaceForw(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg);
bool VirtSpaceBack(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg);
bool VirtRewind(int& opcode, RerrMsg& emsg);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
std::string fType; //!< drive type
bool fEnabled; //!< unit enabled
bool fWProt; //!< unit write protected
size_t fCapacity; //<! capacity in byte (0=unlimited)
};
} // end namespace Retro
 
#include "Rw11UnitTape.ipp"
 
#endif
/Rw11VirtTape.cpp
0,0 → 1,172
// $Id: Rw11VirtTape.cpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTape.cpp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation of Rw11VirtTape.
*/
#include <memory>
 
#include "librtools/RosFill.hpp"
#include "librtools/RparseUrl.hpp"
#include "librtools/Rexception.hpp"
#include "Rw11VirtTapeTap.hpp"
 
#include "Rw11VirtTape.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11VirtTape
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11VirtTape::Rw11VirtTape(Rw11Unit* punit)
: Rw11Virt(punit),
fWProt(false),
fCapacity(0),
fBot(false),
fEot(false),
fEom(true),
fPosFile(-1),
fPosRecord(-1)
{
fStats.Define(kStatNVTReadRec, "NVTReadRec", "ReadRecord() calls");
fStats.Define(kStatNVTReadByt, "NVTReadByt", "bytes read");
fStats.Define(kStatNVTReadEof, "NVTReadEof", "eof read");
fStats.Define(kStatNVTReadEom, "NVTReadEom", "eom read");
fStats.Define(kStatNVTReadPErr, "NVTReadPErr", "parity error read");
fStats.Define(kStatNVTReadLErr, "NVTReadLErr", "length error read");
fStats.Define(kStatNVTWriteRec, "NVTWriteRec", "WriteRecord() calls");
fStats.Define(kStatNVTWriteByt, "NVTWriteByt", "bytes written");
fStats.Define(kStatNVTWriteEof, "NVTWriteEof", "WriteEof() calls");
fStats.Define(kStatNVTSpaForw, "NVTSpaForw", "SpaceForw() calls");
fStats.Define(kStatNVTSpaBack, "NVTSpaBack", "SpaceBack() calls");
fStats.Define(kStatNVTRewind, "NVTRewind", "Rewind() calls");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11VirtTape::~Rw11VirtTape()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
Rw11VirtTape* Rw11VirtTape::New(const std::string& url, Rw11Unit* punit,
RerrMsg& emsg)
{
string scheme = RparseUrl::FindScheme(url, "tap");
unique_ptr<Rw11VirtTape> p;
if (scheme == "tap") { // scheme -> tap:
p.reset(new Rw11VirtTapeTap(punit));
if (p->Open(url, emsg)) return p.release();
 
} else { // scheme -> no match
emsg.Init("Rw11VirtTape::New", string("Scheme '") + scheme +
"' is not supported");
}
 
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtTape::SetPosFile(int posfile)
{
if (posfile < 0) posfile = 0;
 
RerrMsg emsg;
int opcode;
size_t ndone;
bool rc = Rewind(opcode, emsg);
 
while (rc && posfile != fPosFile) {
rc = SpaceForw(1000000000, ndone, opcode, emsg);
if (rc && opcode == kOpCodeEom) return;
}
 
if (!rc) throw Rexception("Rw11VirtTape::SetPosFile", emsg.Text());
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtTape::SetPosRecord(int posrec)
{
if (posrec < 0) posrec = 0;
 
RerrMsg emsg;
int opcode;
size_t ndone;
 
// space back to begin of current file (works even when fPosRecord is -1!)
bool rc = SpaceBack(1000000000, ndone, opcode, emsg);
// if eof was spaced over backwards, space forward over eof
if (rc && opcode == kOpCodeEof) rc = SpaceForw(1, ndone, opcode, emsg);
// now space forward to find record
if (rc && posrec != 0) {
rc = SpaceForw(posrec, ndone, opcode, emsg);
// if eof was spaced over, space backward over eof to stay in file
// the number of records spaced is used to setup fPosRecord
if (rc && opcode == kOpCodeEof) {
size_t ndoneeof;
rc = SpaceBack(1, ndoneeof, opcode, emsg);
if (rc) fPosRecord = ndone;
}
}
 
if (!rc) throw Rexception("Rw11VirtTape::SetPosFile", emsg.Text());
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtTape::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11VirtTape @ " << this << endl;
 
os << bl << " fWProt: " << fWProt << endl;
os << bl << " fCapacity: " << fCapacity << endl;
os << bl << " fBot: " << fBot << endl;
os << bl << " fEot: " << fEot << endl;
os << bl << " fEom: " << fEom << endl;
os << bl << " fPosFile: " << fPosFile << endl;
os << bl << " fPosRecord: " << fPosRecord << endl;
Rw11Virt::Dump(os, ind, " ^");
return;
}
 
 
} // end namespace Retro
/Rw11Cntl.cpp
0,0 → 1,165
// $Id: Rw11Cntl.cpp 682 2015-05-15 18:35:29Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-30 625 1.1 adopt to Rlink V4 attn logic
// 2013-03-06 495 1.0 Initial version
// 2013-02-05 483 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Cntl.cpp 682 2015-05-15 18:35:29Z mueller $
\brief Implemenation of Rw11Cntl.
*/
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
 
#include "Rw11Cntl.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11Cntl
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11Cntl::Rw11Cntl(const std::string& type)
: fpCpu(nullptr),
fType(type),
fName(),
fBase(0),
fLam(-1),
fEnable(true),
fStarted(false),
fProbe(),
fTraceLevel(0),
fPrimClist(),
fStats()
{
fStats.Define(kStatNAttnHdl, "NAttnHdl", "AttnHandler() calls");
fStats.Define(kStatNAttnNoAct,"NAttnNoAct","AttnHandler() no action return");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11Cntl::~Rw11Cntl()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cntl::SetEnable(bool ena)
{
if (fStarted)
throw Rexception("Rw11Cntl::SetEnable", "only allowed before Start()");
fEnable = ena;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Cntl::Probe()
{
return Cpu().ProbeCntl(fProbe);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cntl::Start()
{
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
size_t Rw11Cntl::NUnit() const
{
return 0; // real values from devived classes
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Cntl::BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart)
{
code.clear();
aload = 0;
astart = 0;
return false;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
std::string Rw11Cntl::UnitName(size_t index) const
{
string name = fName;
if (index > 9) name += char('0' + index/10);
name += char('0' + index%10);
return name;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cntl::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11Cntl @ " << this << endl;
 
os << bl << " fpCpu: " << fpCpu << endl;
os << bl << " fType: " << fType << endl;
os << bl << " fName: " << fName << endl;
os << bl << " fBase: " << RosPrintf(fBase,"o0",6) << endl;
os << bl << " fLam: " << fLam << endl;
os << bl << " fEnable: " << fEnable << endl;
os << bl << " fStarted: " << fStarted << endl;
fProbe.Dump(os, ind+2, "fProbe: ");
os << bl << " fTraceLevel: " << fTraceLevel << endl;
fPrimClist.Dump(os, ind+2, "fPrimClist: ");
fStats.Dump(os, ind+2, "fStats: ");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Cntl::ConfigCntl(const std::string& name, uint16_t base, int lam,
uint16_t probeoff, bool probeint, bool proberem)
{
fName = name;
fBase = base;
fLam = lam;
fProbe.fAddr = base + probeoff;
fProbe.fProbeInt = probeint;
fProbe.fProbeRem = proberem;
return;
}
 
} // end namespace Retro
/Rw11VirtTapeTap.cpp
0,0 → 1,589
// $Id: Rw11VirtTapeTap.cpp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTapeTap.cpp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation of Rw11VirtTapeTap.
*/
 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
 
#include "librtools/RosFill.hpp"
#include "librtools/Rtools.hpp"
 
#include "Rw11VirtTapeTap.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11VirtTapeTap
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint32_t Rw11VirtTapeTap::kMetaEof;
const uint32_t Rw11VirtTapeTap::kMetaEom;
const uint32_t Rw11VirtTapeTap::kMeta_M_Perr;
const uint32_t Rw11VirtTapeTap::kMeta_M_Mbz;
const uint32_t Rw11VirtTapeTap::kMeta_B_Rlen;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11VirtTapeTap::Rw11VirtTapeTap(Rw11Unit* punit)
: Rw11VirtTape(punit),
fFd(0),
fSize(0),
fPos(0),
fBad(true),
fPadOdd(false),
fTruncPend(false)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11VirtTapeTap::~Rw11VirtTapeTap()
{
if (fFd > 2) ::close(fFd);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::Open(const std::string& url, RerrMsg& emsg)
{
if (!fUrl.Set(url, "|wpro|e11|cap=|", emsg)) return false;
 
fWProt = fUrl.FindOpt("wpro");
fPadOdd = fUrl.FindOpt("e11");
 
string str_cap;
unsigned long capacity=0;
if (fUrl.FindOpt("cap",str_cap)) {
if (str_cap.length() > 0) {
unsigned long scale = 1;
string str_conv = str_cap;
char clast = str_cap[str_cap.length()-1];
bool ok = true;
 
if (! (clast >= '0' && clast <= '9') ) {
str_conv = str_cap.substr(0,str_cap.length()-1);
switch(str_cap[str_cap.length()-1]) {
case 'k':
case 'K':
scale = 1024;
break;
case 'm':
case 'M':
scale = 1024*1024;
break;
default:
ok = false;
break;
}
}
if (ok) {
RerrMsg emsg_conv;
ok = Rtools::String2Long(str_conv, capacity, emsg_conv);
}
if (!ok) {
emsg.Init("Rw11VirtTapeTap::Open()",
string("bad capacity option '")+str_cap+"'");
return false;
}
capacity *= scale;
}
}
 
int fd = ::open(fUrl.Path().c_str(), fWProt ? O_RDONLY : O_CREAT|O_RDWR,
S_IRUSR|S_IWUSR|S_IRGRP);
if (fd < 0) {
emsg.InitErrno("Rw11VirtTapeTap::Open()",
string("open() for '") + fUrl.Path() + "' failed: ", errno);
return false;
}
 
struct stat sbuf;
if (::fstat(fd, &sbuf) < 0) {
emsg.InitErrno("Rw11VirtTapeTap::Open()",
string("stat() for '") + fUrl.Path() + "' failed: ", errno);
return false;
}
 
if ((sbuf.st_mode & S_IWUSR) == 0) fWProt = true;
 
fFd = fd;
fSize = sbuf.st_size;
fPos = 0;
fBad = false;
fTruncPend = true;
 
fCapacity = capacity;
fBot = true;
fEot = false;
fEom = false;
fPosFile = 0;
fPosRecord = 0;
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::ReadRecord(size_t nbyt, uint8_t* data, size_t& ndone,
int& opcode, RerrMsg& emsg)
{
fStats.Inc(kStatNVTReadRec);
opcode = kOpCodeBadFormat;
ndone = 0;
if (fBad) return BadTapeMsg("ReadRecord()", emsg);
if (fPos == fSize) {
fEom = true;
opcode = kOpCodeEom;
return true;
}
 
uint32_t metabeg;
uint32_t metaend;
 
if (!CheckSizeForw(sizeof(metabeg), "missed metabeg", emsg)) return SetBad();
if (!Read(sizeof(metabeg), reinterpret_cast<uint8_t*>(&metabeg),
emsg)) return SetBad();
 
if (metabeg == kMetaEof) {
fStats.Inc(kStatNVTReadEof);
opcode = kOpCodeEof;
fPosFile += 1;
fPosRecord = 0;
return true;
}
 
if (metabeg == kMetaEom) {
if (!Seek(sizeof(metabeg), -1, emsg)) return SetBad();
fStats.Inc(kStatNVTReadEom);
fEom = true;
opcode = kOpCodeEom;
return true;
}
 
size_t rlen;
bool perr;
if (!ParseMeta(metabeg, rlen, perr, emsg)) return SetBad();
size_t rlenpad = BytePadding(rlen);
 
if (!CheckSizeForw(rlenpad, "missed data", emsg)) return SetBad();
 
ndone = (rlen <= nbyt) ? rlen : nbyt;
if (!Read(ndone, data, emsg)) return SetBad();
if (ndone < rlenpad) {
if (!Seek(rlenpad, +1, emsg)) return SetBad();
}
 
if (!CheckSizeForw(sizeof(metaend), "missed metaend", emsg)) return SetBad();
if (!Read(sizeof(metaend), reinterpret_cast<uint8_t*>(&metaend),
emsg)) return SetBad();
 
if (metabeg != metaend) {
emsg.Init("Rw11VirtTapeTap::ReadRecord", "metabeg metaend mismatch");
ndone = 0;
return SetBad();
}
 
IncPosRecord(+1);
opcode = kOpCodeOK;
if (perr) {
fStats.Inc(kStatNVTReadPErr);
opcode = kOpCodeBadParity;
}
if (ndone < rlen) {
fStats.Inc(kStatNVTReadLErr);
opcode = kOpCodeRecLenErr;
}
fStats.Inc(kStatNVTReadByt, ndone);
 
return true;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::WriteRecord(size_t nbyt, const uint8_t* data,
int& opcode, RerrMsg& emsg)
{
fStats.Inc(kStatNVTWriteRec);
fStats.Inc(kStatNVTWriteByt, nbyt);
 
opcode = kOpCodeBadFormat;
if (fBad) return BadTapeMsg("WriteRecord()", emsg);
 
fEom = false;
 
uint32_t meta = nbyt;
uint8_t zero = 0x00;
 
if (!Write(sizeof(meta), reinterpret_cast<uint8_t*>(&meta),
false, emsg)) return SetBad();
 
if (!Write(nbyt, data,
false, emsg)) return SetBad();
if (fPadOdd && (nbyt&0x01)) {
if (!Write(sizeof(zero), &zero, false, emsg)) return SetBad();
}
if (!Write(sizeof(meta), reinterpret_cast<uint8_t*>(&meta),
false, emsg)) return SetBad();
if (!Write(sizeof(kMetaEom), reinterpret_cast<const uint8_t*>(&kMetaEom),
true, emsg)) return SetBad();
 
IncPosRecord(+1);
opcode = kOpCodeOK;
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::WriteEof(RerrMsg& emsg)
{
fStats.Inc(kStatNVTWriteEof);
 
if (fBad) return BadTapeMsg("WriteEof()", emsg);
 
fEom = false;
 
if (!Write(sizeof(kMetaEof), reinterpret_cast<const uint8_t*>(&kMetaEof),
false, emsg)) return SetBad();
if (!Write(sizeof(kMetaEom), reinterpret_cast<const uint8_t*>(&kMetaEom),
true, emsg)) return SetBad();
 
fPosFile += 1;
fPosRecord = 0;
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::SpaceForw(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg)
{
fStats.Inc(kStatNVTSpaForw);
 
opcode = kOpCodeBadFormat;
ndone = 0;
if (fBad) return BadTapeMsg("SpaceForw()", emsg);
 
while (nrec > 0) {
 
if (fPos == fSize) {
fEom = true;
opcode = kOpCodeEom;
return true;
}
 
uint32_t metabeg;
 
if (!CheckSizeForw(sizeof(metabeg), "missed metabeg", emsg)) return SetBad();
if (!Read(sizeof(metabeg), reinterpret_cast<uint8_t*>(&metabeg),
emsg)) return SetBad();
if (metabeg == kMetaEof) {
opcode = kOpCodeEof;
fPosFile += 1;
fPosRecord = 0;
return true;
}
 
if (metabeg == kMetaEom) {
if (!Seek(sizeof(metabeg), -1, emsg)) return SetBad();
fEom = true;
opcode = kOpCodeEom;
return true;
}
 
size_t rlen;
bool perr;
if (!ParseMeta(metabeg, rlen, perr, emsg)) return SetBad();
size_t rlenpad = BytePadding(rlen);
 
if (!CheckSizeForw(sizeof(metabeg)+rlenpad, "missed data or metaend", emsg))
return SetBad();
if (!Seek(sizeof(metabeg)+rlenpad, +1, emsg)) return SetBad();
 
IncPosRecord(+1);
nrec -= 1;
ndone += 1;
}
 
opcode = kOpCodeOK;
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::SpaceBack(size_t nrec, size_t& ndone,
int& opcode, RerrMsg& emsg)
{
fStats.Inc(kStatNVTSpaBack);
 
opcode = kOpCodeBadFormat;
ndone = 0;
if (fBad) return BadTapeMsg("SpaceBack()", emsg);
 
fEom = false;
fTruncPend = true;
 
while (nrec > 0) {
 
if (fPos == 0) {
opcode = kOpCodeBot;
fPosFile = 0;
fPosRecord = 0;
return true;
}
 
uint32_t metaend;
 
if (!CheckSizeBack(sizeof(metaend), "missed metaend", emsg)) return SetBad();
if (!Seek(sizeof(metaend), -1, emsg)) return SetBad();
if (!Read(sizeof(metaend), reinterpret_cast<uint8_t*>(&metaend),
emsg)) return SetBad();
if (metaend == kMetaEof) {
if (!Seek(sizeof(metaend), -1, emsg)) return SetBad();
opcode = kOpCodeEof;
fPosFile -= 1;
fPosRecord = -1;
return true;
}
 
if (metaend == kMetaEom) {
emsg.Init("Rw11VirtTapeTap::SpaceBack()","unexpected EOM marker");
return SetBad();
}
 
size_t rlen;
bool perr;
if (!ParseMeta(metaend, rlen, perr, emsg)) return SetBad();
size_t rlenpad = BytePadding(rlen);
if (!CheckSizeBack(2*sizeof(metaend)+rlenpad,
"missed data or metabeg", emsg)) return SetBad();
if (!Seek(2*sizeof(metaend)+rlenpad, -1, emsg)) return SetBad();
 
IncPosRecord(-1);
nrec -= 1;
ndone += 1;
}
 
opcode = kOpCodeOK;
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::Rewind(int& opcode, RerrMsg& emsg)
{
fStats.Inc(kStatNVTRewind);
 
opcode = kOpCodeBadFormat;
if (Seek(0, 0, emsg) <0) return SetBad();
 
fBot = true;
fEot = false;
fEom = false;
fPosFile = 0;
fPosRecord = 0;
fBad = false;
fTruncPend = true;
 
opcode = kOpCodeOK;
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtTapeTap::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11VirtTapeTap @ " << this << endl;
 
os << bl << " fFd: " << fFd << endl;
os << bl << " fSize: " << fSize << endl;
os << bl << " fPos: " << fPos << endl;
os << bl << " fBad: " << fBad << endl;
os << bl << " fPadOdd: " << fPadOdd << endl;
Rw11VirtTape::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::Seek(size_t seekpos, int dir, RerrMsg& emsg)
{
off_t offset = seekpos;
int whence = SEEK_SET;
if (dir > 0) {
whence = SEEK_CUR;
} else if (dir < 0) {
whence = SEEK_CUR;
offset = -offset;
}
if (::lseek(fFd, offset, whence) < 0) {
emsg.InitErrno("Rw11VirtTapeTap::Seek()", "seek() failed: ", errno);
return false;
}
 
UpdatePos(seekpos, dir);
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::Read(size_t nbyt, uint8_t* data, RerrMsg& emsg)
{
ssize_t irc = ::read(fFd, data, nbyt);
if (irc < 0) {
emsg.InitErrno("Rw11VirtTapeTap::Read()", "read() failed: ", errno);
return false;
}
UpdatePos(nbyt, +1);
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::Write(size_t nbyt, const uint8_t* data, bool back,
RerrMsg& emsg)
{
if (fTruncPend) {
if (ftruncate(fFd, fPos) < 0) {
emsg.InitErrno("Rw11VirtTapeTap::Write()", "ftruncate() failed: ", errno);
return false;
}
fTruncPend = false;
fSize = fPos;
}
 
ssize_t irc = ::write(fFd, data, nbyt);
if (irc < 0) {
emsg.InitErrno("Rw11VirtTapeTap::Write()", "write() failed: ", errno);
return false;
}
 
UpdatePos(nbyt, +1);
if (fPos > fSize) fSize = fPos;
 
if (back) {
if (!Seek(nbyt, -1, emsg)) return false;
}
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::CheckSizeForw(size_t nbyt, const char* text,
RerrMsg& emsg)
{
if (fPos+nbyt <= fSize) return true;
emsg.Init("Rw11VirtTapeTap::CheckSizeForw()", text);
return false;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::CheckSizeBack(size_t nbyt, const char* text,
RerrMsg& emsg)
{
if (nbyt <= fPos) return true;
emsg.Init("Rw11VirtTapeTap::CheckSizeBack()", text);
return false;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtTapeTap::UpdatePos(size_t nbyt, int dir)
{
if (dir == 0) {
fPos = nbyt;
} else if (dir > 0) {
fPos += nbyt;
} else {
fPos -= nbyt;
}
 
fBot = (fPos == 0);
fEot = (fCapacity == 0) ? false : (fPos > fCapacity);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::ParseMeta(uint32_t meta, size_t& rlen, bool& perr,
RerrMsg& emsg)
{
rlen = meta & kMeta_B_Rlen;
perr = meta & kMeta_M_Perr;
if (meta & kMeta_M_Mbz) {
emsg.Init("Rw11VirtTapeTap::ParseMeta", "bad meta tag");
return false;
}
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTapeTap::BadTapeMsg(const char* meth, RerrMsg& emsg)
{
emsg.Init(string("Rw11VirtTapeTap::")+meth, "bad tape format");
return false;
}
 
} // end namespace Retro
/Rw11VirtTape.ipp
0,0 → 1,103
// $Id: Rw11VirtTape.ipp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTape.ipp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation (inline) of Rw11VirtTape.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11VirtTape::SetWProt(bool wprot)
{
fWProt = wprot;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11VirtTape::SetCapacity(size_t nbyte)
{
fCapacity = nbyte;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11VirtTape::WProt() const
{
return fWProt;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11VirtTape::Capacity() const
{
return fCapacity;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11VirtTape::Bot() const
{
return fBot;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11VirtTape::Eot() const
{
return fEot;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11VirtTape::Eom() const
{
return fEom;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline int Rw11VirtTape::PosFile() const
{
return fPosFile;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline int Rw11VirtTape::PosRecord() const
{
return fPosRecord;
}
 
} // end namespace Retro
/Rw11VirtTapeTap.ipp
0,0 → 1,56
// $Id: Rw11VirtTapeTap.ipp 686 2015-06-04 21:08:08Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-06-04 686 1.0 Initial version
// 2015-05-17 683 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTapeTap.ipp 686 2015-06-04 21:08:08Z mueller $
\brief Implemenation (inline) of Rw11VirtTapeTap.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11VirtTapeTap::BytePadding(size_t rlen)
{
return fPadOdd ? ((rlen+1) & 0xfffe) : rlen;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11VirtTapeTap::SetBad()
{
fBad = true;
return false;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11VirtTapeTap::IncPosRecord(int delta)
{
if (fPosRecord != -1) fPosRecord += delta;
return;
}
 
 
} // end namespace Retro
/Rw11CntlPC11.hpp
0,0 → 1,86
// $Id: Rw11CntlPC11.hpp 665 2015-04-07 07:13:49Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-29 623 1.1 adopt to Rlink V4 attn logic
// 2013-05-03 515 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CntlPC11.hpp 665 2015-04-07 07:13:49Z mueller $
\brief Declaration of class Rw11CntlPC11.
*/
 
#ifndef included_Retro_Rw11CntlPC11
#define included_Retro_Rw11CntlPC11 1
 
#include "Rw11CntlBase.hpp"
#include "Rw11UnitPC11.hpp"
 
namespace Retro {
 
class Rw11CntlPC11 : public Rw11CntlBase<Rw11UnitPC11,2> {
public:
 
Rw11CntlPC11();
~Rw11CntlPC11();
 
void Config(const std::string& name, uint16_t base, int lam);
 
virtual void Start();
 
virtual bool BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart);
 
virtual void UnitSetup(size_t ind);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kIbaddr = 0177550; //!< PC11 default address
static const int kLam = 10; //!< PC11 default lam
 
static const uint16_t kRCSR = 000; //!< RCSR reg offset
static const uint16_t kRBUF = 002; //!< RBUF reg offset
static const uint16_t kPCSR = 004; //!< PCSR reg offset
static const uint16_t kPBUF = 006; //!< PBUF reg offset
 
static const uint16_t kUnit_PR = 0; //<! unit number of paper reader
static const uint16_t kUnit_PP = 1; //<! unit number of paper puncher
 
static const uint16_t kProbeOff = kRCSR; //!< probe address offset (rcsr)
static const bool kProbeInt = true; //!< probe int active
static const bool kProbeRem = true; //!< probr rem active
 
static const uint16_t kRCSR_M_ERROR = kWBit15;
static const uint16_t kPCSR_M_ERROR = kWBit15;
static const uint16_t kPBUF_M_RBUSY = kWBit09;
static const uint16_t kPBUF_M_PVAL = kWBit08;
static const uint16_t kPBUF_M_BUF = 0377;
 
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
void SetOnline(size_t ind, bool online);
protected:
size_t fPC_pbuf; //!< PrimClist: pbuf index
};
} // end namespace Retro
 
//#include "Rw11CntlPC11.ipp"
 
#endif
/Rw11UnitDisk.cpp
0,0 → 1,119
// $Id: Rw11UnitDisk.cpp 659 2015-03-22 23:15:51Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-03-21 659 1.0.1 add fEnabled, Enabled()
// 2013-04-19 507 1.0 Initial version
// 2013-02-19 490 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitDisk.cpp 659 2015-03-22 23:15:51Z mueller $
\brief Implemenation of Rw11UnitDisk.
*/
 
#include "librtools/Rexception.hpp"
 
#include "Rw11UnitDisk.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitDisk
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitDisk::Rw11UnitDisk(Rw11Cntl* pcntl, size_t index)
: Rw11UnitVirt<Rw11VirtDisk>(pcntl, index),
fType(),
fEnabled(false),
fNCyl(0),
fNHead(0),
fNSect(0),
fBlksize(0),
fNBlock(),
fWProt(false)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitDisk::~Rw11UnitDisk()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitDisk::SetType(const std::string& type)
{
throw Rexception("Rw11UnitDisk::SetType",
string("Bad args: only type '") + fType + "' supported");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitDisk::VirtRead(size_t lba, size_t nblk, uint8_t* data,
RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitDisk::VirtRead", "no disk attached");
return false;
}
return Virt()->Read(lba, nblk, data, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitDisk::VirtWrite(size_t lba, size_t nblk, const uint8_t* data,
RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitDisk::VirtWrite", "no disk attached");
return false;
}
return Virt()->Write(lba, nblk, data, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitDisk::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitDisk @ " << this << endl;
os << bl << " fType: " << fType << endl;
os << bl << " fEnabled: " << fEnabled << endl;
os << bl << " fNCyl: " << fNCyl << endl;
os << bl << " fNHead: " << fNHead << endl;
os << bl << " fNSect: " << fNSect << endl;
os << bl << " fBlksize: " << fBlksize << endl;
os << bl << " fNBlock: " << fNBlock << endl;
os << bl << " fWProt: " << fWProt << endl;
 
Rw11UnitVirt<Rw11VirtDisk>::Dump(os, ind, " ^");
return;
}
 
 
} // end namespace Retro
/Rw11Cpu.hpp
0,0 → 1,229
// $Id: Rw11Cpu.hpp 675 2015-05-08 21:05:08Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-08 675 1.2.3 w11a start/stop/suspend overhaul
// 2015-04-25 668 1.2.2 add AddRbibr(), AddWbibr()
// 2015-04-03 661 1.2.1 add kStat_M_* defs
// 2015-03-21 659 1.2 add RAddrMap; add AllRAddrMapInsert();
// 2015-01-01 626 1.1 Adopt for rlink v4 and 4k ibus window; add IAddrMap
// 2013-04-14 506 1.0.1 add AddLalh(),AddRMem(),AddWMem()
// 2013-04-12 504 1.0 Initial version
// 2013-01-27 478 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11Cpu.hpp 675 2015-05-08 21:05:08Z mueller $
\brief Declaration of class Rw11Cpu.
*/
 
#ifndef included_Retro_Rw11Cpu
#define included_Retro_Rw11Cpu 1
 
#include <string>
#include <vector>
 
#include "boost/utility.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/thread/locks.hpp"
#include "boost/thread/condition_variable.hpp"
 
#include "librtools/Rstats.hpp"
#include "librtools/RerrMsg.hpp"
#include "librlink/RlinkConnect.hpp"
#include "librlink/RlinkAddrMap.hpp"
 
#include "Rw11Probe.hpp"
 
#include "librtools/Rbits.hpp"
#include "Rw11.hpp"
 
namespace Retro {
 
class Rw11Cntl; // forw decl to avoid circular incl
 
class Rw11Cpu : public Rbits, private boost::noncopyable {
public:
typedef std::map<std::string, boost::shared_ptr<Rw11Cntl>> cmap_t;
typedef cmap_t::iterator cmap_it_t;
typedef cmap_t::const_iterator cmap_cit_t;
typedef cmap_t::value_type cmap_val_t;
 
 
explicit Rw11Cpu(const std::string& type);
virtual ~Rw11Cpu();
 
void Setup(Rw11* pw11);
Rw11& W11() const;
RlinkServer& Server() const;
RlinkConnect& Connect() const;
RlogFile& LogFile() const;
 
const std::string& Type() const;
size_t Index() const;
uint16_t Base() const;
uint16_t IBase() const;
 
void AddCntl(const boost::shared_ptr<Rw11Cntl>& spcntl);
bool TestCntl(const std::string& name) const;
void ListCntl(std::vector<std::string>& list) const;
Rw11Cntl& Cntl(const std::string& name) const;
 
void Start();
 
std::string NextCntlName(const std::string& base) const;
 
int AddMembe(RlinkCommandList& clist, uint16_t be,
bool stick=false);
int AddRibr(RlinkCommandList& clist, uint16_t ibaddr);
int AddWibr(RlinkCommandList& clist, uint16_t ibaddr,
uint16_t data);
 
int AddRbibr(RlinkCommandList& clist, uint16_t ibaddr,
size_t size);
int AddWbibr(RlinkCommandList& clist, uint16_t ibaddr,
std::vector<uint16_t> block);
 
int AddLalh(RlinkCommandList& clist, uint32_t addr,
uint16_t mode=kCPAH_M_22BIT);
int AddRMem(RlinkCommandList& clist, uint32_t addr,
uint16_t* buf, size_t size,
uint16_t mode=kCPAH_M_22BIT,
bool singleblk=false);
int AddWMem(RlinkCommandList& clist, uint32_t addr,
const uint16_t* buf, size_t size,
uint16_t mode=kCPAH_M_22BIT,
bool singleblk=false);
 
bool MemRead(uint16_t addr, std::vector<uint16_t>& data,
size_t nword, RerrMsg& emsg);
bool MemWrite(uint16_t addr, const std::vector<uint16_t>& data,
RerrMsg& emsg);
 
bool ProbeCntl(Rw11Probe& dsc);
 
bool LoadAbs(const std::string& fname, RerrMsg& emsg,
bool trace=false);
bool Boot(const std::string& uname, RerrMsg& emsg);
 
void SetCpuGoUp();
void SetCpuGoDown(uint16_t stat);
double WaitCpuGoDown(double tout);
bool CpuGo() const;
uint16_t CpuStat() const;
 
uint16_t IbusRemoteAddr(uint16_t ibaddr) const;
void AllIAddrMapInsert(const std::string& name, uint16_t ibaddr);
void AllRAddrMapInsert(const std::string& name, uint16_t rbaddr);
 
bool IAddrMapInsert(const std::string& name, uint16_t ibaddr);
bool IAddrMapErase(const std::string& name);
bool IAddrMapErase(uint16_t ibaddr);
void IAddrMapClear();
const RlinkAddrMap& IAddrMap() const;
 
bool RAddrMapInsert(const std::string& name, uint16_t rbaddr);
bool RAddrMapErase(const std::string& name);
bool RAddrMapErase(uint16_t rbaddr);
void RAddrMapClear();
const RlinkAddrMap& RAddrMap() const;
 
void W11AttnHandler();
 
const Rstats& Stats() const;
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kCPCONF = 0x0000; //!< CPCONF reg offset
static const uint16_t kCPCNTL = 0x0001; //!< CPADDR reg offset
static const uint16_t kCPSTAT = 0x0002; //!< CPSTAT reg offset
static const uint16_t kCPPSW = 0x0003; //!< CPPSW reg offset
static const uint16_t kCPAL = 0x0004; //!< CPAL reg offset
static const uint16_t kCPAH = 0x0005; //!< CPAH reg offset
static const uint16_t kCPMEM = 0x0006; //!< CPMEM reg offset
static const uint16_t kCPMEMI = 0x0007; //!< CPMEMI reg offset
static const uint16_t kCPR0 = 0x0008; //!< CPR0 reg offset
static const uint16_t kCPPC = 0x000f; //!< CPPC reg offset
static const uint16_t kCPMEMBE = 0x0010; //!< CPMEMBE reg offset
 
static const uint16_t kCPFUNC_NOOP = 0x0000; //!<
static const uint16_t kCPFUNC_START = 0x0001; //!<
static const uint16_t kCPFUNC_STOP = 0x0002; //!<
static const uint16_t kCPFUNC_STEP = 0x0003; //!<
static const uint16_t kCPFUNC_CRESET = 0x0004; //!<
static const uint16_t kCPFUNC_BRESET = 0x0005; //!<
static const uint16_t kCPFUNC_SUSPEND = 0x0006; //!<
static const uint16_t kCPFUNC_RESUME = 0x0007; //!<
 
static const uint16_t kCPSTAT_M_SuspExt = kWBit09; //!<
static const uint16_t kCPSTAT_M_SuspInt = kWBit08; //!<
static const uint16_t kCPSTAT_M_CpuRust = 0x00f0; //!<
static const uint16_t kCPSTAT_V_CpuRust = 4; //!<
static const uint16_t kCPSTAT_B_CpuRust = 0x000f; //!<
static const uint16_t kCPSTAT_M_CpuSusp = kWBit03; //!<
static const uint16_t kCPSTAT_M_CpuGo = kWBit02; //!<
static const uint16_t kCPSTAT_M_CmdMErr = kWBit01; //!<
static const uint16_t kCPSTAT_M_CmdErr = kWBit00; //!<
 
static const uint16_t kCPURUST_INIT = 0x0; //!< cpu in init state
static const uint16_t kCPURUST_HALT = 0x1; //!< cpu executed HALT
static const uint16_t kCPURUST_RESET = 0x2; //!< cpu was reset
static const uint16_t kCPURUST_STOP = 0x3; //!< cpu was stopped
static const uint16_t kCPURUST_STEP = 0x4; //!< cpu was stepped
static const uint16_t kCPURUST_SUSP = 0x5; //!< cpu was suspended
static const uint16_t kCPURUST_RUNS = 0x7; //!< cpu running
static const uint16_t kCPURUST_VECFET = 0x8; //!< vector fetch halt
static const uint16_t kCPURUST_RECRSV = 0x9; //!< rec red-stack halt
static const uint16_t kCPURUST_SFAIL = 0xa; //!< sequencer failure
static const uint16_t kCPURUST_VFAIL = 0xb; //!< vmbox failure
 
static const uint16_t kCPAH_M_ADDR = 0x003f; //!<
static const uint16_t kCPAH_M_22BIT = kWBit06; //!<
static const uint16_t kCPAH_M_UBMAP = kWBit07; //!<
 
static const uint16_t kCPMEMBE_M_STICK = kWBit02; //!<
static const uint16_t kCPMEMBE_M_BE = 0x0003; //!<
 
// defs for the four status bits defined by w11 rbus iface
static const uint8_t kStat_M_CmdErr = kBBit07; //!< stat: cmderr flag
static const uint8_t kStat_M_CmdMErr = kBBit06; //!< stat: cmdmerr flag
static const uint8_t kStat_M_CpuHalt = kBBit05; //!< stat: cpuhalt flag
static const uint8_t kStat_M_CpuGo = kBBit04; //!< stat: cpugo flag
 
private:
Rw11Cpu() {} //!< default ctor blocker
 
protected:
Rw11* fpW11;
std::string fType;
size_t fIndex;
uint16_t fBase;
uint16_t fIBase;
bool fCpuGo;
uint16_t fCpuStat;
boost::mutex fCpuGoMutex;
boost::condition_variable fCpuGoCond;
cmap_t fCntlMap; //!< name->cntl map
RlinkAddrMap fIAddrMap; //!< ibus name<->address mapping
RlinkAddrMap fRAddrMap; //!< rbus name<->address mapping
Rstats fStats; //!< statistics
};
} // end namespace Retro
 
#include "Rw11Cpu.ipp"
 
#endif
/Rw11CntlLP11.cpp
0,0 → 1,199
// $Id: Rw11CntlLP11.cpp 659 2015-03-22 23:15:51Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-30 625 1.2 adopt to Rlink V4 attn logic
// 2014-12-25 621 1.1 adopt to 4k word ibus window
// 2013-05-04 515 1.0 Initial version
// 2013-05-01 513 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlLP11.cpp 659 2015-03-22 23:15:51Z mueller $
\brief Implemenation of Rw11CntlLP11.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintBvi.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
#include "librtools/RlogMsg.hpp"
 
#include "Rw11CntlLP11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11CntlLP11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11CntlLP11::kIbaddr;
const int Rw11CntlLP11::kLam;
 
const uint16_t Rw11CntlLP11::kCSR;
const uint16_t Rw11CntlLP11::kBUF;
 
const uint16_t Rw11CntlLP11::kProbeOff;
const bool Rw11CntlLP11::kProbeInt;
const bool Rw11CntlLP11::kProbeRem;
 
const uint16_t Rw11CntlLP11::kCSR_M_ERROR;
const uint16_t Rw11CntlLP11::kBUF_M_VAL;
const uint16_t Rw11CntlLP11::kBUF_M_BUF;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11CntlLP11::Rw11CntlLP11()
: Rw11CntlBase<Rw11UnitLP11,1>("lp11"),
fPC_buf(0)
{
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
for (size_t i=0; i<NUnit(); i++) {
fspUnit[i].reset(new Rw11UnitLP11(this, i));
}
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11CntlLP11::~Rw11CntlLP11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlLP11::Config(const std::string& name, uint16_t base, int lam)
{
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlLP11::Start()
{
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
throw Rexception("Rw11CntlLP11::Start",
"Bad state: started, no lam, not enable, not found");
// add device register address ibus and rbus mappings
// done here because now Cntl bound to Cpu and Cntl probed
Cpu().AllIAddrMapInsert(Name()+".csr", Base() + kCSR);
Cpu().AllIAddrMapInsert(Name()+".buf", Base() + kBUF);
 
// setup primary info clist
fPrimClist.Clear();
fPrimClist.AddAttn();
fPC_buf = Cpu().AddRibr(fPrimClist, fBase+kBUF);
 
// add attn handler
Server().AddAttnHandler(boost::bind(&Rw11CntlLP11::AttnHandler, this, _1),
uint16_t(1)<<fLam, (void*)this);
 
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlLP11::UnitSetup(size_t ind)
{
Rw11UnitLP11& unit = *fspUnit[ind];
SetOnline(unit.Virt()); // online if stream attached
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlLP11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlLP11 @ " << this << endl;
os << bl << " fPC_buf: " << fPC_buf << endl;
 
Rw11CntlBase<Rw11UnitLP11,1>::Dump(os, ind, " ^");
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11CntlLP11::AttnHandler(RlinkServer::AttnArgs& args)
{
fStats.Inc(kStatNAttnHdl);
Server().GetAttnInfo(args, fPrimClist);
 
uint16_t buf = fPrimClist[fPC_buf].Data();
bool val = buf & kBUF_M_VAL;
uint8_t ochr = buf & kBUF_M_BUF;
 
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
lmsg << "-I LP11." << Name()
<< " buf=" << RosPrintBvi(buf,8)
<< " val=" << val;
if (val) {
lmsg << " char=";
if (ochr>=040 && ochr<0177) {
lmsg << "'" << char(ochr) << "'";
} else {
lmsg << RosPrintBvi(ochr,8);
}
}
}
if (val) {
RerrMsg emsg;
bool rc = fspUnit[0]->VirtWrite(&ochr, 1, emsg);
if (!rc) {
RlogMsg lmsg(LogFile());
lmsg << emsg;
SetOnline(false);
}
if (ochr == 014) { // ^L = FF = FormFeed seen ?
rc = fspUnit[0]->VirtFlush(emsg);
}
}
 
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlLP11::SetOnline(bool online)
{
Rw11Cpu& cpu = Cpu();
uint16_t csr = online ? 0 : kCSR_M_ERROR;
RlinkCommandList clist;
cpu.AddWibr(clist, fBase+kCSR, csr);
Server().Exec(clist);
return;
}
} // end namespace Retro
/Rw11UnitDisk.ipp
0,0 → 1,133
// $Id: Rw11UnitDisk.ipp 659 2015-03-22 23:15:51Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-03-21 659 1.0.2 add fEnabled, Enabled()
// 2015-02-18 647 1.0.1 add Nwrd2Nblk()
// 2013-04-19 507 1.0 Initial version
// 2013-02-19 490 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitDisk.ipp 659 2015-03-22 23:15:51Z mueller $
\brief Implemenation (inline) of Rw11UnitDisk.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const std::string& Rw11UnitDisk::Type() const
{
return fType;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11UnitDisk::Enabled() const
{
return fEnabled;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11UnitDisk::NCylinder() const
{
return fNCyl;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11UnitDisk::NHead() const
{
return fNHead;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11UnitDisk::NSector() const
{
return fNSect;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11UnitDisk::BlockSize() const
{
return fBlksize;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11UnitDisk::NBlock() const
{
return fNBlock;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint32_t Rw11UnitDisk::Chs2Lba(uint16_t cy, uint16_t hd, uint16_t se)
{
return se + fNSect * (hd + fNHead*cy);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitDisk::Lba2Chs(uint32_t lba, uint16_t& cy, uint16_t& hd,
uint16_t& se)
{
se = lba % fNSect;
hd = (lba/fNSect) % fNHead;
cy = lba / (fNSect*fNHead);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint32_t Rw11UnitDisk::Nwrd2Nblk(uint32_t nwrd)
{
return (2*nwrd+BlockSize()-1) / BlockSize();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitDisk::SetWProt(bool wprot)
{
fWProt = wprot;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11UnitDisk::WProt() const
{
return fWProt;
}
 
 
} // end namespace Retro
/Rw11CntlRL11.hpp
0,0 → 1,230
// $Id: Rw11CntlRL11.hpp 665 2015-04-07 07:13:49Z mueller $
//
// Copyright 2014-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-03-01 653 1.0 Initial version
// 2014-06-08 561 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CntlRL11.hpp 665 2015-04-07 07:13:49Z mueller $
\brief Declaration of class Rw11CntlRL11.
*/
 
#ifndef included_Retro_Rw11CntlRL11
#define included_Retro_Rw11CntlRL11 1
 
#include "Rw11CntlBase.hpp"
#include "Rw11UnitRL11.hpp"
#include "Rw11RdmaDisk.hpp"
 
namespace Retro {
 
class Rw11CntlRL11 : public Rw11CntlBase<Rw11UnitRL11,4> {
public:
 
Rw11CntlRL11();
~Rw11CntlRL11();
 
void Config(const std::string& name, uint16_t base, int lam);
 
virtual void Start();
 
virtual bool BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart);
 
virtual void UnitSetup(size_t ind);
 
void SetChunkSize(size_t chunk);
size_t ChunkSize() const;
 
const Rstats& RdmaStats() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kIbaddr = 0174400; //!< RL11 default address
static const int kLam = 5; //!< RL11 default lam
 
static const uint16_t kRLCS = 000; //!< RLCS reg offset
static const uint16_t kRLBA = 002; //!< RLBA reg offset
static const uint16_t kRLDA = 004; //!< RLDA reg offset
static const uint16_t kRLMP = 006; //!< RLMP reg offset
 
static const uint16_t kProbeOff = kRLCS; //!< probe address offset (rlcs)
static const bool kProbeInt = true; //!< probe int active
static const bool kProbeRem = true; //!< probr rem active
 
static const uint16_t kRLCS_M_ERR = kWBit15;
static const uint16_t kRLCS_M_DE = kWBit14;
static const uint16_t kRLCS_V_E = 10;
static const uint16_t kRLCS_B_E = 0017;
static const uint16_t kRLCS_V_DS = 8;
static const uint16_t kRLCS_B_DS = 0003;
static const uint16_t kRLCS_M_CRDY = kWBit07;
static const uint16_t kRLCS_M_IE = kWBit06;
static const uint16_t kRLCS_M_BAE = 000060;
static const uint16_t kRLCS_V_BAE = 4;
static const uint16_t kRLCS_B_BAE = 0003;
static const uint16_t kRLCS_V_FUNC = 1;
static const uint16_t kRLCS_B_FUNC = 0007;
static const uint16_t kRLCS_M_DRDY = kWBit00;
 
static const uint16_t kFUNC_NOOP = 0; // done in ibdr
static const uint16_t kFUNC_WCHK = 1;
static const uint16_t kFUNC_GS = 2; // done in ibdr
static const uint16_t kFUNC_SEEK = 3; // done in ibdr
static const uint16_t kFUNC_RHDR = 4;
static const uint16_t kFUNC_WRITE = 5;
static const uint16_t kFUNC_READ = 6;
static const uint16_t kFUNC_RNHC = 7;
 
static const uint16_t kERR_M_DE = kWBit04; // drive error flag
static const uint16_t kERR_OPI = 1; // OPI Operation Incomplete
static const uint16_t kERR_WCHK = 2; // Read Data CRC or Write Check
static const uint16_t kERR_HCRC = 3; // Header CRC
static const uint16_t kERR_DLATE = 4; // Data Late
static const uint16_t kERR_HNFND = 5; // Header not found
static const uint16_t kERR_NXM = 8; // Non-Existant Memory
 
// rem usage of rlcs
static const uint16_t kRLCS_V_MPREM = 11;
static const uint16_t kRLCS_B_MPREM = 0037;
static const uint16_t kRLCS_V_MPLOC = 8;
static const uint16_t kRLCS_B_MPLOC = 0007;
static const uint16_t kRLCS_ENA_MPREM = kWBit05;
static const uint16_t kRLCS_ENA_MPLOC = kWBit04;
 
static const uint16_t kRFUNC_WCS = 1;
static const uint16_t kRFUNC_WMP = 2;
 
static const uint16_t kMPREM_M_MAP = kWBit04;
static const uint16_t kMPREM_M_SEQ = kWBit03;
static const uint16_t kMPREM_S_MP = 0000; // MP+STA+POS sequence
static const uint16_t kMPREM_S_STA = 0001;
static const uint16_t kMPREM_S_POS = 0002;
 
static const uint16_t kMPREM_MP = 0003; // mem: mp
static const uint16_t kMPREM_CRC = 0004; // mem: crc
static const uint16_t kMPREM_STA = 0010; // mem: sta array (4 units)
static const uint16_t kMPREM_POS = 0014; // mem: pos array (4 units)
 
static const uint16_t kMPREM_SEQ_MPSTAPOS = kMPREM_M_MAP|
kMPREM_M_SEQ|kMPREM_S_MP;
 
static const uint16_t kMPLOC_MP = 0000; // 000: return imem(mp)
static const uint16_t kMPLOC_STA = 0001; // 001: return sta(ds)
static const uint16_t kMPLOC_POS = 0002; // 010: return pos(ds) -> ZERO
static const uint16_t kMPLOC_ZERO = 0003; // 011: return 0 -> CRC
static const uint16_t kMPLOC_CRC = 0004; // 100: return imem(crc)
 
static const uint16_t kRLDA_SE_M_DF = 0177600;
static const uint16_t kRLDA_SE_V_DF = 7;
static const uint16_t kRLDA_SE_B_DF = 0777;
static const uint16_t kRLDA_SE_M_HS = kWBit04;
static const uint16_t kRLDA_SE_M_DIR = kWBit02;
static const uint16_t kRLDA_SE_X_MSK = 0000153;
static const uint16_t kRLDA_SE_X_VAL = 0000001;
 
static const uint16_t kRLDA_RW_M_CA = 0177600;
static const uint16_t kRLDA_RW_V_CA = 7;
static const uint16_t kRLDA_RW_B_CA = 0777;
static const uint16_t kRLDA_RW_M_HS = kWBit06;
static const uint16_t kRLDA_RW_V_HS = 6;
static const uint16_t kRLDA_RW_B_HS = 001;
static const uint16_t kRLDA_RW_B_SA = 077;
 
static const uint16_t kRLDA_GS_M_RST = kWBit03;
static const uint16_t kRLDA_GS_X_MSK = 0000367;
static const uint16_t kRLDA_GS_X_VAL = 0000003;
 
static const uint16_t kSTA_M_WDE = kWBit15; // Write data error - 0!
static const uint16_t kSTA_M_CHE = kWBit14; // Current head error - 0!
static const uint16_t kSTA_M_WL = kWBit13; // Write lock
static const uint16_t kSTA_M_STO = kWBit12; // Seek time out
static const uint16_t kSTA_M_SPE = kWBit11; // Spin error
static const uint16_t kSTA_M_WGE = kWBit10; // Write gate error
static const uint16_t kSTA_M_VCE = kWBit09; // Volume check
static const uint16_t kSTA_M_DSE = kWBit08; // Drive select error
static const uint16_t kSTA_M_DT = kWBit07; // Drive type 1=RL02
static const uint16_t kSTA_M_HS = kWBit06; // Head select
static const uint16_t kSTA_M_CO = kWBit05; // Cover open
static const uint16_t kSTA_M_HO = kWBit04; // Heads out
static const uint16_t kSTA_M_BH = kWBit03; // Brush home - 1!
static const uint16_t kSTA_B_ST = 0007; // Drive state
 
static const uint16_t kST_LOAD = 0; // Load(ing) cartidge - used
static const uint16_t kST_SPIN = 1; // Spin(ing) up - !unused!
static const uint16_t kST_BRUSH = 2; // Brush(ing) cycle - !unused!
static const uint16_t kST_HLOAD = 3; // Load(ing) heads - !unused!
static const uint16_t kST_SEEK = 4; // Seek(ing) - ?maybe?
static const uint16_t kST_LOCK = 5; // Lock(ed) on - used
static const uint16_t kST_UNL = 6; // Unload(ing) heads - !unused!
static const uint16_t kST_DOWN = 7; // Spin(ing) down - !unused!
 
// statistics counter indices
enum stats {
kStatNFuncWchk = Rw11Cntl::kDimStat,
kStatNFuncRhdr,
kStatNFuncWrite,
kStatNFuncRead,
kStatNFuncRnhc,
kDimStat
};
 
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
void RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
RlinkCommandList& clist);
void RdmaPostExecCB(int stat, size_t ndone,
RlinkCommandList& clist, size_t ncmd);
void LogRler(uint16_t rlerr);
void AddSetStatus(RlinkCommandList& clist, size_t ind,
uint16_t sta);
void AddSetPosition(RlinkCommandList& clist, size_t ind,
uint16_t pos);
void AddErrorExit(RlinkCommandList& clist, uint16_t rlerr);
void AddNormalExit(RlinkCommandList& clist, size_t ndone,
uint16_t rlerr=0);
uint16_t CalcCrc(size_t size, const uint16_t* data);
 
protected:
size_t fPC_rlcs; //!< PrimClist: rlcs index
size_t fPC_rlba; //!< PrimClist: rlba index
size_t fPC_rlda; //!< PrimClist: rlda index
size_t fPC_imp; //!< PrimClist: imp index
size_t fPC_wc; //!< PrimClist: wc index
size_t fPC_sta; //!< PrimClist: sta index
size_t fPC_pos; //!< PrimClist: pos index
 
uint16_t fRd_rlcs; //!< Rdma: request rlcs
uint16_t fRd_rlda; //!< Rdma: request rlda
uint16_t fRd_rlmp; //!< Rdma: request rlmp (~wc)
uint16_t fRd_sta; //!< Rdma: initial drive status
uint16_t fRd_pos; //!< Rdma: initial drive position
uint32_t fRd_addr; //!< Rdma: current addr
uint32_t fRd_lba; //!< Rdma: current lba
uint32_t fRd_nwrd; //!< Rdma: current nwrd
uint16_t fRd_fu; //!< Rdma: request fu code
bool fRd_ovr; //!< Rdma: overrun condition found
Rw11RdmaDisk fRdma; //!< Rdma controller
};
} // end namespace Retro
 
#include "Rw11CntlRL11.ipp"
 
#endif
/Rw11UnitRHRP.cpp
0,0 → 1,148
// $Id: Rw11UnitRHRP.cpp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-14 680 1.0 Initial version
// 2015-03-21 659 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitRHRP.cpp 680 2015-05-14 13:29:46Z mueller $
\brief Implemenation of Rw11UnitRHRP.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/Rexception.hpp"
#include "librtools/RosFill.hpp"
#include "Rw11CntlRHRP.hpp"
 
#include "Rw11UnitRHRP.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitRHRP
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11UnitRHRP::kDTE_M_RM;
const uint16_t Rw11UnitRHRP::kDTE_RP04;
const uint16_t Rw11UnitRHRP::kDTE_RP06;
const uint16_t Rw11UnitRHRP::kDTE_RM03;
const uint16_t Rw11UnitRHRP::kDTE_RM80;
const uint16_t Rw11UnitRHRP::kDTE_RM05;
const uint16_t Rw11UnitRHRP::kDTE_RP07;
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitRHRP::Rw11UnitRHRP(Rw11CntlRHRP* pcntl, size_t index)
: Rw11UnitDiskBase<Rw11CntlRHRP>(pcntl, index),
fRpdt(0),
fRpds(0)
{
// setup disk geometry: default off
fType = "off";
fEnabled = false;
fBlksize = 512;
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitRHRP::~Rw11UnitRHRP()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitRHRP::SetType(const std::string& type)
{
if (Virt()) {
throw Rexception("Rw11UnitRHRP::SetType",
string("Bad state: file attached"));
}
if (type == "off") {
fRpdt = 0;
fNCyl = 0;
fNHead = 0;
fNSect = 0;
} else if (type == "rp04") {
fRpdt = kDTE_RP04;
fNCyl = 411;
fNHead = 19;
fNSect = 22;
} else if (type == "rp06") {
fRpdt = kDTE_RP06;
fNCyl = 815;
fNHead = 19;
fNSect = 22;
} else if (type == "rm03") {
fRpdt = kDTE_RM03;
fNCyl = 823;
fNHead = 5;
fNSect = 32;
} else if (type == "rm80") {
fRpdt = kDTE_RM80;
fNCyl = 559;
fNHead = 14;
fNSect = 31;
} else if (type == "rm05") {
fRpdt = kDTE_RM05;
fNCyl = 823;
fNHead = 19;
fNSect = 32;
} else if (type == "rp07") {
fRpdt = kDTE_RP07;
fNCyl = 630;
fNHead = 32;
fNSect = 50;
} else {
throw Rexception("Rw11UnitRHRP::SetType",
string("Bad args: only off or rp04,rp06,rm03,rm80,rm05,rp07 supported"));
}
 
fType = type;
fEnabled = fNCyl != 0;
fNBlock = fNCyl*fNHead*fNSect;
 
Cntl().UnitSetup(Index()); // update hardware
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitRHRP::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitRHRP @ " << this << endl;
os << bl << " fRpdt: " << RosPrintf(fRpdt,"o",6) << endl;
os << bl << " fRpds: " << RosPrintf(fRpds,"o",6) << endl;
 
Rw11UnitDiskBase<Rw11CntlRHRP>::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11UnitRHRP.ipp
0,0 → 1,69
// $Id: Rw11UnitRHRP.ipp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-14 680 1.0 Initial version
// 2015-03-21 659 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitRHRP.ipp 680 2015-05-14 13:29:46Z mueller $
\brief Implemenation (inline) of Rw11UnitRHRP.
*/
 
#include "Rw11UnitRHRP.hpp"
 
/*!
\class Retro::Rw11UnitRHRP
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11UnitRHRP::Rpdt() const
{
return fRpdt;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11UnitRHRP::IsRmType() const
{
return fRpdt & kDTE_M_RM;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitRHRP::SetRpds(uint16_t rpds)
{
fRpds = rpds;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11UnitRHRP::Rpds() const
{
return fRpds;
}
 
} // end namespace Retro
/Rw11Unit.hpp
0,0 → 1,97
// $Id: Rw11Unit.hpp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-13 680 1.1.1 add Enabled()
// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone()
// 2013-05-01 513 1.0.1 add fAttachOpts, (Set)AttachOpts()
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11Unit.hpp 680 2015-05-14 13:29:46Z mueller $
\brief Declaration of class Rw11Unit.
*/
 
#ifndef included_Retro_Rw11Unit
#define included_Retro_Rw11Unit 1
 
#include <string>
 
#include "boost/utility.hpp"
 
#include "librtools/Rstats.hpp"
#include "librtools/RerrMsg.hpp"
#include "librlink/RlinkServer.hpp"
 
#include "librtools/Rbits.hpp"
#include "Rw11Cntl.hpp"
 
namespace Retro {
 
class Rw11Unit : public Rbits, private boost::noncopyable {
public:
 
Rw11Unit(Rw11Cntl* pcntl, size_t index);
virtual ~Rw11Unit();
 
size_t Index() const;
std::string Name() const;
 
void SetAttachOpts(const std::string& opts);
const std::string& AttachOpts() const;
 
Rw11Cntl& CntlBase() const;
Rw11Cpu& Cpu() const;
Rw11& W11() const;
RlinkServer& Server() const;
RlinkConnect& Connect() const;
RlogFile& LogFile() const;
 
virtual bool Enabled() const;
 
virtual bool Attach(const std::string& url, RerrMsg& emsg);
virtual void Detach();
 
const Rstats& Stats() const;
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// statistics counter indices
enum stats {
kDimStat = 0
};
 
protected:
virtual void AttachDone();
virtual void DetachCleanup();
virtual void DetachDone();
 
private:
Rw11Unit() {} //!< default ctor blocker
 
protected:
Rw11Cntl* fpCntlBase; //!< plain Rw11Cntl ptr
size_t fIndex; //!< unit number
std::string fAttachOpts; //!< unit context options for attach
Rstats fStats; //!< statistics
};
} // end namespace Retro
 
#include "Rw11Unit.ipp"
 
#endif
/Rw11CntlRHRP.ipp
0,0 → 1,56
// $Id: Rw11CntlRHRP.ipp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-14 680 1.0 Initial version
// 2015-03-21 659 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlRHRP.ipp 680 2015-05-14 13:29:46Z mueller $
\brief Implemenation (inline) of Rw11CntlRHRP.
*/
 
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11CntlRHRP::SetChunkSize(size_t chunk)
{
fRdma.SetChunkSize(chunk);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11CntlRHRP::ChunkSize() const
{
return fRdma.ChunkSize();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11CntlRHRP::RdmaStats() const
{
return fRdma.Stats();
}
 
 
} // end namespace Retro
/Rw11UnitRL11.cpp
0,0 → 1,106
// $Id: Rw11UnitRL11.cpp 659 2015-03-22 23:15:51Z mueller $
//
// Copyright 2014- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-03-21 659 1.0.1 BUGFIX: SetType(): set fType;
// 2014-06-08 561 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitRL11.cpp 659 2015-03-22 23:15:51Z mueller $
\brief Implemenation of Rw11UnitRL11.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/Rexception.hpp"
#include "librtools/RosFill.hpp"
#include "Rw11CntlRL11.hpp"
 
#include "Rw11UnitRL11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitRL11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitRL11::Rw11UnitRL11(Rw11CntlRL11* pcntl, size_t index)
: Rw11UnitDiskBase<Rw11CntlRL11>(pcntl, index),
fRlsta(0),
fRlpos(0)
{
// setup disk geometry: rl01 and rl02 supported, default rl02
fType = "rl02";
fEnabled = true;
fNCyl = 512;
fNHead = 2;
fNSect = 40;
fBlksize = 256;
fNBlock = fNCyl*fNHead*fNSect;
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitRL11::~Rw11UnitRL11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitRL11::SetType(const std::string& type)
{
if (Virt()) {
throw Rexception("Rw11UnitRL11::SetType",
string("Bad state: file attached"));
}
if (type == "rl01") {
fNCyl = 256;
} else if (type == "rl02") {
fNCyl = 512;
} else {
throw Rexception("Rw11UnitRL11::SetType",
string("Bad args: only types 'rl01' and 'rl02' supported"));
}
 
fType = type;
fNBlock = fNCyl*fNHead*fNSect;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitRL11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitRL11 @ " << this << endl;
os << bl << " fRlsta: " << RosPrintf(fRlsta,"o",6) << endl;
os << bl << " fRlpos: " << RosPrintf(fRlpos,"o",6) << endl;
 
Rw11UnitDiskBase<Rw11CntlRL11>::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11CntlPC11.cpp
0,0 → 1,322
// $Id: Rw11CntlPC11.cpp 659 2015-03-22 23:15:51Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-30 625 1.2 adopt to Rlink V4 attn logic
// 2014-12-25 621 1.1 adopt to 4k word ibus window
// 2013-05-03 515 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlPC11.cpp 659 2015-03-22 23:15:51Z mueller $
\brief Implemenation of Rw11CntlPC11.
*/
 
#include "boost/bind.hpp"
#include "boost/foreach.hpp"
#define foreach_ BOOST_FOREACH
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintBvi.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
#include "librtools/RlogMsg.hpp"
 
#include "Rw11CntlPC11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11CntlPC11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11CntlPC11::kIbaddr;
const int Rw11CntlPC11::kLam;
 
const uint16_t Rw11CntlPC11::kRCSR;
const uint16_t Rw11CntlPC11::kRBUF;
const uint16_t Rw11CntlPC11::kPCSR;
const uint16_t Rw11CntlPC11::kPBUF;
 
const uint16_t Rw11CntlPC11::kUnit_PR;
const uint16_t Rw11CntlPC11::kUnit_PP;
 
const uint16_t Rw11CntlPC11::kProbeOff;
const bool Rw11CntlPC11::kProbeInt;
const bool Rw11CntlPC11::kProbeRem;
 
const uint16_t Rw11CntlPC11::kRCSR_M_ERROR;
const uint16_t Rw11CntlPC11::kPCSR_M_ERROR;
const uint16_t Rw11CntlPC11::kPBUF_M_RBUSY;
const uint16_t Rw11CntlPC11::kPBUF_M_PVAL;
const uint16_t Rw11CntlPC11::kPBUF_M_BUF;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11CntlPC11::Rw11CntlPC11()
: Rw11CntlBase<Rw11UnitPC11,2>("pc11"),
fPC_pbuf(0)
{
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
for (size_t i=0; i<NUnit(); i++) {
fspUnit[i].reset(new Rw11UnitPC11(this, i));
}
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11CntlPC11::~Rw11CntlPC11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlPC11::Config(const std::string& name, uint16_t base, int lam)
{
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlPC11::Start()
{
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
throw Rexception("Rw11CntlPC11::Start",
"Bad state: started, no lam, not enable, not found");
// add device register address ibus and rbus mappings
// done here because now Cntl bound to Cpu and Cntl probed
Cpu().AllIAddrMapInsert(Name()+".rcsr", Base() + kRCSR);
Cpu().AllIAddrMapInsert(Name()+".rbuf", Base() + kRBUF);
Cpu().AllIAddrMapInsert(Name()+".pcsr", Base() + kPCSR);
Cpu().AllIAddrMapInsert(Name()+".pbuf", Base() + kPBUF);
 
// setup primary info clist
fPrimClist.Clear();
fPrimClist.AddAttn();
fPC_pbuf = Cpu().AddRibr(fPrimClist, fBase+kPBUF);
 
// add attn handler
Server().AddAttnHandler(boost::bind(&Rw11CntlPC11::AttnHandler, this, _1),
uint16_t(1)<<fLam, (void*)this);
 
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11CntlPC11::BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart)
{
uint16_t kBOOT_START = 0017476;
uint16_t bootcode[] = { // papertape lda loader, from dec-11-l2pc-po
0000000, // C000: halt
0010706, // astart: mov pc,sp
0024646, // cmp -(sp),-(sp)
0010705, // mov pc,r5
0062705, 0000112, // add #000112,r5
0005001, // clr r1
0013716, 0177570, // B000: mov @#cp.dsr,(sp)
0006016, // ror (sp)
0103402, // bcs B001
0005016, // clr (sp)
0000403, // br B002
0006316, // B001: asl (sp)
0001001, // bne B002
0010116, // mov r1,(sp)
0005000, // B002: clr r0
0004715, // jsr pc,(r5)
0105303, // decb r3
0001374, // bne B002
0004715, // jsr pc,(r5)
0004767, 0000074, // jsr pc,R000
0010402, // mov r4,r2
0162702, 0000004, // sub #000004,r2
0022702, 0000002, // cmp #000002,r2
0001441, // beq B007
0004767, 0000054, // jsr pc,R000
0061604, // add (sp),r4
0010401, // mov r4,r1
0004715, // B003: jsr pc,(r5)
0002004, // bge B005
0105700, // tstb r0
0001753, // beq B002
0000000, // B004: halt
0000751, // br B002
0110321, // B005: movb r3,(r1)+
0000770, // br B003
0016703, 0000152, // ldchr: mov p.prcs,r3
0105213, // incb (r3)
0105713, // B006: tstb (r3)
0100376, // bpl B006
0116303, 0000002, // movb 000002(r3),r3
0060300, // add r3,r0
0042703, 0177400, // bic #177400,r3
0005302, // dec r2
0000207, // rts pc
0012667, 0000046, // R000: mov (sp)+,D000
0004715, // jsr pc,(r5)
0010304, // mov r3,r4
0004715, // jsr pc,(r5)
0000303, // swap r3
0050304, // bis r3,r4
0016707, 0000030, // mov D000,pc
0004767, 0177752, // B007: jsr pc,R000
0004715, // jsr pc,(r5)
0105700, // tstb r0
0001342, // bne B004
0006204, // asr r4
0103002, // bcc B008
0000000, // halt
0000700, // br B000
0006304, // B008: asl r4
0061604, // add (sp),r4
0000114, // jmp (r4)
0000000, // D000: .word 000000
0012767, 0000352, 0000020, // L000: mov #000352,B009+2
0012767, 0000765, 0000034, // mov #000765,D001
0000167, 0177532, // jmp C000
0016701, 0000026, // bstart: mov p.prcs,r1
0012702, 0000352, // B009: mov #000352,r2
0005211, // inc (r1)
0105711, // B010: tstb (r1)
0100376, // bpl B010
0116162, 0000002, 0157400, // movb 000002(r1),157400(r2)
0005267, 0177756, // inc B009+2
0000765, // D001: br B009
0177550 // p.prcs: .word 177550
};
code.clear();
foreach_ (uint16_t& w, bootcode) code.push_back(w);
aload = kBOOT_START;
astart = kBOOT_START+2;
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlPC11::UnitSetup(size_t ind)
{
Rw11UnitPC11& unit = *fspUnit[ind];
SetOnline(ind, unit.Virt()); // online if stream attached
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlPC11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlPC11 @ " << this << endl;
os << bl << " fPC_pbuf: " << fPC_pbuf << endl;
 
Rw11CntlBase<Rw11UnitPC11,2>::Dump(os, ind, " ^");
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11CntlPC11::AttnHandler(RlinkServer::AttnArgs& args)
{
fStats.Inc(kStatNAttnHdl);
Server().GetAttnInfo(args, fPrimClist);
 
uint16_t pbuf = fPrimClist[fPC_pbuf].Data();
bool pval = pbuf & kPBUF_M_PVAL;
bool rbusy = pbuf & kPBUF_M_RBUSY;
uint8_t ochr = pbuf & kPBUF_M_BUF;
 
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
lmsg << "-I PC11." << Name()
<< " pbuf=" << RosPrintBvi(pbuf,8)
<< " pval=" << pval
<< " rbusy=" << rbusy;
if (pval) {
lmsg << " char=";
if (ochr>=040 && ochr<0177) {
lmsg << "'" << char(ochr) << "'";
} else {
lmsg << RosPrintBvi(ochr,8);
}
}
}
if (pval) {
RerrMsg emsg;
bool rc = fspUnit[kUnit_PP]->VirtWrite(&ochr, 1, emsg);
if (!rc) {
RlogMsg lmsg(LogFile());
lmsg << emsg;
SetOnline(1, false);
}
}
 
if (rbusy) {
uint8_t ichr = 0;
RerrMsg emsg;
int irc = fspUnit[kUnit_PR]->VirtRead(&ichr, 1, emsg);
if (irc < 0) {
RlogMsg lmsg(LogFile());
lmsg << emsg;
}
if (irc <= 0) {
SetOnline(0, false);
} else {
RlinkCommandList clist;
Cpu().AddWibr(clist, fBase+kRBUF, ichr);
Server().Exec(clist);
}
}
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlPC11::SetOnline(size_t ind, bool online)
{
Rw11Cpu& cpu = Cpu();
RlinkCommandList clist;
if (ind == kUnit_PR) { // reader on/offline
uint16_t rcsr = online ? 0 : kRCSR_M_ERROR;
cpu.AddWibr(clist, fBase+kRCSR, rcsr);
} else { // puncher on/offline
uint16_t pcsr = online ? 0 : kPCSR_M_ERROR;
cpu.AddWibr(clist, fBase+kPCSR, pcsr);
}
Server().Exec(clist);
return;
}
} // end namespace Retro
/Rw11CntlDL11.hpp
0,0 → 1,89
// $Id: Rw11CntlDL11.hpp 665 2015-04-07 07:13:49Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-29 623 1.1 adopt to Rlink V4 attn logic
// 2013-05-04 516 1.0.1 add RxRlim support (receive interrupt rate limit)
// 2013-03-06 495 1.0 Initial version
// 2013-02-05 483 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CntlDL11.hpp 665 2015-04-07 07:13:49Z mueller $
\brief Declaration of class Rw11CntlDL11.
*/
 
#ifndef included_Retro_Rw11CntlDL11
#define included_Retro_Rw11CntlDL11 1
 
#include "Rw11CntlBase.hpp"
#include "Rw11UnitDL11.hpp"
 
namespace Retro {
 
class Rw11CntlDL11 : public Rw11CntlBase<Rw11UnitDL11,1> {
public:
 
Rw11CntlDL11();
~Rw11CntlDL11();
 
void Config(const std::string& name, uint16_t base, int lam);
 
virtual void Start();
 
virtual void UnitSetup(size_t ind);
void Wakeup();
 
void SetRxRlim(uint16_t rlim);
uint16_t RxRlim() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kIbaddr = 0177560; //!< DL11 default address
static const int kLam = 1; //!< DL11 default lam
 
static const uint16_t kRCSR = 000; //!< RCSR reg offset
static const uint16_t kRBUF = 002; //!< RBUF reg offset
static const uint16_t kXCSR = 004; //!< XCSR reg offset
static const uint16_t kXBUF = 006; //!< XBUF reg offset
 
static const uint16_t kProbeOff = kRCSR; //!< probe address offset (rcsr)
static const bool kProbeInt = true; //!< probe int active
static const bool kProbeRem = true; //!< probr rem active
 
static const uint16_t kRCSR_M_RXRLIM = 0070000;
static const uint16_t kRCSR_V_RXRLIM = 12;
static const uint16_t kRCSR_B_RXRLIM = 007;
static const uint16_t kRCSR_M_RDONE = kWBit07;
static const uint16_t kXCSR_M_XRDY = kWBit07;
static const uint16_t kXBUF_M_RRDY = kWBit09;
static const uint16_t kXBUF_M_XVAL = kWBit08;
static const uint16_t kXBUF_M_XBUF = 0xff;
 
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
protected:
size_t fPC_xbuf; //!< PrimClist: xbuf index
uint16_t fRxRlim; //!< rx interrupt rate limit
};
} // end namespace Retro
 
//#include "Rw11CntlDL11.ipp"
 
#endif
/Rw11UnitVirt.ipp
0,0 → 1,120
// $Id: Rw11UnitVirt.ipp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-13 680 1.2 Attach(): check for Enabled()
// 2014-11-02 600 1.1.1 add (bool) cast, needed in 4.8.2
// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone()
// 2013-03-03 494 1.0 Initial version
// 2013-02-05 483 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitVirt.ipp 680 2015-05-14 13:29:46Z mueller $
\brief Implemenation (inline) of Rw11UnitVirt.
*/
 
#include "boost/thread/locks.hpp"
 
#include "librtools/RosFill.hpp"
 
#include "Rw11UnitVirt.hpp"
 
/*!
\class Retro::Rw11UnitVirt
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
template <class TV>
Rw11UnitVirt<TV>::Rw11UnitVirt(Rw11Cntl* pcntl, size_t index)
: Rw11Unit(pcntl, index),
fpVirt()
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
template <class TV>
Rw11UnitVirt<TV>::~Rw11UnitVirt()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TV>
inline TV* Rw11UnitVirt<TV>::Virt() const
{
return fpVirt.get();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TV>
inline bool Rw11UnitVirt<TV>::Attach(const std::string& url, RerrMsg& emsg)
{
// synchronize with server thread
boost::lock_guard<RlinkConnect> lock(Connect());
if (fpVirt) Detach();
if (!Enabled()) {
emsg.Init("Rw11UnitVirt::Attach","unit not enabled");
return false;
}
fpVirt.reset(TV::New(url, this, emsg));
if (fpVirt) AttachDone();
return (bool)fpVirt;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TV>
inline void Rw11UnitVirt<TV>::Detach()
{
// synchronize with server thread
boost::lock_guard<RlinkConnect> lock(Connect());
if (!fpVirt) return;
DetachCleanup();
fpVirt.reset();
DetachDone();
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TV>
void Rw11UnitVirt<TV>::Dump(std::ostream& os, int ind,
const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitVirt @ " << this << std::endl;
if (fpVirt) {
fpVirt->Dump(os, ind+2, "*fpVirt: ");
} else {
os << bl << " fpVirt: " << fpVirt.get() << std::endl;
}
Rw11Unit::Dump(os, ind, " ^");
return;
}
 
} // end namespace Retro
/Rw11Cpu.ipp
0,0 → 1,207
// $Id: Rw11Cpu.ipp 659 2015-03-22 23:15:51Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-03-21 659 1.2 add RAddrMap
// 2014-12-25 621 1.1 Adopt for 4k word ibus window; add IAddrMap
// 2013-04-12 504 1.0 Initial version
// 2013-01-27 478 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Cpu.ipp 659 2015-03-22 23:15:51Z mueller $
\brief Implemenation (inline) of Rw11Cpu.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11& Rw11Cpu::W11() const
{
return *fpW11;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkServer& Rw11Cpu::Server() const
{
return fpW11->Server();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkConnect& Rw11Cpu::Connect() const
{
return fpW11->Connect();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlogFile& Rw11Cpu::LogFile() const
{
return fpW11->LogFile();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const std::string& Rw11Cpu::Type() const
{
return fType;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11Cpu::Index() const
{
return fIndex;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11Cpu::Base() const
{
return fBase;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11Cpu::IBase() const
{
return fIBase;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11Cpu::CpuStat() const
{
return fCpuStat;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cpu::CpuGo() const
{
return fCpuGo;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11Cpu::IbusRemoteAddr(uint16_t ibaddr) const
{
return fIBase + (ibaddr & 017777)/2;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cpu::IAddrMapInsert(const std::string& name, uint16_t ibaddr)
{
return fIAddrMap.Insert(name, ibaddr);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cpu::IAddrMapErase(const std::string& name)
{
return fIAddrMap.Erase(name);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cpu::IAddrMapErase(uint16_t ibaddr)
{
return fIAddrMap.Erase(ibaddr);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11Cpu::IAddrMapClear()
{
return fIAddrMap.Clear();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const RlinkAddrMap& Rw11Cpu::IAddrMap() const
{
return fIAddrMap;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cpu::RAddrMapInsert(const std::string& name, uint16_t ibaddr)
{
return fRAddrMap.Insert(name, ibaddr);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cpu::RAddrMapErase(const std::string& name)
{
return fRAddrMap.Erase(name);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cpu::RAddrMapErase(uint16_t ibaddr)
{
return fRAddrMap.Erase(ibaddr);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11Cpu::RAddrMapClear()
{
return fRAddrMap.Clear();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const RlinkAddrMap& Rw11Cpu::RAddrMap() const
{
return fRAddrMap;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11Cpu::Stats() const
{
return fStats;
}
 
} // end namespace Retro
/Rw11UnitDisk.hpp
0,0 → 1,83
// $Id: Rw11UnitDisk.hpp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-03-21 659 1.0.2 add fEnabled, Enabled()
// 2015-02-18 647 1.0.1 add Nwrd2Nblk()
// 2013-04-19 507 1.0 Initial version
// 2013-02-19 490 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitDisk.hpp 680 2015-05-14 13:29:46Z mueller $
\brief Declaration of class Rw11UnitDisk.
*/
 
#ifndef included_Retro_Rw11UnitDisk
#define included_Retro_Rw11UnitDisk 1
 
#include "Rw11VirtDisk.hpp"
 
#include "Rw11UnitVirt.hpp"
 
namespace Retro {
 
class Rw11UnitDisk : public Rw11UnitVirt<Rw11VirtDisk> {
public:
Rw11UnitDisk(Rw11Cntl* pcntl, size_t index);
~Rw11UnitDisk();
 
virtual void SetType(const std::string& type);
 
const std::string& Type() const;
virtual bool Enabled() const;
size_t NCylinder() const;
size_t NHead() const;
size_t NSector() const;
size_t BlockSize() const;
size_t NBlock() const;
 
uint32_t Chs2Lba(uint16_t cy, uint16_t hd, uint16_t se);
void Lba2Chs(uint32_t lba, uint16_t& cy, uint16_t& hd,
uint16_t& se);
uint32_t Nwrd2Nblk(uint32_t nwrd);
 
void SetWProt(bool wprot);
bool WProt() const;
 
bool VirtRead(size_t lba, size_t nblk, uint8_t* data,
RerrMsg& emsg);
bool VirtWrite(size_t lba, size_t nblk, const uint8_t* data,
RerrMsg& emsg);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
std::string fType; //!< drive type
bool fEnabled; //!< unit enabled
size_t fNCyl; //!< # cylinder
size_t fNHead; //!< # heads (aka surfaces)
size_t fNSect; //!< # sectors
size_t fBlksize; //!< block size (in bytes)
size_t fNBlock; //!< # blocks
bool fWProt; //!< unit write protected
};
} // end namespace Retro
 
#include "Rw11UnitDisk.ipp"
 
#endif
/Rw11CntlLP11.hpp
0,0 → 1,76
// $Id: Rw11CntlLP11.hpp 665 2015-04-07 07:13:49Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-29 623 1.1 adopt to Rlink V4 attn logic
// 2013-05-01 513 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CntlLP11.hpp 665 2015-04-07 07:13:49Z mueller $
\brief Declaration of class Rw11CntlLP11.
*/
 
#ifndef included_Retro_Rw11CntlLP11
#define included_Retro_Rw11CntlLP11 1
 
#include "Rw11CntlBase.hpp"
#include "Rw11UnitLP11.hpp"
 
namespace Retro {
 
class Rw11CntlLP11 : public Rw11CntlBase<Rw11UnitLP11,1> {
public:
 
Rw11CntlLP11();
~Rw11CntlLP11();
 
void Config(const std::string& name, uint16_t base, int lam);
 
virtual void Start();
 
virtual void UnitSetup(size_t ind);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kIbaddr = 0177514; //!< LP11 default address
static const int kLam = 8; //!< LP11 default lam
 
static const uint16_t kCSR = 000; //!< CSR reg offset
static const uint16_t kBUF = 002; //!< BUF reg offset
 
static const uint16_t kProbeOff = kCSR; //!< probe address offset (rcsr)
static const bool kProbeInt = true; //!< probe int active
static const bool kProbeRem = true; //!< probr rem active
 
static const uint16_t kCSR_M_ERROR = kWBit15;
static const uint16_t kBUF_M_VAL = kWBit08;
static const uint16_t kBUF_M_BUF = 0177;
 
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
void SetOnline(bool online);
protected:
size_t fPC_buf; //!< PrimClist: buf index
};
} // end namespace Retro
 
//#include "Rw11CntlLP11.ipp"
 
#endif
/Rw11Unit.cpp
0,0 → 1,115
// $Id: Rw11Unit.cpp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-13 680 1.1.1 add Enabled()
// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone()
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Unit.cpp 680 2015-05-14 13:29:46Z mueller $
\brief Implemenation of Rw11Unit.
*/
 
#include "librtools/RosFill.hpp"
 
#include "Rw11Unit.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11Unit
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11Unit::Rw11Unit(Rw11Cntl* pcntl, size_t index)
: fpCntlBase(pcntl),
fIndex(index),
fAttachOpts(),
fStats()
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11Unit::~Rw11Unit()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Unit::Enabled() const
{
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Unit::Attach(const std::string& url, RerrMsg& emsg)
{
emsg.Init("Rw11Unit::Attach","attach not available for this device type");
return false;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Unit::Detach()
{
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Unit::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11Unit @ " << this << endl;
 
os << bl << " fIndex: " << fIndex << endl;
os << bl << " fAttachOpts: " << fAttachOpts << endl;
fStats.Dump(os, ind+2, "fStats: ");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Unit::AttachDone()
{}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Unit::DetachCleanup()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Unit::DetachDone()
{}
 
} // end namespace Retro
/Rw11UnitRHRP.hpp
0,0 → 1,68
// $Id: Rw11UnitRHRP.hpp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-14 680 1.0 Initial version
// 2015-03-21 659 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitRHRP.hpp 680 2015-05-14 13:29:46Z mueller $
\brief Declaration of class Rw11UnitRHRP.
*/
 
#ifndef included_Retro_Rw11UnitRHRP
#define included_Retro_Rw11UnitRHRP 1
 
#include "Rw11UnitDiskBase.hpp"
 
namespace Retro {
 
class Rw11CntlRHRP; // forw decl to avoid circular incl
 
class Rw11UnitRHRP : public Rw11UnitDiskBase<Rw11CntlRHRP> {
public:
Rw11UnitRHRP(Rw11CntlRHRP* pcntl, size_t index);
~Rw11UnitRHRP();
 
virtual void SetType(const std::string& type);
uint16_t Rpdt() const;
bool IsRmType() const;
 
void SetRpds(uint16_t rpds);
uint16_t Rpds() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kDTE_M_RM = kWBit02; //!< rm type flag
static const uint16_t kDTE_RP04 = 00; //!< drive type of RP04 rm=0
static const uint16_t kDTE_RP06 = 01; //!< drive type of RP06 rm=0
static const uint16_t kDTE_RM03 = 04; //!< drive type of RM03 rm=1
static const uint16_t kDTE_RM80 = 05; //!< drive type of RM80 rm=1
static const uint16_t kDTE_RM05 = 06; //!< drive type of RM05 rm=1
static const uint16_t kDTE_RP07 = 07; //!< drive type of RP07 rm=1
 
protected:
uint16_t fRpdt; //!< drive type (encoded)
uint16_t fRpds; //!< drive status
};
} // end namespace Retro
 
#include "Rw11UnitRHRP.ipp"
 
#endif
/Rw11CntlRHRP.hpp
0,0 → 1,221
// $Id: Rw11CntlRHRP.hpp 680 2015-05-14 13:29:46Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-05-14 680 1.0 Initial version
// 2015-03-21 659 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CntlRHRP.hpp 680 2015-05-14 13:29:46Z mueller $
\brief Declaration of class Rw11CntlRHRP.
*/
 
#ifndef included_Retro_Rw11CntlRHRP
#define included_Retro_Rw11CntlRHRP 1
 
#include "Rw11CntlBase.hpp"
#include "Rw11UnitRHRP.hpp"
#include "Rw11RdmaDisk.hpp"
 
namespace Retro {
 
class Rw11CntlRHRP : public Rw11CntlBase<Rw11UnitRHRP,4> {
public:
 
Rw11CntlRHRP();
~Rw11CntlRHRP();
 
void Config(const std::string& name, uint16_t base, int lam);
 
virtual void Start();
 
virtual bool BootCode(size_t unit, std::vector<uint16_t>& code,
uint16_t& aload, uint16_t& astart);
 
virtual void UnitSetup(size_t ind);
 
void SetChunkSize(size_t chunk);
size_t ChunkSize() const;
 
const Rstats& RdmaStats() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const uint16_t kIbaddr = 0176700; //!< RHRP default address
static const int kLam = 6; //!< RHRP default lam
 
static const uint16_t kRPCS1 = 000; //!< RPCS1 reg offset
static const uint16_t kRPWC = 002; //!< RPWC reg offset
static const uint16_t kRPBA = 004; //!< RPBA reg offset
static const uint16_t kRPDA = 006; //!< RPDA reg offset
static const uint16_t kRPCS2 = 010; //!< RPCS2 reg offset
static const uint16_t kRPDS = 012; //!< RPDS reg offset
static const uint16_t kRPER1 = 014; //!< RPER1 reg offset
static const uint16_t kRPAS = 016; //!< RPAS reg offset
static const uint16_t kRPLA = 020; //!< RPLA reg offset
static const uint16_t kRPDB = 022; //!< RPDB reg offset
static const uint16_t kRPMR1 = 024; //!< RPMR1 reg offset
static const uint16_t kRPDT = 026; //!< RPDT reg offset
static const uint16_t kRPSN = 030; //!< RPSN reg offset
static const uint16_t kRPOF = 032; //!< RPOF reg offset
static const uint16_t kRPDC = 034; //!< RPDC reg offset
static const uint16_t kRxM13 = 036; //!< MB reg 13 reg offset
static const uint16_t kRxM14 = 040; //!< MB reg 14 reg offset
static const uint16_t kRxM15 = 042; //!< MB reg 15 reg offset
static const uint16_t kRPEC1 = 044; //!< RPEC1 reg offset
static const uint16_t kRPEC2 = 046; //!< RPEC2 reg offset
static const uint16_t kRPBAE = 050; //!< RPBAE reg offset
static const uint16_t kRPCS3 = 052; //!< RPCS3 reg offset
 
static const uint16_t kProbeOff = kRPCS2;//!< probe address offset (rxcs2)
static const bool kProbeInt = true; //!< probe int active
static const bool kProbeRem = true; //!< probr rem active
 
static const uint16_t kRPCS1_M_SC = kWBit15;
static const uint16_t kRPCS1_M_TRE = kWBit14;
static const uint16_t kRPCS1_M_DVA = kWBit11;
static const uint16_t kRPCS1_M_BAE = 001400;
static const uint16_t kRPCS1_V_BAE = 8;
static const uint16_t kRPCS1_B_BAE = 0003;
static const uint16_t kRPCS1_M_RDY = kWBit07;
static const uint16_t kRPCS1_M_IE = kWBit06;
static const uint16_t kRPCS1_V_FUNC = 1;
static const uint16_t kRPCS1_B_FUNC = 0037;
static const uint16_t kRPCS1_M_GO = kWBit00;
 
// only function codes handled in backend are defined
static const uint16_t kFUNC_WCD = 024; //!< func: write chk data
static const uint16_t kFUNC_WCHD = 025; //!< func: write chk head&data
static const uint16_t kFUNC_WRITE = 030; //!< func: write
static const uint16_t kFUNC_WHD = 031; //!< func: write head&data
static const uint16_t kFUNC_READ = 034; //!< func: read
static const uint16_t kFUNC_RHD = 035; //!< func: read head&data
// remote function codes
static const uint16_t kRFUNC_WUNIT = 001; //!< rfunc: write runit
static const uint16_t kRFUNC_CUNIT = 002; //!< rfunc: copy funit->runit
static const uint16_t kRFUNC_DONE = 003; //!< rfunc: done (set rdy)
static const uint16_t kRFUNC_WIDLY = 004; //!< rfunc: write idly
 
// cs1 usage or rem func=wunit
static const uint16_t kRPCS1_V_RUNIT = 8;
static const uint16_t kRPCS1_B_RUNIT = 0003;
// cs1 usage or rem func=done
static const uint16_t kRPCS1_M_RATA = kWBit08;
// cs1 usage or rem func=widly
static const uint16_t kRPCS1_V_RIDLY = 8;
static const uint16_t kRPCS1_B_RIDLY = 0377;
 
static const uint16_t kRPDA_V_TA = 8;
static const uint16_t kRPDA_B_TA = 0037;
static const uint16_t kRPDA_B_SA = 0077;
 
static const uint16_t kRPCS2_M_RWCO = kWBit15;
static const uint16_t kRPCS2_M_WCE = kWBit14;
static const uint16_t kRPCS2_M_NED = kWBit12;
static const uint16_t kRPCS2_M_NEM = kWBit11;
static const uint16_t kRPCS2_M_PGE = kWBit10;
static const uint16_t kRPCS2_M_MXF = kWBit09;
static const uint16_t kRPCS2_M_OR = kWBit07;
static const uint16_t kRPCS2_M_IR = kWBit06;
static const uint16_t kRPCS2_M_CLR = kWBit05;
static const uint16_t kRPCS2_M_PAT = kWBit04;
static const uint16_t kRPCS2_M_BAI = kWBit03;
static const uint16_t kRPCS2_M_UNIT2 = kWBit02;
static const uint16_t kRPCS2_B_UNIT = 0003;
 
static const uint16_t kRPDS_M_ATA = kWBit15;
static const uint16_t kRPDS_M_ERP = kWBit14;
static const uint16_t kRPDS_M_MOL = kWBit12;
static const uint16_t kRPDS_M_WRL = kWBit11;
static const uint16_t kRPDS_M_LBT = kWBit10;
static const uint16_t kRPDS_M_DPR = kWBit08;
static const uint16_t kRPDS_M_DRY = kWBit07;
static const uint16_t kRPDS_M_VV = kWBit06;
static const uint16_t kRPDS_M_OM = kWBit00;
 
static const uint16_t kRPER1_M_UNS = kWBit14;
static const uint16_t kRPER1_M_WLE = kWBit11;
static const uint16_t kRPER1_M_IAE = kWBit10;
static const uint16_t kRPER1_M_AOE = kWBit09;
static const uint16_t kRPER1_M_RMR = kWBit02;
static const uint16_t kRPER1_M_ILF = kWBit00;
 
static const uint16_t kRPDC_B_CA = 01777;
 
static const uint16_t kRPCS3_M_IE = kWBit06;
static const uint16_t kRPCS3_M_RSEARDONE = kWBit03;
static const uint16_t kRPCS3_M_RPACKDONE = kWBit02;
static const uint16_t kRPCS3_M_RPOREDONE = kWBit01;
static const uint16_t kRPCS3_M_RSEEKDONE = kWBit00;
 
// statistics counter indices
enum stats {
kStatNFuncWchk = Rw11Cntl::kDimStat,
kStatNFuncWrite,
kStatNFuncRead,
kStatNFuncSear,
kStatNFuncPack,
kStatNFuncPore,
kStatNFuncSeek,
kDimStat
};
 
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
void RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
RlinkCommandList& clist);
void RdmaPostExecCB(int stat, size_t ndone,
RlinkCommandList& clist, size_t ncmd);
void AddErrorExit(RlinkCommandList& clist, uint16_t rper1);
void AddNormalExit(RlinkCommandList& clist, size_t ndone,
uint16_t rper1=0, uint16_t rpcs2=0);
 
protected:
size_t fPC_rpcs1; //!< PrimClist: rpcs1 index
size_t fPC_rpcs2; //!< PrimClist: rpcs2 index
size_t fPC_rpcs3; //!< PrimClist: rpcs3 index
size_t fPC_rpwc; //!< PrimClist: rpwc index
size_t fPC_rpba; //!< PrimClist: rpba index
size_t fPC_rpbae; //!< PrimClist: rpbae index
size_t fPC_cunit; //!< PrimClist: copy unit
size_t fPC_rpds; //!< PrimClist: rpds index
size_t fPC_rpda; //!< PrimClist: rpda index
size_t fPC_rpdc; //!< PrimClist: rpdc index
 
uint16_t fRd_rpcs1; //!< Rdma: request rpcs1
uint16_t fRd_rpcs2; //!< Rdma: request rpcs2
uint16_t fRd_rpcs3; //!< Rdma: request rpcs3
uint16_t fRd_rpwc; //!< Rdma: request rpwc
uint16_t fRd_rpba; //!< Rdma: request rpba
uint16_t fRd_rpbae; //!< Rdma: request rpbae
uint16_t fRd_rpds; //!< Rdma: request rpds
uint16_t fRd_rpda; //!< Rdma: request rpda
uint16_t fRd_rpdc; //!< Rdma: request rpdc
uint32_t fRd_addr; //!< Rdma: current addr
uint32_t fRd_lba; //!< Rdma: current lba
uint32_t fRd_nwrd; //!< Rdma: current nwrd
uint16_t fRd_fu; //!< Rdma: request fu code
bool fRd_ovr; //!< Rdma: overrun condition found
Rw11RdmaDisk fRdma; //!< Rdma controller
};
} // end namespace Retro
 
#include "Rw11CntlRHRP.ipp"
 
#endif
/Rw11UnitRK11.cpp
0,0 → 1,79
// $Id: Rw11UnitRK11.cpp 659 2015-03-22 23:15:51Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-04-20 508 1.0 Initial version
// 2013-02-05 483 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitRK11.cpp 659 2015-03-22 23:15:51Z mueller $
\brief Implemenation of Rw11UnitRK11.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/RosFill.hpp"
#include "Rw11CntlRK11.hpp"
 
#include "Rw11UnitRK11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitRK11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitRK11::Rw11UnitRK11(Rw11CntlRK11* pcntl, size_t index)
: Rw11UnitDiskBase<Rw11CntlRK11>(pcntl, index),
fRkds(0)
{
// setup disk geometry: only rk05 supported, no rk05f !
fType = "rk05";
fEnabled = true;
fNCyl = 203;
fNHead = 2;
fNSect = 12;
fBlksize = 512;
fNBlock = fNCyl*fNHead*fNSect;
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitRK11::~Rw11UnitRK11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitRK11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitRK11 @ " << this << endl;
os << bl << " fRkds: " << fRkds << endl;
 
Rw11UnitDiskBase<Rw11CntlRK11>::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11CntlDL11.cpp
0,0 → 1,264
// $Id: Rw11CntlDL11.cpp 659 2015-03-22 23:15:51Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-30 625 1.2 adopt to Rlink V4 attn logic
// 2014-12-25 621 1.1 adopt to 4k word ibus window and
// 2013-05-04 516 1.0.2 add RxRlim support (receive interrupt rate limit)
// 2013-04-20 508 1.0.1 add trace support
// 2013-03-06 495 1.0 Initial version
// 2013-02-05 483 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlDL11.cpp 659 2015-03-22 23:15:51Z mueller $
\brief Implemenation of Rw11CntlDL11.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintBvi.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
#include "librtools/RlogMsg.hpp"
 
#include "Rw11CntlDL11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11CntlDL11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint16_t Rw11CntlDL11::kIbaddr;
const int Rw11CntlDL11::kLam;
 
const uint16_t Rw11CntlDL11::kRCSR;
const uint16_t Rw11CntlDL11::kRBUF;
const uint16_t Rw11CntlDL11::kXCSR;
const uint16_t Rw11CntlDL11::kXBUF;
 
const uint16_t Rw11CntlDL11::kProbeOff;
const bool Rw11CntlDL11::kProbeInt;
const bool Rw11CntlDL11::kProbeRem;
 
const uint16_t Rw11CntlDL11::kRCSR_M_RXRLIM;
const uint16_t Rw11CntlDL11::kRCSR_V_RXRLIM;
const uint16_t Rw11CntlDL11::kRCSR_B_RXRLIM;
const uint16_t Rw11CntlDL11::kRCSR_M_RDONE;
const uint16_t Rw11CntlDL11::kXCSR_M_XRDY;
const uint16_t Rw11CntlDL11::kXBUF_M_RRDY;
const uint16_t Rw11CntlDL11::kXBUF_M_XVAL;
const uint16_t Rw11CntlDL11::kXBUF_M_XBUF;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11CntlDL11::Rw11CntlDL11()
: Rw11CntlBase<Rw11UnitDL11,1>("dl11"),
fPC_xbuf(0),
fRxRlim(0)
{
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
for (size_t i=0; i<NUnit(); i++) {
fspUnit[i].reset(new Rw11UnitDL11(this, i));
}
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11CntlDL11::~Rw11CntlDL11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlDL11::Config(const std::string& name, uint16_t base, int lam)
{
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlDL11::Start()
{
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
throw Rexception("Rw11CntlDL11::Start",
"Bad state: started, no lam, not enable, not found");
// add device register address ibus and rbus mappings
// done here because now Cntl bound to Cpu and Cntl probed
Cpu().AllIAddrMapInsert(Name()+".rcsr", Base() + kRCSR);
Cpu().AllIAddrMapInsert(Name()+".rbuf", Base() + kRBUF);
Cpu().AllIAddrMapInsert(Name()+".xcsr", Base() + kXCSR);
Cpu().AllIAddrMapInsert(Name()+".xbuf", Base() + kXBUF);
 
// setup primary info clist
fPrimClist.Clear();
fPrimClist.AddAttn();
fPC_xbuf = Cpu().AddRibr(fPrimClist, fBase+kXBUF);
 
// add attn handler
Server().AddAttnHandler(boost::bind(&Rw11CntlDL11::AttnHandler, this, _1),
uint16_t(1)<<fLam, (void*)this);
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlDL11::UnitSetup(size_t ind)
{
Rw11Cpu& cpu = Cpu();
uint16_t rcsr = (fRxRlim<<kRCSR_V_RXRLIM) & kRCSR_M_RXRLIM;
RlinkCommandList clist;
cpu.AddWibr(clist, fBase+kRCSR, rcsr);
Server().Exec(clist);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlDL11::Wakeup()
{
if (!fspUnit[0]->RcvQueueEmpty()) {
RlinkCommandList clist;
size_t ircsr = Cpu().AddRibr(clist, fBase+kRCSR);
Server().Exec(clist);
uint16_t rcsr = clist[ircsr].Data();
if ((rcsr & kRCSR_M_RDONE) == 0) { // RBUF not full
uint8_t ichr = fspUnit[0]->RcvNext();
clist.Clear();
Cpu().AddWibr(clist, fBase+kRBUF, ichr);
Server().Exec(clist);
}
}
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlDL11::SetRxRlim(uint16_t rlim)
{
if (rlim > kRCSR_B_RXRLIM)
throw Rexception("Rw11CntlDL11::SetRxRlim","Bad args: rlim too large");
 
fRxRlim = rlim;
UnitSetup(0);
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
uint16_t Rw11CntlDL11::RxRlim() const
{
return fRxRlim;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CntlDL11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlDL11 @ " << this << endl;
os << bl << " fPC_xbuf: " << fPC_xbuf << endl;
os << bl << " fRxRlim: " << fRxRlim << endl;
 
Rw11CntlBase<Rw11UnitDL11,1>::Dump(os, ind, " ^");
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11CntlDL11::AttnHandler(RlinkServer::AttnArgs& args)
{
fStats.Inc(kStatNAttnHdl);
Server().GetAttnInfo(args, fPrimClist);
 
uint16_t xbuf = fPrimClist[fPC_xbuf].Data();
 
uint8_t ochr = xbuf & kXBUF_M_XBUF;
bool xval = xbuf & kXBUF_M_XVAL;
bool rrdy = xbuf & kXBUF_M_RRDY;
 
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile());
lmsg << "-I DL11." << Name()
<< " xbuf=" << RosPrintBvi(xbuf,8)
<< " xval=" << xval
<< " rrdy=" << rrdy
<< " rcvq=" << RosPrintf(fspUnit[0]->RcvQueueSize(),"d",3);
if (xval) {
lmsg << " char=";
if (ochr>=040 && ochr<0177) {
lmsg << "'" << char(ochr) << "'";
} else {
lmsg << RosPrintBvi(ochr,8);
lmsg << " " << ((ochr&0200) ? "|" : " ");
uint8_t ochr7 = ochr & 0177;
if (ochr7 < 040) {
switch (ochr7) {
case 010: lmsg << "BS"; break;
case 011: lmsg << "HT"; break;
case 012: lmsg << "LF"; break;
case 013: lmsg << "VT"; break;
case 014: lmsg << "FF"; break;
case 015: lmsg << "CR"; break;
default: lmsg << "^" << char('A'+ochr7);
}
} else {
if (ochr7 < 0177) {
lmsg << "'" << char(ochr7) << "'";
} else {
lmsg << "DEL";
}
}
}
}
}
 
if (xval) {
fspUnit[0]->Snd(&ochr, 1);
}
 
if (rrdy && !fspUnit[0]->RcvQueueEmpty()) {
uint8_t ichr = fspUnit[0]->RcvNext();
RlinkCommandList clist;
Cpu().AddWibr(clist, fBase+kRBUF, ichr);
Server().Exec(clist);
}
 
return 0;
}
 
} // end namespace Retro
/Rw11UnitRL11.hpp
0,0 → 1,58
// $Id: Rw11UnitRL11.hpp 653 2015-03-01 12:53:01Z mueller $
//
// Copyright 2014- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-06-08 561 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitRL11.hpp 653 2015-03-01 12:53:01Z mueller $
\brief Declaration of class Rw11UnitRL11.
*/
 
#ifndef included_Retro_Rw11UnitRL11
#define included_Retro_Rw11UnitRL11 1
 
#include "Rw11UnitDiskBase.hpp"
 
namespace Retro {
 
class Rw11CntlRL11; // forw decl to avoid circular incl
 
class Rw11UnitRL11 : public Rw11UnitDiskBase<Rw11CntlRL11> {
public:
Rw11UnitRL11(Rw11CntlRL11* pcntl, size_t index);
~Rw11UnitRL11();
 
virtual void SetType(const std::string& type);
 
void SetRlsta(uint16_t rlsta);
void SetRlpos(uint16_t rlpos);
uint16_t Rlsta() const;
uint16_t Rlpos() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
uint16_t fRlsta;
uint16_t fRlpos;
};
} // end namespace Retro
 
#include "Rw11UnitRL11.ipp"
 
#endif
/Rw11RdmaDisk.hpp
0,0 → 1,87
// $Id: Rw11RdmaDisk.hpp 648 2015-02-20 20:16:21Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-01-04 627 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11RdmaDisk.hpp 648 2015-02-20 20:16:21Z mueller $
\brief Declaration of class Rw11RdmaDisk.
*/
 
#ifndef included_Retro_Rw11RdmaDisk
#define included_Retro_Rw11RdmaDisk 1
 
#include <vector>
 
#include "Rw11Rdma.hpp"
#include "Rw11UnitDisk.hpp"
 
namespace Retro {
 
class Rw11RdmaDisk : public Rw11Rdma {
public:
Rw11RdmaDisk(Rw11Cntl* pcntl, const precb_t& precb,
const postcb_t& postcb);
~Rw11RdmaDisk();
 
void QueueDiskRead(uint32_t addr, size_t size, uint16_t mode,
uint32_t lba, Rw11UnitDisk* punit);
void QueueDiskWrite(uint32_t addr, size_t size, uint16_t mode,
uint32_t lba, Rw11UnitDisk* punit);
void QueueDiskWriteCheck(uint32_t addr, size_t size,
uint16_t mode, uint32_t lba,
Rw11UnitDisk* punit);
 
size_t WriteCheck(size_t nwdone);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// statistics counter indices
enum stats {
kStatNWritePadded = Rw11Rdma::kDimStat,//!< padded disk write
kStatNWChkFail, //!< write check failed
kDimStat
};
protected:
// function code values
enum func {
kFuncRead, //!< read function
kFuncWrite, //!< write function
kFuncWriteCheck //!< write check function
};
 
void SetupDisk(size_t size, uint32_t lba, Rw11UnitDisk* punit,
Rw11RdmaDisk::func func);
virtual void PreRdmaHook();
virtual void PostRdmaHook(size_t nwdone);
 
protected:
std::vector<uint16_t> fBuf; //!< data buffer
Rw11UnitDisk* fpUnit; //!< UnitDisk to read VirtDisk
size_t fNWord; //!< words to transfer
size_t fNBlock; //!< disk blocks to transfer
size_t fLba; //!< disk lba
enum func fFunc; //!< current function
};
} // end namespace Retro
 
#include "Rw11RdmaDisk.ipp"
 
#endif
/Rw11Rdma.cpp
0,0 → 1,236
// $Id: Rw11Rdma.cpp 648 2015-02-20 20:16:21Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-02-17 647 1.1 PreExecCB with nwdone and nwnext
// 2015-01-04 627 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Rdma.cpp 648 2015-02-20 20:16:21Z mueller $
\brief Implemenation of Rw11Rdma.
*/
 
#include <algorithm>
 
#include "boost/bind.hpp"
 
#include "librtools/Rexception.hpp"
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/RosPrintBvi.hpp"
 
#include "Rw11Rdma.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11Rdma
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11Rdma::Rw11Rdma(Rw11Cntl* pcntl, const precb_t& precb,
const postcb_t& postcb)
: fpCntlBase(pcntl),
fPreExecCB(precb),
fPostExecCB(postcb),
fChunksize(0),
fStatus(kStatusDone),
fIsWMem(false),
fAddr(0),
fMode(0),
fNWordMax(0),
fNWordRest(0),
fNWordDone(0),
fpBlock(nullptr),
fStats()
{
fStats.Define(kStatNQueRMem, "NQueRMem" , "RMem chains queued");
fStats.Define(kStatNQueWMem, "NQueWMem" , "WMem chains queued");
fStats.Define(kStatNRdmaRMem, "NRdmaRMem" , "RMem chunks done");
fStats.Define(kStatNRdmaWMem, "NRdmaWMem" , "WMem chunks done");
fStats.Define(kStatNExtClist, "NExtClist" , "clist extended");
fStats.Define(kStatNFailRdma, "NFailRdma" , "Rdma failures");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11Rdma::~Rw11Rdma()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Rdma::SetChunkSize(size_t chunk)
{
size_t cmax = CntlBase().IsStarted() ? Connect().BlockSizePrudent() : 0;
if (chunk==0 || chunk>cmax) chunk = cmax;
fChunksize = chunk;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Rdma::QueueRMem(uint32_t addr, uint16_t* block, size_t size,
uint16_t mode)
{
fStats.Inc(kStatNQueRMem);
SetupRdma(false, addr, block, size, mode);
Server().QueueAction(boost::bind(&Rw11Rdma::RdmaHandler, this));
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Rdma::QueueWMem(uint32_t addr, const uint16_t* block, size_t size,
uint16_t mode)
{
fStats.Inc(kStatNQueWMem);
SetupRdma(true, addr, const_cast<uint16_t*>(block), size, mode);
Server().QueueAction(boost::bind(&Rw11Rdma::RdmaHandler, this));
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Rdma::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11Rdma @ " << this << endl;
 
os << bl << " fChunkSize: " << RosPrintf(fChunksize,"d",4) << endl;
os << bl << " fStatus: " << fStatus << endl;
os << bl << " fIsWMem: " << fIsWMem << endl;
os << bl << " fAddr: " << RosPrintBvi(fAddr,8,22) << endl;
os << bl << " fMode: " << RosPrintBvi(fAddr,16,16) << endl;
os << bl << " fNWordMax: " << RosPrintf(fNWordMax,"d",4) << endl;
os << bl << " fNWordRest: " << RosPrintf(fNWordRest,"d",4) << endl;
os << bl << " fNWordDone: " << RosPrintf(fNWordDone,"d",4) << endl;
os << bl << " fpBlock: " << fpBlock << endl;
fStats.Dump(os, ind+2, "fStats: ");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Rdma::SetupRdma(bool iswmem, uint32_t addr, uint16_t* block,
size_t size, uint16_t mode)
{
if (IsActive())
throw Rexception("Rw11Rdma::SetupRdma", "Bad state: Rdma already active");
// if chunk size not yet defined use 'maximal prudent size from Connect
// Note: can't be done in ctor because linkage to Connect is set much
// later in Cntl::Start
if (fChunksize == 0) fChunksize = Connect().BlockSizePrudent();
 
fStatus = kStatusBusy;
fIsWMem = iswmem;
fAddr = addr;
fMode = mode;
fNWordMax = fChunksize;
fNWordRest = size;
fNWordDone = 0;
fpBlock = block;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11Rdma::RdmaHandler()
{
RlinkCommandList clist;
 
if (fNWordDone == 0) { // first chunk ?
PreRdmaHook();
}
 
size_t nwnext = min(fNWordRest, fNWordMax);
if (fIsWMem) {
fStats.Inc(kStatNRdmaWMem);
Cpu().AddWMem(clist, fAddr, fpBlock, nwnext, fMode, true);
} else {
fStats.Inc(kStatNRdmaRMem);
Cpu().AddRMem(clist, fAddr, fpBlock, nwnext, fMode, true);
}
size_t ncmd = clist.Size();
if (nwnext == fNWordRest) fStatus = kStatusBusyLast;
fPreExecCB(fStatus, fNWordDone, nwnext, clist);
if (clist.Size() != ncmd) fStats.Inc(kStatNExtClist);
 
Server().Exec(clist);
 
size_t nwdone = clist[ncmd-1].BlockDone();
fAddr += 2*nwdone;
fNWordRest -= nwdone;
fNWordDone += nwdone;
fpBlock += nwdone;
 
bool islast = false;
if (nwnext != nwdone) {
fStats.Inc(kStatNFailRdma);
fStatus = kStatusFailRdma;
islast = true;
} else if (fNWordRest == 0) {
fStatus = kStatusDone;
islast = true;
}
 
if (islast) {
PostRdmaHook(fNWordDone);
}
 
fPostExecCB(fStatus, fNWordDone, clist, ncmd);
 
if (fStatus == kStatusBusy) {
return 1;
}
fStatus = kStatusDone;
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Rdma::PreRdmaHook()
{
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Rdma::PostRdmaHook(size_t nwdone)
{
return;
}
 
} // end namespace Retro
/Rw11VirtTermTcp.cpp
0,0 → 1,434
// $Id: Rw11VirtTermTcp.cpp 632 2015-01-11 12:30:03Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-08-22 584 1.0.4 use nullptr
// 2013-05-17 512 1.0.3 use Rtools::String2Long
// 2013-05-05 516 1.0.2 fix mistakes in emsg generation with errno
// 2013-04-20 508 1.0.1 add fSndPreConQue handling
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTermTcp.cpp 632 2015-01-11 12:30:03Z mueller $
\brief Implemenation of Rw11VirtTermTcp.
*/
 
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
 
#include <sstream>
 
#include "librtools/RosFill.hpp"
#include "librtools/RlogMsg.hpp"
 
#include "Rw11VirtTermTcp.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11VirtTermTcp
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const uint8_t Rw11VirtTermTcp::kCode_NULL;
const uint8_t Rw11VirtTermTcp::kCode_LF;
const uint8_t Rw11VirtTermTcp::kCode_CR;
const uint8_t Rw11VirtTermTcp::kCode_ESC;
const uint8_t Rw11VirtTermTcp::kCode_SE;
const uint8_t Rw11VirtTermTcp::kCode_NOP;
const uint8_t Rw11VirtTermTcp::kCode_IP;
const uint8_t Rw11VirtTermTcp::kCode_GA;
const uint8_t Rw11VirtTermTcp::kCode_SB;
const uint8_t Rw11VirtTermTcp::kCode_WILL;
const uint8_t Rw11VirtTermTcp::kCode_WONT;
const uint8_t Rw11VirtTermTcp::kCode_DO;
const uint8_t Rw11VirtTermTcp::kCode_DONT;
const uint8_t Rw11VirtTermTcp::kCode_IAC;
 
const uint8_t Rw11VirtTermTcp::kOpt_BIN;
const uint8_t Rw11VirtTermTcp::kOpt_ECHO;
const uint8_t Rw11VirtTermTcp::kOpt_SGA;
const uint8_t Rw11VirtTermTcp::kOpt_TTYP;
const uint8_t Rw11VirtTermTcp::kOpt_LINE;
 
const size_t Rw11VirtTermTcp::kPreConQue_limit;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11VirtTermTcp::Rw11VirtTermTcp(Rw11Unit* punit)
: Rw11VirtTerm(punit),
fFdListen(-1),
fFd(-1),
fState(ts_Closed),
fTcpTrace(false),
fSndPreConQue()
{
fStats.Define(kStatNVTPreConSave , "NVTPreConSave" ,
"VT snd bytes saved prior connect");
fStats.Define(kStatNVTPreConDrop , "NVTPreConDrop" ,
"VT snd bytes dropped prior connect");
fStats.Define(kStatNVTListenPoll , "NVTListenPoll" ,
"VT ListenPollHandler() calls");
fStats.Define(kStatNVTAccept, "NVTAccept", "VT socket accepts");
fStats.Define(kStatNVTRcvRaw, "NVTRcvRaw", "VT raw bytes received");
fStats.Define(kStatNVTSndRaw, "NVTSndRaw", "VT raw bytes send");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11VirtTermTcp::~Rw11VirtTermTcp()
{
if (fFdListen > 2) {
Server().RemovePollHandler(fFdListen);
close(fFdListen);
}
if (Connected()) {
Server().RemovePollHandler(fFd);
close(fFd);
}
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTermTcp::Open(const std::string& url, RerrMsg& emsg)
{
if (!fUrl.Set(url, "|port=|trace|", emsg)) return false;
if (!(fUrl.FindOpt("port"))) {
emsg.Init("Rw11VirtTermTcp::Open", "port= option not specified");
return false;
}
 
fTcpTrace = fUrl.FindOpt("trace");
 
string port;
fUrl.FindOpt("port",port);
unsigned long portno;
if (!Rtools::String2Long(port, portno, emsg)) return false;
 
protoent* pe = getprotobyname("tcp");
if (pe == nullptr) {
emsg.Init("Rw11VirtTermTcp::Open","getprotobyname(\"tcp\") failed");
return false;
}
 
int fd = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, pe->p_proto);
if (fd < 0) {
emsg.InitErrno("Rw11VirtTermTcp::Open","socket() failed: ", errno);
return false;
}
 
int on = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
emsg.InitErrno("Rw11VirtTermTcp::Open","setsockop() failed: ", errno);
close(fd);
return false;
}
 
sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons((unsigned short) portno);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
 
// Note: ::bind needed below to avoid collision with std::bind...
if (::bind(fd, (sockaddr*) &sa, sizeof(sa)) < 0) {
emsg.InitErrno("Rw11VirtTermTcp::Open","bind() failed: ", errno);
close(fd);
return false;
}
 
if (listen(fd, 1) <0) {
emsg.InitErrno("Rw11VirtTermTcp::Open","listen() failed: ", errno);
close(fd);
return false;
}
 
fFdListen = fd;
fChannelId = port;
fState = ts_Listen;
 
if (fTcpTrace) {
RlogMsg lmsg(LogFile(),'I');
lmsg << "TermTcp: listen on " << fChannelId << " for " << Unit().Name();
}
 
Server().AddPollHandler(boost::bind(&Rw11VirtTermTcp::ListenPollHandler,
this, _1),
fFdListen, POLLIN);
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTermTcp::Snd(const uint8_t* data, size_t count, RerrMsg& emsg)
{
fStats.Inc(kStatNVTSnd);
const uint8_t* pdata = data;
const uint8_t* pdataend = data+count;
if (count == 0) return true; // quit if nothing to do
 
if (!Connected()) { // if not connected keep last chars
for (size_t i=0; i<count; i++) fSndPreConQue.push_back(data[i]);
fStats.Inc(kStatNVTPreConSave, double(count));
while (fSndPreConQue.size() > kPreConQue_limit) {
fSndPreConQue.pop_front();
fStats.Inc(kStatNVTPreConDrop);
}
return true;
}
 
uint8_t obuf[1024];
while (pdata < pdataend) {
uint8_t* pobuf = obuf;
uint8_t* pobufend = obuf+1024;
while (pdata < pdataend && pobuf < pobufend-1) {
if (*pdata == kCode_IAC) *pobuf++ = kCode_IAC;
*pobuf++ = *pdata++;
}
 
int irc = write(fFd, obuf, pobuf-obuf);
if (irc < 0) {
RlogMsg lmsg(LogFile(),'E');
RerrMsg emsg("Rw11VirtTermTcp::Snd",
string("write() for port ") + fChannelId + " failed: ",
errno);
lmsg << emsg;
} else {
fStats.Inc(kStatNVTSndRaw, double(irc));
}
}
 
fStats.Inc(kStatNVTSndByt, double(count));
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtTermTcp::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11VirtTermTcp @ " << this << endl;
 
os << bl << " fFdListen: " << fFdListen << endl;
os << bl << " fFd: " << fFd << endl;
const char* t_state = "";
switch (fState) {
case ts_Closed: t_state = "ts_Closed"; break;
case ts_Listen: t_state = "ts_Listen"; break;
case ts_Stream: t_state = "ts_Stream"; break;
case ts_Iac: t_state = "ts_Iac"; break;
case ts_Cmd: t_state = "ts_Cmd"; break;
case ts_Subneg: t_state = "ts_Subneg"; break;
case ts_Subiac: t_state = "ts_Subiac"; break;
default: t_state = "???";
}
os << bl << " fState: " << t_state << endl;
os << bl << " fTcpTrace: " << fTcpTrace << endl;
os << bl << " fSndPreConQue.size" << fSndPreConQue.size() << endl;
Rw11VirtTerm::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11VirtTermTcp::ListenPollHandler(const pollfd& pfd)
{
// bail-out and cancel handler if poll returns an error event
if (pfd.revents & (~pfd.events)) return -1;
 
fFd = accept(fFdListen, nullptr, 0);
 
if (fFd < 0) {
RlogMsg lmsg(LogFile(),'E');
RerrMsg emsg("Rw11VirtTermTcp::ListenPollHandler",
string("accept() for port ") + fChannelId + " failed: ",
errno);
lmsg << emsg;
// FIXME_code: proper error handling
return 0;
}
 
fStats.Inc(kStatNVTAccept);
 
uint8_t buf_1[3] = {kCode_IAC, kCode_WILL, kOpt_LINE};
uint8_t buf_2[3] = {kCode_IAC, kCode_WILL, kOpt_SGA};
uint8_t buf_3[3] = {kCode_IAC, kCode_WILL, kOpt_ECHO};
uint8_t buf_4[3] = {kCode_IAC, kCode_WILL, kOpt_BIN};
uint8_t buf_5[3] = {kCode_IAC, kCode_DO , kOpt_BIN};
 
int nerr = 0;
 
// send initial negotiation WILLs and DOs
if (write(fFd, buf_1, sizeof(buf_1)) < 0) nerr += 1;
if (write(fFd, buf_2, sizeof(buf_2)) < 0) nerr += 1;
if (write(fFd, buf_3, sizeof(buf_3)) < 0) nerr += 1;
if (write(fFd, buf_4, sizeof(buf_4)) < 0) nerr += 1;
if (write(fFd, buf_5, sizeof(buf_5)) < 0) nerr += 1;
 
// send connect message
if (nerr==0) {
stringstream msg;
msg << "\r\nconnect on port " << fChannelId
<< " for " << Unit().Name() << "\r\n\r\n";
string str = msg.str();
if (write(fFd, str.c_str(), str.length()) < 0) nerr += 1;
}
 
// send chars buffered while attached but not connected
if (nerr==0 && fSndPreConQue.size()) {
stringstream msg;
while (!fSndPreConQue.empty()) {
msg << char(fSndPreConQue.front());
fSndPreConQue.pop_front();
}
string str = msg.str();
if (write(fFd, str.c_str(), str.length()) < 0) nerr += 1;
}
 
if (nerr) {
close(fFd);
fFd = -1;
RlogMsg lmsg(LogFile(),'E');
RerrMsg emsg("Rw11VirtTermTcp::ListenPollHandler",
string("initial write()s for port ") + fChannelId +
" failed: ", errno);
lmsg << emsg;
return 0;
}
 
if (fTcpTrace) {
RlogMsg lmsg(LogFile(),'I');
lmsg << "TermTcp: accept on " << fChannelId << " for " << Unit().Name();
}
 
fState = ts_Stream;
 
Server().RemovePollHandler(fFdListen);
Server().AddPollHandler(boost::bind(&Rw11VirtTermTcp::RcvPollHandler,
this, _1),
fFd, POLLIN);
return 0;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11VirtTermTcp::RcvPollHandler(const pollfd& pfd)
{
fStats.Inc(kStatNVTRcvPoll);
 
int irc = -1;
 
if (pfd.revents & POLLIN) {
uint8_t ibuf[1024];
uint8_t obuf[1024];
uint8_t* pobuf = obuf;
 
irc = read(fFd, ibuf, 1024);
 
if (irc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) return 0;
 
if (irc > 0) {
fStats.Inc(kStatNVTRcvRaw, double(irc));
for (int i=0; i<irc; i++) {
uint8_t byt = ibuf[i];
switch (fState) {
case ts_Stream:
if (byt == kCode_IAC) {
fState = ts_Iac;
} else {
*pobuf++ = byt;
fStats.Inc(kStatNVTRcvByt, 1.);
}
break;
 
case ts_Iac:
if (byt == kCode_WILL || byt == kCode_WONT ||
byt == kCode_DO || byt == kCode_DONT) {
fState = ts_Cmd;
} else if (byt == kCode_SB) {
fState = ts_Subneg;
} else {
fState = ts_Stream;
}
break;
 
case ts_Cmd:
fState = ts_Stream;
break;
 
case ts_Subneg:
if (byt == kCode_IAC) {
fState = ts_Subiac;
}
break;
 
case ts_Subiac:
fState = ts_Stream;
break;
default:
break;
}
 
}
}
 
if (pobuf > obuf) fRcvCb(obuf, pobuf - obuf);
}
 
 
if (irc <= 0) {
if (irc < 0) {
RlogMsg lmsg(LogFile(),'E');
RerrMsg emsg("Rw11VirtTermTcp::ListenPollHandler",
string("read() for port ") + fChannelId + " failed: ",
errno);
lmsg << emsg;
}
if (fTcpTrace) {
RlogMsg lmsg(LogFile(),'I');
lmsg << "TermTcp: close on " << fChannelId << " for " << Unit().Name();
}
close(fFd);
fFd = -1;
Server().AddPollHandler(boost::bind(&Rw11VirtTermTcp::ListenPollHandler,
this, _1),
fFdListen, POLLIN);
fState = ts_Listen;
return -1;
}
 
return 0;
}
 
} // end namespace Retro
/Rw11UnitRL11.ipp
0,0 → 1,69
// $Id: Rw11UnitRL11.ipp 653 2015-03-01 12:53:01Z mueller $
//
// Copyright 2014- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-06-08 561 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitRL11.ipp 653 2015-03-01 12:53:01Z mueller $
\brief Implemenation (inline) of Rw11UnitRL11.
*/
 
#include "Rw11UnitRL11.hpp"
 
/*!
\class Retro::Rw11UnitRL11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitRL11::SetRlsta(uint16_t rlsta)
{
fRlsta = rlsta;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitRL11::SetRlpos(uint16_t rlpos)
{
fRlpos = rlpos;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11UnitRL11::Rlsta() const
{
return fRlsta;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11UnitRL11::Rlpos() const
{
return fRlpos;
}
 
} // end namespace Retro
/Rw11RdmaDisk.cpp
0,0 → 1,208
// $Id: Rw11RdmaDisk.cpp 648 2015-02-20 20:16:21Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-01-04 628 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11RdmaDisk.cpp 648 2015-02-20 20:16:21Z mueller $
\brief Implemenation of Rw11RdmaDisk.
*/
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
 
#include "Rw11RdmaDisk.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11RdmaDisk
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11RdmaDisk::Rw11RdmaDisk(Rw11Cntl* pcntl, const precb_t& precb,
const postcb_t& postcb)
: Rw11Rdma(pcntl, precb, postcb),
fBuf(),
fpUnit(nullptr),
fNWord(0),
fNBlock(0),
fLba()
{
fStats.Define(kStatNWritePadded, "NWritePadded" , "padded disk write");
fStats.Define(kStatNWChkFail, "NWChkFail" , "write check failed");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11RdmaDisk::~Rw11RdmaDisk()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::QueueDiskRead(uint32_t addr, size_t size, uint16_t mode,
uint32_t lba, Rw11UnitDisk* punit)
{
SetupDisk(size, lba, punit, kFuncRead);
QueueWMem(addr, fBuf.data(), size, mode);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::QueueDiskWrite(uint32_t addr,size_t size, uint16_t mode,
uint32_t lba, Rw11UnitDisk* punit)
{
SetupDisk(size, lba, punit, kFuncWrite);
QueueRMem(addr, fBuf.data(), size, mode);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::QueueDiskWriteCheck(uint32_t addr, size_t size,
uint16_t mode, uint32_t lba,
Rw11UnitDisk* punit)
{
SetupDisk(size, lba, punit, kFuncWriteCheck);
QueueRMem(addr, fBuf.data(), size, mode);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
size_t Rw11RdmaDisk::WriteCheck(size_t nwdone)
{
if (nwdone == 0) return 0;
 
size_t bszwrd = fpUnit->BlockSize()/2; // block size in words
size_t nblk = (nwdone+bszwrd-1)/bszwrd;
size_t dsize = nblk*bszwrd;
std::vector<uint16_t> dbuf(dsize);
RerrMsg emsg;
bool rc = fpUnit->VirtRead(fLba, nblk,
reinterpret_cast<uint8_t*>(dbuf.data()), emsg);
if (!rc) throw Rexception("Rw11RdmaDisk::WriteCheck()",
"VirtRead() failed: ", emsg);
uint16_t* pdsk = dbuf.data();
uint16_t* pmem = fBuf.data();
for (size_t i=0; i<nwdone; i++) {
if (*pdsk++ != *pmem++) {
fStats.Inc(kStatNWChkFail);
return i;
}
}
 
return nwdone;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11RdmaDisk @ " << this << endl;
os << bl << " fBuf.size() " << RosPrintf(fBuf.size(),"d",5) << endl;
os << bl << " fpUnit: " << fpUnit << endl;
os << bl << " fNWord: " << RosPrintf(fNWord,"d",5) << endl;
os << bl << " fNBlock: " << RosPrintf(fNBlock,"d",5) << endl;
os << bl << " fLba: " << RosPrintf(fLba,"d",8) << endl;
os << bl << " fFunc: " << fFunc << endl;
 
Rw11Rdma::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::SetupDisk(size_t size, uint32_t lba, Rw11UnitDisk* punit,
Rw11RdmaDisk::func func)
{
fpUnit = punit;
size_t bszwrd = fpUnit->BlockSize()/2; // block size in words
 
fNWord = size;
fNBlock = (fNWord+bszwrd-1)/bszwrd;
fLba = lba;
fFunc = func;
 
size_t tsize = fNBlock*bszwrd;
if (fBuf.size() < tsize) fBuf.resize(tsize);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::PreRdmaHook()
{
if (fFunc != kFuncRead) return; // quit unless read request
 
RerrMsg emsg;
bool rc = fpUnit->VirtRead(fLba, fNBlock,
reinterpret_cast<uint8_t*>(fBuf.data()), emsg);
if (!rc) throw Rexception("Rw11RdmaDisk::PreRdmaHook()",
"VirtRead() failed: ", emsg);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11RdmaDisk::PostRdmaHook(size_t nwdone)
{
if (nwdone == 0) return; // quit if rdma failed early
if (fFunc != kFuncWrite) return; // quit unless write request
 
size_t bszwrd = fpUnit->BlockSize()/2; // block size in words
size_t nblock = (nwdone+bszwrd-1)/bszwrd;
size_t npad = nblock*bszwrd - nwdone;
 
// if an incomplete block was read, pad it with hex dead
if (npad) {
fStats.Inc(kStatNWritePadded);
uint16_t* p = fBuf.data()+nwdone;
for (size_t i=0; i<npad; i++) *p++ = 0xdead;
}
 
RerrMsg emsg;
bool rc = fpUnit->VirtWrite(fLba, nblock,
reinterpret_cast<uint8_t*>(fBuf.data()), emsg);
if (!rc) throw Rexception("Rw11RdmaDisk::PostRdmaHook()",
"VirtWrite() failed: ", emsg);
return;
}
 
 
} // end namespace Retro
/Rw11CntlRL11.ipp
0,0 → 1,55
// $Id: Rw11CntlRL11.ipp 632 2015-01-11 12:30:03Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-01-10 632 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlRL11.ipp 632 2015-01-11 12:30:03Z mueller $
\brief Implemenation (inline) of Rw11CntlRL11.
*/
 
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11CntlRL11::SetChunkSize(size_t chunk)
{
fRdma.SetChunkSize(chunk);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11CntlRL11::ChunkSize() const
{
return fRdma.ChunkSize();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11CntlRL11::RdmaStats() const
{
return fRdma.Stats();
}
 
 
} // end namespace Retro
/Rw11Rdma.hpp
0,0 → 1,119
// $Id: Rw11Rdma.hpp 648 2015-02-20 20:16:21Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-02-17 647 1.1 PreExecCB with nwdone and nwnext
// 2015-01-04 627 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11Rdma.hpp 648 2015-02-20 20:16:21Z mueller $
\brief Declaration of class Rw11Rdma.
*/
 
#ifndef included_Retro_Rw11Rdma
#define included_Retro_Rw11Rdma 1
 
#include "boost/utility.hpp"
#include "boost/function.hpp"
 
#include "librtools/Rstats.hpp"
#include "librtools/RerrMsg.hpp"
 
#include "librtools/Rbits.hpp"
#include "Rw11Cntl.hpp"
 
namespace Retro {
 
class Rw11Rdma : public Rbits, private boost::noncopyable {
public:
 
typedef boost::function<void(int,size_t,size_t,
RlinkCommandList&)> precb_t;
typedef boost::function<void(int,size_t,
RlinkCommandList&,size_t)> postcb_t;
 
Rw11Rdma(Rw11Cntl* pcntl, const precb_t& precb,
const postcb_t& postcb);
virtual ~Rw11Rdma();
 
Rw11Cntl& CntlBase() const;
Rw11Cpu& Cpu() const;
Rw11& W11() const;
RlinkServer& Server() const;
RlinkConnect& Connect() const;
RlogFile& LogFile() const;
 
void SetChunkSize(size_t chunk);
size_t ChunkSize() const;
 
bool IsActive() const;
 
void QueueRMem(uint32_t addr, uint16_t* block, size_t size,
uint16_t mode);
void QueueWMem(uint32_t addr, const uint16_t* block, size_t size,
uint16_t mode);
 
const Rstats& Stats() const;
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// statistics counter indices
enum stats {
kStatNQueRMem, //!< RMem chains queued
kStatNQueWMem, //!< WMem chains queued
kStatNRdmaRMem, //!< RMem chunks done
kStatNRdmaWMem, //!< WMem chunks done
kStatNExtClist, //!< clist extended
kStatNFailRdma, //!< Rdma failures
kDimStat
};
 
// status values
enum status {
kStatusDone, //!< all chunks done and ok
kStatusBusy, //!< more chunks to come
kStatusBusyLast, //!< last chunk to come
kStatusFailRdma //!< last rdma transfer failed
};
 
protected:
void SetupRdma(bool iswmem, uint32_t addr, uint16_t* block,
size_t size, uint16_t mode);
int RdmaHandler();
virtual void PreRdmaHook();
virtual void PostRdmaHook(size_t nwdone);
 
protected:
Rw11Cntl* fpCntlBase; //!< plain Rw11Cntl ptr
precb_t fPreExecCB; //!< pre Exec callback
postcb_t fPostExecCB; //!< post Exec callback
size_t fChunksize; //!< channel chunk size
enum status fStatus; //!< dma status
bool fIsWMem; //!< is memory write
uint32_t fAddr; //!< current mem address
uint16_t fMode; //!< current mode
size_t fNWordMax; //!< transfer chunk size
size_t fNWordRest; //!< words to be done
size_t fNWordDone; //!< words transfered
uint16_t* fpBlock; //!< current buffer pointer
Rstats fStats; //!< statistics
};
} // end namespace Retro
 
#include "Rw11Rdma.ipp"
 
#endif
/Rw11VirtTermPty.cpp
0,0 → 1,157
// $Id: Rw11VirtTermPty.cpp 632 2015-01-11 12:30:03Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-24 492 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTermPty.cpp 632 2015-01-11 12:30:03Z mueller $
\brief Implemenation of Rw11VirtTermPty.
*/
#define _XOPEN_SOURCE 600
 
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
 
#include "boost/bind.hpp"
 
#include "librtools/RosFill.hpp"
#include "Rw11VirtTermPty.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11VirtTermPty
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11VirtTermPty::Rw11VirtTermPty(Rw11Unit* punit)
: Rw11VirtTerm(punit),
fFd(-1)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11VirtTermPty::~Rw11VirtTermPty()
{
if (fFd>=2) {
Server().RemovePollHandler(fFd);
close(fFd);
}
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTermPty::Open(const std::string& url, RerrMsg& emsg)
{
int fd = posix_openpt(O_RDWR);
if (fd < 0) {
emsg.InitErrno("Rw11VirtTermPty::Open", "posix_openpt() failed: ", errno);
return false;
}
 
int irc = grantpt(fd);
if (irc < 0) {
emsg.InitErrno("Rw11VirtTermPty::Open", "grantpt() failed: ", errno);
close(fd);
return false;
}
irc = unlockpt(fd);
if (irc < 0) {
emsg.InitErrno("Rw11VirtTermPty::Open", "unlockpt() failed: ", errno);
close(fd);
return false;
}
char* pname = ptsname(fd);
if (pname == nullptr) {
emsg.InitErrno("Rw11VirtTermPty::Open", "ptsname() failed: ", errno);
close(fd);
return false;
}
fFd = fd;
fChannelId = pname;
 
Server().AddPollHandler(boost::bind(&Rw11VirtTermPty::RcvPollHandler,
this, _1),
fFd, POLLIN);
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtTermPty::Snd(const uint8_t* data, size_t count, RerrMsg& emsg)
{
fStats.Inc(kStatNVTSnd);
ssize_t irc = write(fFd, data, count);
if (irc != ssize_t(count)) {
emsg.InitErrno("Rw11VirtTermPty::Snd", "write() failed: ", errno);
return false;
}
fStats.Inc(kStatNVTSndByt, double(count));
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11VirtTermPty::RcvPollHandler(const pollfd& pfd)
{
fStats.Inc(kStatNVTRcvPoll);
// bail-out and cancel handler if poll returns an error event
if (pfd.revents & (~pfd.events)) return -1;
 
uint8_t buf[1024];
ssize_t irc = read(fFd, buf, 1024);
 
if (irc > 0) {
fRcvCb(buf, size_t(irc));
fStats.Inc(kStatNVTRcvByt, double(irc));
}
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtTermPty::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11VirtTermPty @ " << this << endl;
 
os << bl << " fFd: " << fFd << endl;
Rw11VirtTerm::Dump(os, ind+2, "");
return;
}
 
 
} // end namespace Retro
/Rw11.hpp
0,0 → 1,78
// $Id: Rw11.hpp 625 2014-12-30 16:17:45Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-29 624 1.1 adopt to Rlink V4 attn logic
// 2013-03-06 495 1.0 Initial version
// 2013-01-27 478 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11.hpp 625 2014-12-30 16:17:45Z mueller $
\brief Declaration of class Rw11.
*/
 
#ifndef included_Retro_Rw11
#define included_Retro_Rw11 1
 
#include "boost/utility.hpp"
#include "boost/shared_ptr.hpp"
 
#include "librlink/RlinkServer.hpp"
 
namespace Retro {
 
class Rw11Cpu; // forw decl to avoid circular incl
 
class Rw11 : private boost::noncopyable {
public:
 
Rw11();
virtual ~Rw11();
 
void SetServer(const boost::shared_ptr<RlinkServer>& spserv);
const boost::shared_ptr<RlinkServer>& ServerSPtr() const;
RlinkServer& Server() const;
RlinkConnect& Connect() const;
RlogFile& LogFile() const;
 
void AddCpu(const boost::shared_ptr<Rw11Cpu>& spcpu);
size_t NCpu() const;
Rw11Cpu& Cpu(size_t ind) const;
 
void Start();
bool IsStarted() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// some constants (also defined in cpp)
static const int kLam = 0; //!< W11 CPU cluster lam
 
protected:
int AttnHandler(RlinkServer::AttnArgs& args);
 
protected:
boost::shared_ptr<RlinkServer> fspServ;
size_t fNCpu;
boost::shared_ptr<Rw11Cpu> fspCpu[4];
bool fStarted; //!< true if Start() called
};
} // end namespace Retro
 
#include "Rw11.ipp"
 
#endif
/Rw11CntlRK11.ipp
0,0 → 1,55
// $Id: Rw11CntlRK11.ipp 627 2015-01-04 11:36:37Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-01-03 627 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlRK11.ipp 627 2015-01-04 11:36:37Z mueller $
\brief Implemenation (inline) of Rw11CntlRK11.
*/
 
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11CntlRK11::SetChunkSize(size_t chunk)
{
fRdma.SetChunkSize(chunk);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11CntlRK11::ChunkSize() const
{
return fRdma.ChunkSize();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11CntlRK11::RdmaStats() const
{
return fRdma.Stats();
}
 
 
} // end namespace Retro
/Rw11CpuW11a.hpp
0,0 → 1,52
// $Id: Rw11CpuW11a.hpp 621 2014-12-26 21:20:05Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-25 621 1.1 adopt to 4k word ibus window
// 2013-03-03 494 1.0 Initial version
// 2013-01-27 478 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11CpuW11a.hpp 621 2014-12-26 21:20:05Z mueller $
\brief Declaration of class Rw11CpuW11a.
*/
 
#ifndef included_Retro_Rw11CpuW11a
#define included_Retro_Rw11CpuW11a 1
 
#include "Rw11Cpu.hpp"
 
namespace Retro {
 
class Rw11CpuW11a : public Rw11Cpu {
public:
 
Rw11CpuW11a();
~Rw11CpuW11a();
 
void Setup(size_t ind, uint16_t base, uint16_t ibase);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
protected:
};
} // end namespace Retro
 
//#include "Rw11CpuW11a.ipp"
 
#endif
/Rw11Rdma.ipp
0,0 → 1,100
// $Id: Rw11Rdma.ipp 627 2015-01-04 11:36:37Z mueller $
//
// Copyright 20154- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-01-04 627 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Rdma.ipp 627 2015-01-04 11:36:37Z mueller $
\brief Implemenation (inline) of Rw11Rdma.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11Cntl& Rw11Rdma::CntlBase() const
{
return *fpCntlBase;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11Cpu& Rw11Rdma::Cpu() const
{
return fpCntlBase->Cpu();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11& Rw11Rdma::W11() const
{
return fpCntlBase->W11();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkServer& Rw11Rdma::Server() const
{
return fpCntlBase->Server();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkConnect& Rw11Rdma::Connect() const
{
return fpCntlBase->Connect();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlogFile& Rw11Rdma::LogFile() const
{
return fpCntlBase->LogFile();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11Rdma::ChunkSize() const
{
return fChunksize;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Rdma::IsActive() const
{
return fStatus != kStatusDone;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11Rdma::Stats() const
{
return fStats;
}
 
} // end namespace Retro
/Rw11.cpp
0,0 → 1,145
// $Id: Rw11.cpp 625 2014-12-30 16:17:45Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-30 625 1.1 adopt to Rlink V4 attn logic
// 2013-03-06 495 1.0 Initial version
// 2013-01-27 478 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11.cpp 625 2014-12-30 16:17:45Z mueller $
\brief Implemenation of Rw11.
*/
 
#include "librtools/Rexception.hpp"
 
#include "librtools/RosFill.hpp"
#include "Rw11Cpu.hpp"
 
#include "Rw11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
// constants definitions
 
const int Rw11::kLam;
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11::Rw11()
: fspServ(),
fNCpu(0),
fStarted(false)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11::~Rw11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11::SetServer(const boost::shared_ptr<RlinkServer>& spserv)
{
fspServ = spserv;
fspServ->AddAttnHandler(boost::bind(&Rw11::AttnHandler, this, _1),
uint16_t(1)<<kLam, (void*)this);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11::AddCpu(const boost::shared_ptr<Rw11Cpu>& spcpu)
{
if (fNCpu >= 4)
throw Rexception("Rw11::AddCpu", "Bad state: already 4 cpus registered");
if (fNCpu > 0 && fspCpu[0]->Type() != spcpu->Type())
throw Rexception("Rw11::AddCpu", "Bad state: type mismatch, new is "
+ spcpu->Type() + " first was " + fspCpu[0]->Type());
 
fspCpu[fNCpu] = spcpu;
fNCpu += 1;
spcpu->Setup(this);
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
Rw11Cpu& Rw11::Cpu(size_t ind) const
{
return *fspCpu[ind];
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11::Start()
{
if (fStarted)
throw Rexception("Rw11::Start()","alread started");
for (size_t i=0; i<fNCpu; i++) fspCpu[i]->Start();
 
if (!Server().IsActive()) Server().Start();
 
fStarted = true;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11 @ " << this << endl;
 
os << bl << " fspServ: " << fspServ.get() << endl;
os << bl << " fNCpu: " << fNCpu << endl;
os << bl << " fspCpu[4]: ";
for (size_t i=0; i<4; i++) os << fspCpu[i].get() << " ";
os << endl;
os << bl << " fStarted: " << fStarted << endl;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11::AttnHandler(RlinkServer::AttnArgs& args)
{
Server().GetAttnInfo(args);
 
for (size_t i=0; i<fNCpu; i++) fspCpu[i]->W11AttnHandler();
return 0;
}
} // end namespace Retro
/Rw11RdmaDisk.ipp
0,0 → 1,29
// $Id: Rw11RdmaDisk.ipp 627 2015-01-04 11:36:37Z mueller $
//
// Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2015-01-04 627 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11RdmaDisk.ipp 627 2015-01-04 11:36:37Z mueller $
\brief Implemenation (inline) of Rw11RdmaDisk.
*/
 
 
// all method definitions in namespace Retro
namespace Retro {
 
} // end namespace Retro
/Rw11CpuW11a.cpp
0,0 → 1,76
// $Id: Rw11CpuW11a.cpp 621 2014-12-26 21:20:05Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2014-12-25 621 1.1 adopt to 4k word ibus window
// 2013-03-03 494 1.0 Initial version
// 2013-01-27 478 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CpuW11a.cpp 621 2014-12-26 21:20:05Z mueller $
\brief Implemenation of Rw11CpuW11a.
*/
 
#include "librtools/RosFill.hpp"
 
#include "Rw11CpuW11a.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11CpuW11a
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11CpuW11a::Rw11CpuW11a()
: Rw11Cpu("w11a")
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11CpuW11a::~Rw11CpuW11a()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CpuW11a::Setup(size_t ind, uint16_t base, uint16_t ibase)
{
fIndex = ind;
fBase = base;
fIBase = ibase;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11CpuW11a::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CpuW11a @ " << this << endl;
Rw11Cpu::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11UnitTerm.hpp
0,0 → 1,96
// $Id: Rw11UnitTerm.hpp 570 2014-07-20 19:05:11Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone()
// 2013-04-20 508 1.0.1 add 7bit and non-printable masking; add log file
// 2013-04-13 504 1.0 Initial version
// 2013-02-19 490 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitTerm.hpp 570 2014-07-20 19:05:11Z mueller $
\brief Declaration of class Rw11UnitTerm.
*/
 
#ifndef included_Retro_Rw11UnitTerm
#define included_Retro_Rw11UnitTerm 1
 
#include <iostream>
#include <fstream>
#include <deque>
 
#include "Rw11VirtTerm.hpp"
 
#include "Rw11UnitVirt.hpp"
 
namespace Retro {
 
class Rw11UnitTerm : public Rw11UnitVirt<Rw11VirtTerm> {
public:
Rw11UnitTerm(Rw11Cntl* pcntl, size_t index);
~Rw11UnitTerm();
 
const std::string& ChannelId() const;
 
void SetTo7bit(bool to7bit);
void SetToEnpc(bool toenpc);
void SetTi7bit(bool ti7bit);
bool To7bit() const;
bool ToEnpc() const;
bool Ti7bit() const;
 
void SetLog(const std::string& fname);
const std::string& Log() const;
 
virtual bool RcvQueueEmpty();
virtual size_t RcvQueueSize();
virtual uint8_t RcvNext();
virtual size_t Rcv(uint8_t* buf, size_t count);
 
virtual bool Snd(const uint8_t* buf, size_t count);
 
virtual bool RcvCallback(const uint8_t* buf, size_t count);
virtual void WakeupCntl();
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// statistics counter indices
enum stats {
kStatNPreAttDrop = Rw11Unit::kDimStat,
kDimStat
};
protected:
virtual void AttachDone();
 
protected:
bool fTo7bit; //<! discard parity bit on output
bool fToEnpc; //<! escape non-printables on output
bool fTi7bit; //<! discard parity bit on input
std::deque<uint8_t> fRcvQueue; //<! input queue
std::string fLogFname; //<! log file name
std::ofstream fLogStream; //<! log file stream
bool fLogOptCrlf; //<! log file: crlf option given
bool fLogCrPend; //<! log file: cr pending
bool fLogLfLast; //<! log file: lf was last char
};
} // end namespace Retro
 
#include "Rw11UnitTerm.ipp"
 
#endif
/Rw11UnitStream.cpp
0,0 → 1,135
// $Id: Rw11UnitStream.cpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-04 515 1.0 Initial version
// 2013-05-01 513 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitStream.cpp 515 2013-05-04 17:28:59Z mueller $
\brief Implemenation of Rw11UnitStream.
*/
 
#include "librtools/Rexception.hpp"
 
#include "Rw11UnitStream.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitStream
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitStream::Rw11UnitStream(Rw11Cntl* pcntl, size_t index)
: Rw11UnitVirt<Rw11VirtStream>(pcntl, index)
{
fStats.Define(kStatNPreAttDrop, "NPreAttDrop",
"output bytes dropped prior attach");
fStats.Define(kStatNPreAttMiss, "NPreAttMiss",
"input bytes missed prior attach");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitStream::~Rw11UnitStream()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitStream::SetPos(int pos)
{
if (!Virt())
throw Rexception("Rw11UnitStream::SetPos", "no stream attached");
 
RerrMsg emsg;
if (!Virt()->Seek(pos, emsg)) throw Rexception(emsg);
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11UnitStream::Pos() const
{
if (!Virt())
throw Rexception("Rw11UnitStream::Pos", "no stream attached");
 
RerrMsg emsg;
int irc = Virt()->Tell(emsg);
if (irc < 0) throw Rexception(emsg);
return irc;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11UnitStream::VirtRead(uint8_t* data, size_t count, RerrMsg& emsg)
{
if (!Virt()) {
fStats.Inc(kStatNPreAttMiss);
emsg.Init("Rw11UnitStream::VirtRead", "no stream attached");
return -1;
}
return Virt()->Read(data, count, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitStream::VirtWrite(const uint8_t* data, size_t count, RerrMsg& emsg)
{
if (!Virt()) {
fStats.Inc(kStatNPreAttDrop, double(count));
emsg.Init("Rw11UnitStream::VirtWrite", "no stream attached");
return false;
}
return Virt()->Write(data, count, emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitStream::VirtFlush(RerrMsg& emsg)
{
if (!Virt()) {
emsg.Init("Rw11UnitStream::VirtFlush", "no stream attached");
return false;
}
return Virt()->Flush(emsg);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitStream::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitStream @ " << this << endl;
Rw11UnitVirt<Rw11VirtStream>::Dump(os, ind, " ^");
return;
}
 
 
} // end namespace Retro
/Rw11VirtStream.cpp
0,0 → 1,238
// $Id: Rw11VirtStream.cpp 516 2013-05-05 21:24:52Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-05 516 1.0.1 Open(): support ?app and ?bck=n options
// 2013-05-04 515 1.0 Initial version
// 2013-05-01 513 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtStream.cpp 516 2013-05-05 21:24:52Z mueller $
\brief Implemenation of Rw11VirtStream.
*/
#include <memory>
 
#include "librtools/Rtools.hpp"
#include "librtools/Rexception.hpp"
#include "librtools/RparseUrl.hpp"
#include "librtools/RosFill.hpp"
 
#include "Rw11VirtStream.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11VirtStream
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11VirtStream::Rw11VirtStream(Rw11Unit* punit)
: Rw11Virt(punit),
fIStream(false),
fOStream(false),
fFile(0)
{
fStats.Define(kStatNVSRead, "NVSRead", "Read() calls");
fStats.Define(kStatNVSReadByt, "NVSReadByt", "bytes read");
fStats.Define(kStatNVSWrite, "NVSWrite", "Write() calls");
fStats.Define(kStatNVSWriteByt,"NVSWriteByt", "bytes written");
fStats.Define(kStatNVSFlush, "NVSFlush", "Flush() calls");
fStats.Define(kStatNVSTell, "NVSTell", "Tell() calls");
fStats.Define(kStatNVSSeek, "NVSSeek", "Seek() calls");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11VirtStream::~Rw11VirtStream()
{
if (fFile) ::fclose(fFile);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtStream::Open(const std::string& url, RerrMsg& emsg)
{
RparseUrl opts;
if (!opts.Set(fpUnit->AttachOpts(), "|ronly|wonly|", emsg)) return false;
fIStream = opts.FindOpt("ronly");
fOStream = opts.FindOpt("wonly");
if (!(fIStream ^ fOStream))
throw Rexception("Rw11VirtStream::Open",
"Bad state: neither ronly nor wonly seen");
 
if (fOStream) { // handle output streams
if (!fUrl.Set(url, "|app|bck=|", emsg)) return false;
if (!Rtools::CreateBackupFile(fUrl, emsg)) return false;
fFile = ::fopen(fUrl.Path().c_str(), fUrl.FindOpt("app") ? "a" : "w");
 
} else { // handle input streams
if (!fUrl.Set(url, "", emsg)) return false;
fFile = ::fopen(fUrl.Path().c_str(), "r");
}
 
if (!fFile) {
emsg.InitErrno("Rw11VirtStream::Open()",
string("fopen() for '") + fUrl.Path() + "' failed: ",
errno);
return false;
}
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11VirtStream::Read(uint8_t* data, size_t count, RerrMsg& emsg)
{
if (!fIStream)
throw Rexception("Rw11VirtStream::Read",
"Bad state: Read() called but fIStream=false");
if (!fFile)
throw Rexception("Rw11VirtStream::Read", "Bad state: file not open");
 
fStats.Inc(kStatNVSRead);
size_t irc = ::fread(data, 1, count, fFile);
if (irc == 0 && ferror(fFile)) {
emsg.InitErrno("Rw11VirtStream::Read()", "fread() failed: ", errno);
return -1;
}
fStats.Inc(kStatNVSReadByt, double(irc));
return int(irc);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtStream::Write(const uint8_t* data, size_t count, RerrMsg& emsg)
{
if (!fOStream)
throw Rexception("Rw11VirtStream::Write",
"Bad state: Write() called but fOStream=false");
if (!fFile)
throw Rexception("Rw11VirtStream::Write", "Bad state: file not open");
 
fStats.Inc(kStatNVSWrite);
size_t irc = ::fwrite(data, 1, count, fFile);
if (irc != count) {
emsg.InitErrno("Rw11VirtStream::Write()", "fwrite() failed: ", errno);
return false;
}
 
fStats.Inc(kStatNVSWriteByt, double(count));
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtStream::Flush(RerrMsg& emsg)
{
if (!fOStream) return true;
if (!fFile)
throw Rexception("Rw11VirtStream::Write", "Bad state: file not open");
 
fStats.Inc(kStatNVSFlush);
size_t irc = ::fflush(fFile);
if (irc != 0) {
emsg.InitErrno("Rw11VirtStream::Flush()", "fflush() failed: ", errno);
return false;
}
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int Rw11VirtStream::Tell(RerrMsg& emsg)
{
if (!fFile)
throw Rexception("Rw11VirtStream::Tell", "Bad state: file not open");
 
fStats.Inc(kStatNVSTell);
long irc = ::ftell(fFile);
if (irc < 0) {
emsg.InitErrno("Rw11VirtStream::Tell()", "ftell() failed: ", errno);
return -1;
}
 
return int(irc);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11VirtStream::Seek(int pos, RerrMsg& emsg)
{
if (!fFile)
throw Rexception("Rw11VirtStream::Seek", "Bad state: file not open");
 
fStats.Inc(kStatNVSSeek);
int whence = SEEK_SET;
if (pos < 0) {
pos = 0;
whence = SEEK_END;
}
int irc = ::fseek(fFile, pos, whence);
 
if (irc < 0) {
emsg.InitErrno("Rw11VirtStream::Seek()", "fseek() failed: ", errno);
return false;
}
 
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtStream::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11VirtStream @ " << this << endl;
 
os << bl << " fIStream: " << fIStream << endl;
os << bl << " fOStream: " << fOStream << endl;
os << bl << " fFile: " << fFile << endl;
Rw11Virt::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
Rw11VirtStream* Rw11VirtStream::New(const std::string& url, Rw11Unit* punit,
RerrMsg& emsg)
{
unique_ptr<Rw11VirtStream> p;
p.reset(new Rw11VirtStream(punit));
if (p->Open(url, emsg)) return p.release();
return 0;
}
 
 
} // end namespace Retro
/Rw11UnitDiskBase.hpp
0,0 → 1,58
// $Id: Rw11UnitDiskBase.hpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone()
// 2013-04-14 506 1.0 Initial version
// 2013-02-22 490 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitDiskBase.hpp 515 2013-05-04 17:28:59Z mueller $
\brief Declaration of class Rw11UnitDiskBase.
*/
 
#ifndef included_Retro_Rw11UnitDiskBase
#define included_Retro_Rw11UnitDiskBase 1
 
#include "Rw11UnitDisk.hpp"
 
namespace Retro {
 
template <class TC>
class Rw11UnitDiskBase : public Rw11UnitDisk {
public:
 
Rw11UnitDiskBase(TC* pcntl, size_t index);
~Rw11UnitDiskBase();
 
TC& Cntl() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
virtual void AttachDone();
virtual void DetachDone();
 
protected:
TC* fpCntl;
};
} // end namespace Retro
 
#include "Rw11UnitDiskBase.ipp"
 
#endif
/Rw11UnitStreamBase.hpp
0,0 → 1,57
// $Id: Rw11UnitStreamBase.hpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-04 515 1.0 Initial version
// 2013-05-01 513 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitStreamBase.hpp 515 2013-05-04 17:28:59Z mueller $
\brief Declaration of class Rw11UnitStreamBase.
*/
 
#ifndef included_Retro_Rw11UnitStreamBase
#define included_Retro_Rw11UnitStreamBase 1
 
#include "Rw11UnitStream.hpp"
 
namespace Retro {
 
template <class TC>
class Rw11UnitStreamBase : public Rw11UnitStream {
public:
 
Rw11UnitStreamBase(TC* pcntl, size_t index);
~Rw11UnitStreamBase();
 
TC& Cntl() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
virtual void AttachDone();
virtual void DetachDone();
 
protected:
TC* fpCntl;
};
} // end namespace Retro
 
#include "Rw11UnitStreamBase.ipp"
 
#endif
/Rw11UnitPC11.cpp
0,0 → 1,71
// $Id: Rw11UnitPC11.cpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-03 515 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitPC11.cpp 515 2013-05-04 17:28:59Z mueller $
\brief Implemenation of Rw11UnitPC11.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/RosFill.hpp"
#include "Rw11CntlPC11.hpp"
 
#include "Rw11UnitPC11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitPC11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitPC11::Rw11UnitPC11(Rw11CntlPC11* pcntl, size_t index)
: Rw11UnitStreamBase<Rw11CntlPC11>(pcntl, index)
{
// unit 0 -> reader -> read only stream
// unit 1 -> puncher -> write only stream
const char* opts = (index==0) ? "?ronly" : "?wonly";
SetAttachOpts(opts);
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitPC11::~Rw11UnitPC11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitPC11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitPC11 @ " << this << endl;
Rw11UnitStreamBase<Rw11CntlPC11>::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11UnitLP11.hpp
0,0 → 1,53
// $Id: Rw11UnitLP11.hpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-01 513 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitLP11.hpp 515 2013-05-04 17:28:59Z mueller $
\brief Declaration of class Rw11UnitLP11.
*/
 
#ifndef included_Retro_Rw11UnitLP11
#define included_Retro_Rw11UnitLP11 1
 
#include "Rw11VirtStream.hpp"
 
#include "Rw11UnitStreamBase.hpp"
 
namespace Retro {
 
class Rw11CntlLP11; // forw decl to avoid circular incl
 
class Rw11UnitLP11 : public Rw11UnitStreamBase<Rw11CntlLP11> {
public:
 
Rw11UnitLP11(Rw11CntlLP11* pcntl, size_t index);
~Rw11UnitLP11();
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
 
};
} // end namespace Retro
 
//#include "Rw11UnitLP11.ipp"
 
#endif
/Rw11UnitStream.hpp
0,0 → 1,64
// $Id: Rw11UnitStream.hpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-04 515 1.0 Initial version
// 2013-05-01 513 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitStream.hpp 515 2013-05-04 17:28:59Z mueller $
\brief Declaration of class Rw11UnitStream.
*/
 
#ifndef included_Retro_Rw11UnitStream
#define included_Retro_Rw11UnitStream 1
 
#include "Rw11VirtStream.hpp"
 
#include "Rw11UnitVirt.hpp"
 
namespace Retro {
 
class Rw11UnitStream : public Rw11UnitVirt<Rw11VirtStream> {
public:
Rw11UnitStream(Rw11Cntl* pcntl, size_t index);
~Rw11UnitStream();
 
void SetPos(int pos);
int Pos() const;
 
int VirtRead(uint8_t* data, size_t count, RerrMsg& emsg);
bool VirtWrite(const uint8_t* data, size_t count, RerrMsg& emsg);
bool VirtFlush(RerrMsg& emsg);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// statistics counter indices
enum stats {
kStatNPreAttDrop = Rw11Unit::kDimStat,
kStatNPreAttMiss,
kDimStat
};
 
protected:
};
} // end namespace Retro
 
//#include "Rw11UnitStream.ipp"
 
#endif
/Rw11VirtStream.hpp
0,0 → 1,75
// $Id: Rw11VirtStream.hpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-04 515 1.0 Initial version
// 2013-05-01 513 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtStream.hpp 515 2013-05-04 17:28:59Z mueller $
\brief Declaration of class Rw11VirtStream.
*/
 
#ifndef included_Retro_Rw11VirtStream
#define included_Retro_Rw11VirtStream 1
 
#include <stdio.h>
 
#include "Rw11Virt.hpp"
 
namespace Retro {
 
class Rw11VirtStream : public Rw11Virt {
public:
 
explicit Rw11VirtStream(Rw11Unit* punit);
~Rw11VirtStream();
 
bool Open(const std::string& url, RerrMsg& emsg);
int Read(uint8_t* data, size_t count, RerrMsg& emsg);
bool Write(const uint8_t* data, size_t count, RerrMsg& emsg);
bool Flush(RerrMsg& emsg);
int Tell(RerrMsg& emsg);
bool Seek(int pos, RerrMsg& emsg);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
static Rw11VirtStream* New(const std::string& url, Rw11Unit* punit,
RerrMsg& emsg);
 
// statistics counter indices
enum stats {
kStatNVSRead = Rw11Virt::kDimStat,
kStatNVSReadByt,
kStatNVSWrite,
kStatNVSWriteByt,
kStatNVSFlush,
kStatNVSTell,
kStatNVSSeek,
kDimStat
};
 
protected:
bool fIStream; //<! is input (read only) stream
bool fOStream; //<! is output (write only) stream
FILE* fFile; //<! file ptr
};
} // end namespace Retro
 
//#include "Rw11VirtStream.ipp"
 
#endif
/Rw11Unit.ipp
0,0 → 1,119
// $Id: Rw11Unit.ipp 513 2013-05-01 14:02:06Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-01 513 1.0.1 add fAttachOpts, (Set)AttachOpts()
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Unit.ipp 513 2013-05-01 14:02:06Z mueller $
\brief Implemenation (inline) of Rw11Unit.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11Unit::Index() const
{
return fIndex;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline std::string Rw11Unit::Name() const
{
return fpCntlBase->UnitName(fIndex);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11Unit::SetAttachOpts(const std::string& opts)
{
fAttachOpts = opts;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const std::string& Rw11Unit::AttachOpts() const
{
return fAttachOpts;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11Cntl& Rw11Unit::CntlBase() const
{
return *fpCntlBase;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11Cpu& Rw11Unit::Cpu() const
{
return fpCntlBase->Cpu();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11& Rw11Unit::W11() const
{
return fpCntlBase->W11();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkServer& Rw11Unit::Server() const
{
return fpCntlBase->Server();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkConnect& Rw11Unit::Connect() const
{
return fpCntlBase->Connect();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlogFile& Rw11Unit::LogFile() const
{
return fpCntlBase->LogFile();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11Unit::Stats() const
{
return fStats;
}
 
} // end namespace Retro
/Rw11UnitDiskBase.ipp
0,0 → 1,99
// $Id: Rw11UnitDiskBase.ipp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone()
// 2013-04-14 506 1.0 Initial version
// 2013-02-22 490 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitDiskBase.ipp 515 2013-05-04 17:28:59Z mueller $
\brief Implemenation (inline) of Rw11UnitDiskBase.
*/
 
#include "Rw11UnitDiskBase.hpp"
 
/*!
\class Retro::Rw11UnitDiskBase
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
template <class TC>
Rw11UnitDiskBase<TC>::Rw11UnitDiskBase(TC* pcntl, size_t index)
: Rw11UnitDisk(pcntl, index),
fpCntl(pcntl)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
template <class TC>
Rw11UnitDiskBase<TC>::~Rw11UnitDiskBase()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
inline TC& Rw11UnitDiskBase<TC>::Cntl() const
{
return *fpCntl;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitDiskBase<TC>::Dump(std::ostream& os, int ind,
const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitDiskBase @ " << this << std::endl;
os << bl << " fpCntl: " << fpCntl << std::endl;
Rw11UnitDisk::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitDiskBase<TC>::AttachDone()
{
Virt()->Setup(BlockSize(), NBlock());
Cntl().UnitSetup(Index());
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitDiskBase<TC>::DetachDone()
{
SetWProt(false);
Cntl().UnitSetup(Index());
return;
}
 
} // end namespace Retro
/Rw11UnitStreamBase.ipp
0,0 → 1,96
// $Id: Rw11UnitStreamBase.ipp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-04 515 1.0 Initial version
// 2013-05-01 513 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitStreamBase.ipp 515 2013-05-04 17:28:59Z mueller $
\brief Implemenation (inline) of Rw11UnitStreamBase.
*/
 
#include "Rw11UnitStreamBase.hpp"
 
/*!
\class Retro::Rw11UnitStreamBase
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
template <class TC>
Rw11UnitStreamBase<TC>::Rw11UnitStreamBase(TC* pcntl, size_t index)
: Rw11UnitStream(pcntl, index),
fpCntl(pcntl)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
template <class TC>
Rw11UnitStreamBase<TC>::~Rw11UnitStreamBase()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
inline TC& Rw11UnitStreamBase<TC>::Cntl() const
{
return *fpCntl;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitStreamBase<TC>::Dump(std::ostream& os, int ind,
const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitStreamBase @ " << this << std::endl;
os << bl << " fpCntl: " << fpCntl << std::endl;
Rw11UnitStream::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitStreamBase<TC>::AttachDone()
{
Cntl().UnitSetup(Index());
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitStreamBase<TC>::DetachDone()
{
Cntl().UnitSetup(Index());
return;
}
 
} // end namespace Retro
/Rw11UnitTerm.cpp
0,0 → 1,323
// $Id: Rw11UnitTerm.cpp 516 2013-05-05 21:24:52Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone()
// 2013-04-13 504 1.0 Initial version
// 2013-02-19 490 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitTerm.cpp 516 2013-05-05 21:24:52Z mueller $
\brief Implemenation of Rw11UnitTerm.
*/
 
#include "boost/thread/locks.hpp"
#include "boost/bind.hpp"
 
#include "librtools/RparseUrl.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/Rexception.hpp"
 
#include "Rw11UnitTerm.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitTerm
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitTerm::Rw11UnitTerm(Rw11Cntl* pcntl, size_t index)
: Rw11UnitVirt<Rw11VirtTerm>(pcntl, index),
fTo7bit(false),
fToEnpc(false),
fTi7bit(false),
fRcvQueue(),
fLogFname(),
fLogStream(),
fLogOptCrlf(false),
fLogCrPend(false),
fLogLfLast(false)
{
fStats.Define(kStatNPreAttDrop, "NPreAttDrop",
"snd bytes dropped prior attach");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitTerm::~Rw11UnitTerm()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
const std::string& Rw11UnitTerm::ChannelId() const
{
if (fpVirt) return fpVirt->ChannelId();
static string nil;
return nil;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTerm::SetLog(const std::string& fname)
{
if (fLogStream.is_open()) {
if (fLogCrPend) fLogStream << "\r";
fLogCrPend = false;
fLogStream.close();
}
fLogFname.clear();
if (fname.length() == 0) return;
 
RparseUrl purl;
RerrMsg emsg;
if (!purl.Set(fname, "|app|bck=|crlf|", emsg))
throw Rexception(emsg);
if (!Rtools::CreateBackupFile(purl, emsg))
throw Rexception(emsg);
 
ios_base::openmode mode = ios_base::out;
if (purl.FindOpt("app")) mode |= ios_base::app;
 
fLogStream.open(purl.Path(), mode);
if (!fLogStream.is_open()) {
throw Rexception("Rw11UnitTerm::SetLog",
string("failed to open '")+purl.Path()+"'");
}
 
fLogFname = fname;
fLogOptCrlf = purl.FindOpt("crlf");
fLogCrPend = false;
fLogLfLast = false;
 
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTerm::RcvQueueEmpty()
{
return fRcvQueue.empty();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
size_t Rw11UnitTerm::RcvQueueSize()
{
return fRcvQueue.size();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
uint8_t Rw11UnitTerm::RcvNext()
{
if (RcvQueueEmpty()) return 0;
uint8_t ochr = fRcvQueue.front();
fRcvQueue.pop_front();
return ochr;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
size_t Rw11UnitTerm::Rcv(uint8_t* buf, size_t count)
{
uint8_t* p = buf;
for (size_t i=0; i<count && !fRcvQueue.empty(); i++) {
*p++ = fRcvQueue.front();
fRcvQueue.pop_front();
}
return p - buf;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTerm::Snd(const uint8_t* buf, size_t count)
{
bool ok = true;
vector<uint8_t> bufmod;
const uint8_t* bufout = buf;
size_t bufcnt = count;
 
if (fTo7bit || fToEnpc) {
for (size_t i=0; i<count; i++) {
uint8_t ochr = buf[i];
if (fTo7bit) ochr &= 0177;
if (fToEnpc) {
if ((ochr>=040 && ochr<177) ||
ochr=='\t' || ochr=='\n' || ochr=='\r') {
bufmod.push_back(ochr);
} else {
if (ochr != 0) {
bufmod.push_back('<');
bufmod.push_back('0' + ((ochr>>6)&07) );
bufmod.push_back('0' + ((ochr>>3)&07) );
bufmod.push_back('0' + (ochr &07) );
bufmod.push_back('>');
}
}
} else {
bufmod.push_back(ochr);
}
}
bufout = bufmod.data();
bufcnt = bufmod.size();
}
 
if (fLogStream.is_open()) {
for (size_t i=0; i<bufcnt; i++) {
uint8_t ochr = bufout[i];
// the purpose of the 'crlf' filter is to map
// \r\n -> \n
// \r\r\n -> \n (any number of \r)
// \n\r -> \n
// \n\r\r -> \n (any number of \r)
// and to ignore \0 chars
if (fLogOptCrlf) { // crlf filtering on
if (ochr == 0) continue; // ignore \0 chars
if (fLogCrPend) {
if (ochr == '\r') continue; // collapes multiple \r
if (ochr != '\n') fLogStream << '\r'; // log \r if not followed by \n
fLogCrPend = false;
}
if (ochr == '\r') { // \r seen
fLogCrPend = !fLogLfLast; // remember \r if last wasn't \n
continue;
}
}
fLogStream << char(ochr);
fLogLfLast = (ochr == '\n');
}
}
 
if (fpVirt) { // if virtual device attached
RerrMsg emsg;
ok = fpVirt->Snd(bufout, bufcnt, emsg);
// FIXME_code: handler errors
} else { // no virtual device attached
if (Name() == "tta0") { // is it main console ?
for (size_t i=0; i<bufcnt; i++) { // than print to stdout
cout << char(bufout[i]) << flush;
}
} else { // otherwise discard
fStats.Inc(kStatNPreAttDrop); // and count at least...
}
}
return ok;
}
 
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11UnitTerm::RcvCallback(const uint8_t* buf, size_t count)
{
// lock connect to protect rxqueue
boost::lock_guard<RlinkConnect> lock(Connect());
 
bool que_empty_old = fRcvQueue.empty();
for (size_t i=0; i<count; i++) {
uint8_t ichr = buf[i];
if (fTi7bit) ichr &= 0177;
fRcvQueue.push_back(ichr);
}
bool que_empty_new = fRcvQueue.empty();
if (que_empty_old && !que_empty_new) WakeupCntl();
return true;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTerm::WakeupCntl()
{
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTerm::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitTerm @ " << this << endl;
 
os << bl << " fTo7bit: " << fTo7bit << endl;
os << bl << " fToEnpc: " << fToEnpc << endl;
os << bl << " fTi7bit: " << fTi7bit << endl;
{
boost::lock_guard<RlinkConnect> lock(Connect());
size_t size = fRcvQueue.size();
os << bl << " fRcvQueue.size: " << fRcvQueue.size() << endl;
if (size > 0) {
os << bl << " fRcvQueue: \"";
size_t ocount = 0;
for (size_t i=0; i<size; i++) {
if (ocount >= 50) {
os << "...";
break;
}
uint8_t byt = fRcvQueue[i];
if (byt >= 040 && byt <= 0176) {
os << char(byt);
ocount += 1;
} else {
os << "<" << RosPrintf(byt,"o0",3) << ">";
ocount += 5;
}
}
os << "\"" << endl;
}
}
os << bl << " fLogFname: " << fLogFname << endl;
os << bl << " fLogStream.is_open: " << fLogStream.is_open() << endl;
os << bl << " fLogOptCrlf: " << fLogOptCrlf << endl;
os << bl << " fLogCrPend: " << fLogCrPend << endl;
os << bl << " fLogLfLast: " << fLogLfLast << endl;
 
Rw11UnitVirt<Rw11VirtTerm>::Dump(os, ind, " ^");
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitTerm::AttachDone()
{
fpVirt->SetupRcvCallback(boost::bind(&Rw11UnitTerm::RcvCallback,
this, _1, _2));
return;
}
 
 
} // end namespace Retro
/Rw11UnitPC11.hpp
0,0 → 1,53
// $Id: Rw11UnitPC11.hpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-03 515 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitPC11.hpp 515 2013-05-04 17:28:59Z mueller $
\brief Declaration of class Rw11UnitPC11.
*/
 
#ifndef included_Retro_Rw11UnitPC11
#define included_Retro_Rw11UnitPC11 1
 
#include "Rw11VirtStream.hpp"
 
#include "Rw11UnitStreamBase.hpp"
 
namespace Retro {
 
class Rw11CntlPC11; // forw decl to avoid circular incl
 
class Rw11UnitPC11 : public Rw11UnitStreamBase<Rw11CntlPC11> {
public:
 
Rw11UnitPC11(Rw11CntlPC11* pcntl, size_t index);
~Rw11UnitPC11();
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
 
};
} // end namespace Retro
 
//#include "Rw11UnitPC11.ipp"
 
#endif
/Rw11UnitLP11.cpp
0,0 → 1,68
// $Id: Rw11UnitLP11.cpp 515 2013-05-04 17:28:59Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-05-01 513 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitLP11.cpp 515 2013-05-04 17:28:59Z mueller $
\brief Implemenation of Rw11UnitLP11.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/RosFill.hpp"
#include "Rw11CntlLP11.hpp"
 
#include "Rw11UnitLP11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitLP11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitLP11::Rw11UnitLP11(Rw11CntlLP11* pcntl, size_t index)
: Rw11UnitStreamBase<Rw11CntlLP11>(pcntl, index)
{
SetAttachOpts("?wonly"); // use write only (output) streams
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitLP11::~Rw11UnitLP11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitLP11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitLP11 @ " << this << endl;
Rw11UnitStreamBase<Rw11CntlLP11>::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11UnitRK11.hpp
0,0 → 1,54
// $Id: Rw11UnitRK11.hpp 509 2013-04-21 20:46:20Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-04-20 508 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitRK11.hpp 509 2013-04-21 20:46:20Z mueller $
\brief Declaration of class Rw11UnitRK11.
*/
 
#ifndef included_Retro_Rw11UnitRK11
#define included_Retro_Rw11UnitRK11 1
 
#include "Rw11UnitDiskBase.hpp"
 
namespace Retro {
 
class Rw11CntlRK11; // forw decl to avoid circular incl
 
class Rw11UnitRK11 : public Rw11UnitDiskBase<Rw11CntlRK11> {
public:
Rw11UnitRK11(Rw11CntlRK11* pcntl, size_t index);
~Rw11UnitRK11();
 
void SetRkds(uint16_t rkds);
uint16_t Rkds() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
uint16_t fRkds;
};
} // end namespace Retro
 
#include "Rw11UnitRK11.ipp"
 
#endif
/Rw11UnitRK11.ipp
0,0 → 1,53
// $Id: Rw11UnitRK11.ipp 509 2013-04-21 20:46:20Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-04-20 508 1.0 Initial version
// 2013-04-14 505 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitRK11.ipp 509 2013-04-21 20:46:20Z mueller $
\brief Implemenation (inline) of Rw11UnitRK11.
*/
 
#include "Rw11UnitRK11.hpp"
 
/*!
\class Retro::Rw11UnitRK11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitRK11::SetRkds(uint16_t rkds)
{
fRkds = rkds;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11UnitRK11::Rkds() const
{
return fRkds;
}
 
} // end namespace Retro
/Rw11VirtTermTcp.hpp
0,0 → 1,112
// $Id: Rw11VirtTermTcp.hpp 508 2013-04-20 18:43:28Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-04-20 508 1.0.1 add fSndPreConQue handling
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11VirtTermTcp.hpp 508 2013-04-20 18:43:28Z mueller $
\brief Declaration of class Rw11VirtTermTcp.
*/
 
#ifndef included_Retro_Rw11VirtTermTcp
#define included_Retro_Rw11VirtTermTcp 1
 
#include <deque>
 
#include "Rw11VirtTerm.hpp"
 
namespace Retro {
 
class Rw11VirtTermTcp : public Rw11VirtTerm {
public:
 
explicit Rw11VirtTermTcp(Rw11Unit* punit);
~Rw11VirtTermTcp();
 
bool Open(const std::string& url, RerrMsg& emsg);
 
virtual bool Snd(const uint8_t* data, size_t count, RerrMsg& emsg);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// statistics counter indices
enum stats {
kStatNVTPreConSave = Rw11VirtTerm::kDimStat,
kStatNVTPreConDrop,
kStatNVTListenPoll,
kStatNVTAccept,
kStatNVTRcvRaw,
kStatNVTSndRaw,
kDimStat
};
 
protected:
 
bool Connected() const;
int ListenPollHandler(const pollfd& pfd);
int RcvPollHandler(const pollfd& pfd);
 
// some constants (also defined in cpp)
static const uint8_t kCode_NULL = 0;
static const uint8_t kCode_LF = 10;
static const uint8_t kCode_CR = 13;
static const uint8_t kCode_ESC = 27;
static const uint8_t kCode_SE = 240;
static const uint8_t kCode_NOP = 241;
static const uint8_t kCode_IP = 244;
static const uint8_t kCode_GA = 249;
static const uint8_t kCode_SB = 250;
static const uint8_t kCode_WILL = 251;
static const uint8_t kCode_WONT = 252;
static const uint8_t kCode_DO = 253;
static const uint8_t kCode_DONT = 254;
static const uint8_t kCode_IAC = 255;
 
static const uint8_t kOpt_BIN = 0;
static const uint8_t kOpt_ECHO = 1;
static const uint8_t kOpt_SGA = 3;
static const uint8_t kOpt_TTYP = 24;
static const uint8_t kOpt_LINE = 34;
 
static const size_t kPreConQue_limit = 65536;
 
enum telnet_state {
ts_Closed = 0,
ts_Listen,
ts_Stream,
ts_Iac,
ts_Cmd,
ts_Subneg,
ts_Subiac
};
protected:
int fFdListen;
int fFd;
telnet_state fState;
bool fTcpTrace;
std::deque<uint8_t> fSndPreConQue;
};
} // end namespace Retro
 
#include "Rw11VirtTermTcp.ipp"
 
#endif
/Rw11VirtTermTcp.ipp
0,0 → 1,43
// $Id: Rw11VirtTermTcp.ipp 508 2013-04-20 18:43:28Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-04-20 508 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTermTcp.ipp 508 2013-04-20 18:43:28Z mueller $
\brief Implemenation (inline) of Rw11VirtTermTcp.
*/
 
#include "Rw11VirtTermTcp.hpp"
 
/*!
\class Retro::Rw11VirtTermTcp
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11VirtTermTcp::Connected() const
{
return fFd > 2;
}
 
} // end namespace Retro
/Rw11VirtDisk.cpp
0,0 → 1,99
// $Id: Rw11VirtDisk.cpp 509 2013-04-21 20:46:20Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-03 494 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtDisk.cpp 509 2013-04-21 20:46:20Z mueller $
\brief Implemenation of Rw11VirtDisk.
*/
#include <memory>
 
#include "librtools/RosFill.hpp"
#include "librtools/RparseUrl.hpp"
#include "Rw11VirtDiskFile.hpp"
 
#include "Rw11VirtDisk.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11VirtDisk
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11VirtDisk::Rw11VirtDisk(Rw11Unit* punit)
: Rw11Virt(punit),
fBlkSize(0),
fNBlock(0)
{
fStats.Define(kStatNVDRead, "NVDRead", "Read() calls");
fStats.Define(kStatNVDReadBlk, "NVDReadBlk", "blocks read");
fStats.Define(kStatNVDWrite, "NVDWrite", "Write() calls");
fStats.Define(kStatNVDWriteBlk,"NVDWriteBlk", "blocks written");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11VirtDisk::~Rw11VirtDisk()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
Rw11VirtDisk* Rw11VirtDisk::New(const std::string& url, Rw11Unit* punit,
RerrMsg& emsg)
{
string scheme = RparseUrl::FindScheme(url, "file");
unique_ptr<Rw11VirtDisk> p;
if (scheme == "file") { // scheme -> file:
p.reset(new Rw11VirtDiskFile(punit));
if (p->Open(url, emsg)) return p.release();
 
} else { // scheme -> no match
emsg.Init("Rw11VirtDisk::New", string("Scheme '") + scheme +
"' is not supported");
}
 
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtDisk::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11VirtDisk @ " << this << endl;
 
os << bl << " fBlkSize: " << fBlkSize << endl;
os << bl << " fNBlock: " << fNBlock << endl;
Rw11Virt::Dump(os, ind, " ^");
return;
}
 
 
} // end namespace Retro
/Rw11VirtDiskFile.hpp
0,0 → 1,61
// $Id: Rw11VirtDiskFile.hpp 509 2013-04-21 20:46:20Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-04-14 506 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11VirtDiskFile.hpp 509 2013-04-21 20:46:20Z mueller $
\brief Declaration of class Rw11VirtDiskFile.
*/
 
#ifndef included_Retro_Rw11VirtDiskFile
#define included_Retro_Rw11VirtDiskFile 1
 
#include "Rw11VirtDisk.hpp"
 
namespace Retro {
 
class Rw11VirtDiskFile : public Rw11VirtDisk {
public:
 
explicit Rw11VirtDiskFile(Rw11Unit* punit);
~Rw11VirtDiskFile();
 
bool Open(const std::string& url, RerrMsg& emsg);
 
virtual bool Read(size_t lba, size_t nblk, uint8_t* data,
RerrMsg& emsg);
virtual bool Write(size_t lba, size_t nblk, const uint8_t* data,
RerrMsg& emsg);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
bool Seek(size_t seekpos, RerrMsg& emsg);
 
protected:
int fFd;
size_t fSize;
};
} // end namespace Retro
 
//#include "Rw11VirtDiskFile.ipp"
 
#endif
/Rw11VirtDisk.hpp
0,0 → 1,71
// $Id: Rw11VirtDisk.hpp 509 2013-04-21 20:46:20Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-03 494 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11VirtDisk.hpp 509 2013-04-21 20:46:20Z mueller $
\brief Declaration of class Rw11VirtDisk.
*/
 
#ifndef included_Retro_Rw11VirtDisk
#define included_Retro_Rw11VirtDisk 1
 
#include "Rw11Virt.hpp"
 
namespace Retro {
 
class Rw11VirtDisk : public Rw11Virt {
public:
explicit Rw11VirtDisk(Rw11Unit* punit);
~Rw11VirtDisk();
 
void Setup(size_t blksize, size_t nblock);
size_t BlockSize() const;
size_t NBlock() const;
 
virtual bool Read(size_t lba, size_t nblk, uint8_t* data,
RerrMsg& emsg) = 0;
virtual bool Write(size_t lba, size_t nblk, const uint8_t* data,
RerrMsg& emsg) = 0;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
static Rw11VirtDisk* New(const std::string& url, Rw11Unit* punit,
RerrMsg& emsg);
 
// statistics counter indices
enum stats {
kStatNVDRead = Rw11Virt::kDimStat,
kStatNVDReadBlk,
kStatNVDWrite,
kStatNVDWriteBlk,
kDimStat
};
 
protected:
size_t fBlkSize; //<! block size in byte
size_t fNBlock; //<! disk size in blocks
};
} // end namespace Retro
 
#include "Rw11VirtDisk.ipp"
 
#endif
/Rw11VirtDisk.ipp
0,0 → 1,55
// $Id: Rw11VirtDisk.ipp 509 2013-04-21 20:46:20Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-03 494 1.0 Initial version
// 2013-02-19 490 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtDisk.ipp 509 2013-04-21 20:46:20Z mueller $
\brief Implemenation (inline) of Rw11VirtDisk.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11VirtDisk::Setup(size_t blksize, size_t nblock)
{
fBlkSize = blksize;
fNBlock = nblock;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11VirtDisk::BlockSize() const
{
return fBlkSize;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11VirtDisk::NBlock() const
{
return fNBlock;
}
 
} // end namespace Retro
/Rw11VirtTerm.cpp
0,0 → 1,102
// $Id: Rw11VirtTerm.cpp 508 2013-04-20 18:43:28Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTerm.cpp 508 2013-04-20 18:43:28Z mueller $
\brief Implemenation of Rw11VirtTerm.
*/
#include <memory>
 
#include "librtools/RparseUrl.hpp"
#include "librtools/RosFill.hpp"
#include "Rw11VirtTermPty.hpp"
#include "Rw11VirtTermTcp.hpp"
 
#include "Rw11VirtTerm.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11VirtTerm
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11VirtTerm::Rw11VirtTerm(Rw11Unit* punit)
: Rw11Virt(punit),
fChannelId(),
fRcvCb()
{
fStats.Define(kStatNVTRcvPoll, "NVTRcvPoll", "VT RcvPollHandler() calls");
fStats.Define(kStatNVTSnd, "NVTSnd", "VT Snd() calls");
fStats.Define(kStatNVTRcvByt, "NVTRcvByt", "VT bytes received");
fStats.Define(kStatNVTSndByt, "NVTSndByt", "VT bytes send");
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11VirtTerm::~Rw11VirtTerm()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
Rw11VirtTerm* Rw11VirtTerm::New(const std::string& url, Rw11Unit* punit,
RerrMsg& emsg)
{
string scheme = RparseUrl::FindScheme(url, "tcp");
unique_ptr<Rw11VirtTerm> p;
if (scheme == "pty") { // scheme -> pty:
p.reset(new Rw11VirtTermPty(punit));
if (p->Open(url, emsg)) return p.release();
 
} else if (scheme == "tcp") { // scheme -> tcp:
p.reset(new Rw11VirtTermTcp(punit));
if (p->Open(url, emsg)) return p.release();
 
} else { // scheme -> no match
emsg.Init("Rw11VirtTerm::New", string("Scheme '") + scheme +
"' is not supported");
 
}
return 0;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11VirtTerm::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11VirtTerm @ " << this << endl;
 
os << bl << " fChannelId: " << fChannelId << endl;
Rw11Virt::Dump(os, ind, " ^");
return;
}
 
} // end namespace Retro
/Rw11UnitTerm.ipp
0,0 → 1,89
// $Id: Rw11UnitTerm.ipp 508 2013-04-20 18:43:28Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-04-20 508 1.0.1 add 7bit and non-printable masking; add log file
// 2013-04-13 504 1.0 Initial version
// 2013-03-02 493 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitTerm.ipp 508 2013-04-20 18:43:28Z mueller $
\brief Implemenation (inline) of Rw11UnitTerm.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitTerm::SetTo7bit(bool to7bit)
{
fTo7bit = to7bit;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitTerm::SetToEnpc(bool toenpc)
{
fToEnpc = toenpc;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11UnitTerm::SetTi7bit(bool ti7bit)
{
fTi7bit = ti7bit;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11UnitTerm::To7bit() const
{
return fTo7bit;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11UnitTerm::ToEnpc() const
{
return fToEnpc;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11UnitTerm::Ti7bit() const
{
return fTi7bit;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const std::string& Rw11UnitTerm::Log() const
{
return fLogFname;
}
 
} // end namespace Retro
/Rw11.ipp
0,0 → 1,78
// $Id: Rw11.ipp 502 2013-04-02 19:29:30Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-01-27 478 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11.ipp 502 2013-04-02 19:29:30Z mueller $
\brief Implemenation (inline) of Rw11.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const boost::shared_ptr<RlinkServer>& Rw11::ServerSPtr() const
{
return fspServ;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkServer& Rw11::Server() const
{
return *fspServ;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkConnect& Rw11::Connect() const
{
return fspServ->Connect();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlogFile& Rw11::LogFile() const
{
return fspServ->LogFile();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline size_t Rw11::NCpu() const
{
return fNCpu;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11::IsStarted() const
{
return fStarted;
}
 
 
} // end namespace Retro
/Rw11UnitVirt.hpp
0,0 → 1,59
// $Id: Rw11UnitVirt.hpp 504 2013-04-13 15:37:24Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-03 494 1.0 Initial version
// 2013-02-22 490 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitVirt.hpp 504 2013-04-13 15:37:24Z mueller $
\brief Declaration of class Rw11UnitVirt.
*/
 
#ifndef included_Retro_Rw11UnitVirt
#define included_Retro_Rw11UnitVirt 1
 
#include "boost/scoped_ptr.hpp"
 
#include "Rw11Unit.hpp"
 
namespace Retro {
 
template <class TV>
class Rw11UnitVirt : public Rw11Unit {
public:
 
Rw11UnitVirt(Rw11Cntl* pcntl, size_t index);
~Rw11UnitVirt();
 
TV* Virt() const;
 
virtual bool Attach(const std::string& url, RerrMsg& emsg);
virtual void Detach();
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
boost::scoped_ptr<TV> fpVirt;
 
};
} // end namespace Retro
 
#include "Rw11UnitVirt.ipp"
 
#endif
/Rw11CntlBase.ipp
0,0 → 1,100
// $Id: Rw11CntlBase.ipp 495 2013-03-06 17:13:48Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-14 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11CntlBase.ipp 495 2013-03-06 17:13:48Z mueller $
\brief Implemenation (inline) of Rw11CntlBase.
*/
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintf.hpp"
 
#include "Rw11CntlBase.hpp"
 
/*!
\class Retro::Rw11CntlBase
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
template <class TU, size_t NU>
inline Rw11CntlBase<TU,NU>::Rw11CntlBase(const std::string& type)
: Rw11Cntl(type)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
template <class TU, size_t NU>
inline Rw11CntlBase<TU,NU>::~Rw11CntlBase()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TU, size_t NU>
inline size_t Rw11CntlBase<TU,NU>::NUnit() const
{
return NU;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TU, size_t NU>
inline TU& Rw11CntlBase<TU,NU>::Unit(size_t index) const
{
return *fspUnit[index];
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TU, size_t NU>
inline const boost::shared_ptr<TU>&
Rw11CntlBase<TU,NU>::UnitSPtr(size_t index) const
{
return fspUnit[index];
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TU, size_t NU>
void Rw11CntlBase<TU,NU>::Dump(std::ostream& os, int ind,
const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11CntlBase @ " << this << std::endl;
os << bl << " fspUnit: " << std::endl;
for (size_t i=0; i<NU; i++) {
os << bl << " " << RosPrintf(i,"d",2) << " : "
<< fspUnit[i].get() << std::endl;
}
Rw11Cntl::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11Probe.cpp
0,0 → 1,100
// $Id: Rw11Probe.cpp 495 2013-03-06 17:13:48Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-05 495 1.0 Initial version
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Probe.cpp 495 2013-03-06 17:13:48Z mueller $
\brief Implemenation of Rw11Probe.
*/
 
#include "librtools/RosFill.hpp"
#include "librtools/RosPrintf.hpp"
 
#include "librlink/RlinkServer.hpp"
 
#include "Rw11Probe.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11Probe
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11Probe::Rw11Probe(uint16_t addr, bool probeint, bool proberem)
: fAddr(addr),
fProbeInt(probeint),
fProbeRem(proberem),
fProbeDone(false),
fFoundInt(false),
fFoundRem(false)
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool Rw11Probe::Found() const
{
if (!fProbeDone) return false;
if (fProbeInt && ! fFoundInt) return false;
if (fProbeRem && ! fFoundRem) return false;
return true;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
char Rw11Probe::IndicatorInt() const
{
if (!fProbeDone) return '?';
if (!fProbeInt) return '-';
return fFoundInt ? 'y' : 'n';
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
char Rw11Probe::IndicatorRem() const
{
if (!fProbeDone) return '?';
if (!fProbeRem) return '-';
return fFoundRem ? 'y' : 'n';
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Probe::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11Probe @ " << this << endl;
 
os << bl << " fAddr: " << RosPrintf(fAddr,"o0",6) << endl;
os << bl << " fProbeInt,Rem: " << fProbeInt << ", " << fProbeInt<< endl;
os << bl << " fProbeDone: " << fProbeDone << endl;
os << bl << " fFoundInt,Rem " << fFoundInt << ", " << fFoundInt<< endl;
return;
}
 
} // end namespace Retro
/Rw11UnitTermBase.hpp
0,0 → 1,55
// $Id: Rw11UnitTermBase.hpp 504 2013-04-13 15:37:24Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-03 494 1.0 Initial version
// 2013-02-22 490 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitTermBase.hpp 504 2013-04-13 15:37:24Z mueller $
\brief Declaration of class Rw11UnitTermBase.
*/
 
#ifndef included_Retro_Rw11UnitTermBase
#define included_Retro_Rw11UnitTermBase 1
 
#include "Rw11UnitTerm.hpp"
 
namespace Retro {
 
template <class TC>
class Rw11UnitTermBase : public Rw11UnitTerm {
public:
 
Rw11UnitTermBase(TC* pcntl, size_t index);
~Rw11UnitTermBase();
 
TC& Cntl() const;
 
virtual void WakeupCntl();
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
TC* fpCntl;
};
} // end namespace Retro
 
#include "Rw11UnitTermBase.ipp"
 
#endif
/Rw11UnitTermBase.ipp
0,0 → 1,85
// $Id: Rw11UnitTermBase.ipp 504 2013-04-13 15:37:24Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-03 494 1.0 Initial version
// 2013-02-22 490 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitTermBase.ipp 504 2013-04-13 15:37:24Z mueller $
\brief Implemenation (inline) of Rw11UnitTermBase.
*/
 
#include "Rw11UnitTermBase.hpp"
 
/*!
\class Retro::Rw11UnitTermBase
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
template <class TC>
Rw11UnitTermBase<TC>::Rw11UnitTermBase(TC* pcntl, size_t index)
: Rw11UnitTerm(pcntl, index),
fpCntl(pcntl)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
template <class TC>
Rw11UnitTermBase<TC>::~Rw11UnitTermBase()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
inline TC& Rw11UnitTermBase<TC>::Cntl() const
{
return *fpCntl;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
inline void Rw11UnitTermBase<TC>::WakeupCntl()
{
fpCntl->Wakeup();
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
template <class TC>
void Rw11UnitTermBase<TC>::Dump(std::ostream& os, int ind,
const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitTermBase @ " << this << std::endl;
os << bl << " fpCntl: " << fpCntl << std::endl;
Rw11UnitTerm::Dump(os, ind, " ^");
return;
}
 
} // end namespace Retro
/Rw11Probe.hpp
0,0 → 1,54
// $Id: Rw11Probe.hpp 495 2013-03-06 17:13:48Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-05 495 1.0 Initial version
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11Probe.hpp 495 2013-03-06 17:13:48Z mueller $
\brief Declaration of class Rw11Probe.
*/
 
#ifndef included_Retro_Rw11Probe
#define included_Retro_Rw11Probe 1
 
namespace Retro {
 
struct Rw11Probe {
uint16_t fAddr;
bool fProbeInt;
bool fProbeRem;
bool fProbeDone;
bool fFoundInt;
bool fFoundRem;
 
explicit Rw11Probe(uint16_t addr = 0, bool probeint = false,
bool proberem = false);
 
bool Found() const;
 
char IndicatorInt() const;
char IndicatorRem() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
};
} // end namespace Retro
 
//#include "Rw11Probe.ipp"
 
#endif
/.cvsignore
0,0 → 1,54
*.dep
/Rw11Virt.cpp
0,0 → 1,70
// $Id: Rw11Virt.cpp 495 2013-03-06 17:13:48Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Virt.cpp 495 2013-03-06 17:13:48Z mueller $
\brief Implemenation of Rw11Virt.
*/
 
#include "librtools/RosFill.hpp"
 
#include "Rw11Virt.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11Virt
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
Rw11Virt::Rw11Virt(Rw11Unit* punit)
: fpUnit(punit),
fUrl(),
fStats()
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11Virt::~Rw11Virt()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11Virt::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11Virt @ " << this << endl;
 
os << bl << " fpUnit: " << fpUnit << endl;
fUrl.Dump(os, ind+2, "fUrl: ");
fStats.Dump(os, ind+2, "fStats: ");
return;
}
 
 
} // end namespace Retro
/Rw11Virt.hpp
0,0 → 1,75
// $Id: Rw11Virt.hpp 495 2013-03-06 17:13:48Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11Virt.hpp 495 2013-03-06 17:13:48Z mueller $
\brief Declaration of class Rw11Virt.
*/
 
#ifndef included_Retro_Rw11Virt
#define included_Retro_Rw11Virt 1
 
#include <string>
#include <iostream>
 
#include "boost/utility.hpp"
 
#include "librtools/RparseUrl.hpp"
#include "librtools/RerrMsg.hpp"
#include "librtools/Rstats.hpp"
#include "Rw11Unit.hpp"
 
namespace Retro {
 
class Rw11Virt : private boost::noncopyable {
public:
explicit Rw11Virt(Rw11Unit* punit);
virtual ~Rw11Virt();
 
Rw11Unit& Unit() const;
Rw11Cntl& Cntl() const;
Rw11Cpu& Cpu() const;
Rw11& W11() const;
RlinkServer& Server() const;
RlogFile& LogFile() const;
 
virtual bool Open(const std::string& url, RerrMsg& emsg) = 0;
 
const Rstats& Stats() const;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
// statistics counter indices
enum stats {
kDimStat = 0
};
 
protected:
Rw11Unit* fpUnit; //<! back ref to unit
RparseUrl fUrl;
Rstats fStats; //!< statistics
};
} // end namespace Retro
 
#include "Rw11Virt.ipp"
 
#endif
/Rw11Virt.ipp
0,0 → 1,85
// $Id: Rw11Virt.ipp 495 2013-03-06 17:13:48Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-16 489 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Virt.ipp 495 2013-03-06 17:13:48Z mueller $
\brief Implemenation (inline) of Rw11Virt.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11Unit& Rw11Virt::Unit() const
{
return *fpUnit;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11Cntl& Rw11Virt::Cntl() const
{
return fpUnit->CntlBase();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11Cpu& Rw11Virt::Cpu() const
{
return fpUnit->Cpu();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11& Rw11Virt::W11() const
{
return fpUnit->W11();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkServer& Rw11Virt::Server() const
{
return fpUnit->Server();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlogFile& Rw11Virt::LogFile() const
{
return fpUnit->LogFile();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11Virt::Stats() const
{
return fStats;
}
 
} // end namespace Retro
/Rw11UnitDL11.cpp
0,0 → 1,67
// $Id: Rw11UnitDL11.cpp 504 2013-04-13 15:37:24Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-03 494 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11UnitDL11.cpp 504 2013-04-13 15:37:24Z mueller $
\brief Implemenation of Rw11UnitDL11.
*/
 
#include "boost/bind.hpp"
 
#include "librtools/RosFill.hpp"
#include "Rw11CntlDL11.hpp"
 
#include "Rw11UnitDL11.hpp"
 
using namespace std;
 
/*!
\class Retro::Rw11UnitDL11
\brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Constructor
 
Rw11UnitDL11::Rw11UnitDL11(Rw11CntlDL11* pcntl, size_t index)
: Rw11UnitTermBase<Rw11CntlDL11>(pcntl, index)
{}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
Rw11UnitDL11::~Rw11UnitDL11()
{}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
void Rw11UnitDL11::Dump(std::ostream& os, int ind, const char* text) const
{
RosFill bl(ind);
os << bl << (text?text:"--") << "Rw11UnitDL11 @ " << this << endl;
Rw11UnitTermBase<Rw11CntlDL11>::Dump(os, ind, " ^");
return;
}
} // end namespace Retro
/Rw11UnitDL11.hpp
0,0 → 1,54
// $Id: Rw11UnitDL11.hpp 504 2013-04-13 15:37:24Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-03 494 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11UnitDL11.hpp 504 2013-04-13 15:37:24Z mueller $
\brief Declaration of class Rw11UnitDL11.
*/
 
#ifndef included_Retro_Rw11UnitDL11
#define included_Retro_Rw11UnitDL11 1
 
#include "Rw11VirtTerm.hpp"
 
#include "Rw11UnitTermBase.hpp"
 
namespace Retro {
 
class Rw11CntlDL11; // forw decl to avoid circular incl
 
class Rw11UnitDL11 : public Rw11UnitTermBase<Rw11CntlDL11> {
public:
 
Rw11UnitDL11(Rw11CntlDL11* pcntl, size_t index);
~Rw11UnitDL11();
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
 
};
} // end namespace Retro
 
//#include "Rw11UnitDL11.ipp"
 
#endif
/Rw11Cntl.ipp
0,0 → 1,159
// $Id: Rw11Cntl.ipp 495 2013-03-06 17:13:48Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-05 483 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11Cntl.ipp 495 2013-03-06 17:13:48Z mueller $
\brief Implemenation (inline) of Rw11Cntl.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11Cntl::SetCpu(Rw11Cpu* pcpu)
{
fpCpu = pcpu;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11Cpu& Rw11Cntl::Cpu() const
{
return *fpCpu;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline Rw11& Rw11Cntl::W11() const
{
return fpCpu->W11();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkServer& Rw11Cntl::Server() const
{
return fpCpu->Server();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlinkConnect& Rw11Cntl::Connect() const
{
return fpCpu->Connect();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline RlogFile& Rw11Cntl::LogFile() const
{
return fpCpu->LogFile();
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const std::string& Rw11Cntl::Type() const
{
return fType;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const std::string& Rw11Cntl::Name() const
{
return fName;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint16_t Rw11Cntl::Base() const
{
return fBase;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline int Rw11Cntl::Lam() const
{
return fLam;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cntl::Enable() const
{
return fEnable;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rw11Probe& Rw11Cntl::ProbeStatus() const
{
return fProbe;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline bool Rw11Cntl::IsStarted() const
{
return fStarted;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11Cntl::SetTraceLevel(uint32_t level)
{
fTraceLevel = level;
return;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline uint32_t Rw11Cntl::TraceLevel() const
{
return fTraceLevel;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const Rstats& Rw11Cntl::Stats() const
{
return fStats;
}
 
} // end namespace Retro
/Rw11VirtTermPty.hpp
0,0 → 1,59
// $Id: Rw11VirtTermPty.hpp 504 2013-04-13 15:37:24Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-24 492 0.1 First draft
// ---------------------------------------------------------------------------
 
 
/*!
\file
\version $Id: Rw11VirtTermPty.hpp 504 2013-04-13 15:37:24Z mueller $
\brief Declaration of class Rw11VirtTermPty.
*/
 
#ifndef included_Retro_Rw11VirtTermPty
#define included_Retro_Rw11VirtTermPty 1
 
#include <poll.h>
 
#include "Rw11VirtTerm.hpp"
 
namespace Retro {
 
class Rw11VirtTermPty : public Rw11VirtTerm {
public:
 
explicit Rw11VirtTermPty(Rw11Unit* punit);
~Rw11VirtTermPty();
 
bool Open(const std::string& url, RerrMsg& emsg);
 
virtual bool Snd(const uint8_t* data, size_t count, RerrMsg& emsg);
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
protected:
int RcvPollHandler(const pollfd& pfd);
 
protected:
int fFd; //<! fd for pty master side
};
} // end namespace Retro
 
//#include "Rw11VirtTermPty.ipp"
 
#endif
/Rw11VirtTerm.hpp
0,0 → 1,70
// $Id: Rw11VirtTerm.hpp 504 2013-04-13 15:37:24Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-13 488 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTerm.hpp 504 2013-04-13 15:37:24Z mueller $
\brief Declaration of class Rw11VirtTerm.
*/
 
#ifndef included_Retro_Rw11VirtTerm
#define included_Retro_Rw11VirtTerm 1
 
#include "boost/function.hpp"
 
#include "Rw11Virt.hpp"
 
namespace Retro {
 
class Rw11VirtTerm : public Rw11Virt {
public:
typedef boost::function<bool(const uint8_t*, size_t)> rcvcbfo_t;
 
explicit Rw11VirtTerm(Rw11Unit* punit);
~Rw11VirtTerm();
 
virtual const std::string& ChannelId() const;
 
void SetupRcvCallback(const rcvcbfo_t& rcvcbfo);
virtual bool Snd(const uint8_t* data, size_t count, RerrMsg& emsg) = 0;
 
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
 
static Rw11VirtTerm* New(const std::string& url, Rw11Unit* punit,
RerrMsg& emsg);
 
// statistics counter indices
enum stats {
kStatNVTRcvPoll = Rw11Virt::kDimStat,
kStatNVTSnd,
kStatNVTRcvByt,
kStatNVTSndByt,
kDimStat
};
 
protected:
std::string fChannelId; //!< channel id
rcvcbfo_t fRcvCb; //!< receive callback fobj
};
} // end namespace Retro
 
#include "Rw11VirtTerm.ipp"
 
#endif
/Rw11VirtTerm.ipp
0,0 → 1,47
// $Id: Rw11VirtTerm.ipp 504 2013-04-13 15:37:24Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, 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 complete details.
//
// Revision History:
// Date Rev Version Comment
// 2013-03-06 495 1.0 Initial version
// 2013-02-19 490 0.1 First draft
// ---------------------------------------------------------------------------
 
/*!
\file
\version $Id: Rw11VirtTerm.ipp 504 2013-04-13 15:37:24Z mueller $
\brief Implemenation (inline) of Rw11VirtTerm.
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline const std::string& Rw11VirtTerm::ChannelId() const
{
return fChannelId;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
inline void Rw11VirtTerm::SetupRcvCallback(const rcvcbfo_t& rcvcbfo)
{
fRcvCb = rcvcbfo;
return;
}
 
} // end namespace Retro
/.
. Property changes : Added: svn:ignore ## -0,0 +1,34 ## +*.dep_ghdl +*.dep_isim +*.dep_xst +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +isim +isim.log +isim.wdb +fuse.log +*_[sft]sim.vhd +*_tsim.sdf +*_xst.log +*_tra.log +*_twr.log +*_map.log +*_par.log +*_tsi.log +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log +*.dep

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.