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