mirror of
https://github.com/wfjm/w11.git
synced 2026-02-15 12:36:34 +00:00
- interim release w11a_V0.57 (untagged)
- new C++ and Tcl based backend server supports now RK11 handling - w11a systems operate with rlink over USB on nexsy2 and nexsy3 boards. See w11a_os_guide.txt for details
This commit is contained in:
@@ -25,9 +25,12 @@ 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 += Rw11CntlDL11.o Rw11UnitDL11.o
|
||||
OBJ_all += Rw11CntlRK11.o Rw11UnitRK11.o
|
||||
OBJ_all += Rw11Virt.o
|
||||
OBJ_all += Rw11VirtTerm.o Rw11VirtTermPty.o Rw11VirtTermTcp.o
|
||||
OBJ_all += Rw11VirtDisk.o Rw11VirtDiskFile.o
|
||||
#
|
||||
DEP_all = $(OBJ_all:.o=.dep)
|
||||
#
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11Cntl.hpp 495 2013-03-06 17:13:48Z mueller $
|
||||
// $Id: Rw11Cntl.hpp 508 2013-04-20 18:43:28Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11Cntl.hpp 495 2013-03-06 17:13:48Z mueller $
|
||||
\version $Id: Rw11Cntl.hpp 508 2013-04-20 18:43:28Z mueller $
|
||||
\brief Declaration of class Rw11Cntl.
|
||||
*/
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace Retro {
|
||||
bool fEnable; //!< enable flag
|
||||
bool fStarted; //!< true if Start() called
|
||||
Rw11Probe fProbe; //!< controller probe context
|
||||
uint32_t fTraceLevel; //!< trace level; 0=off;1=attn
|
||||
uint32_t fTraceLevel; //!< trace level; 0=off;1=cntl
|
||||
RlinkCommandList fPrimClist; //!< clist for attn primary info
|
||||
Rstats fStats; //!< statistics
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11CntlDL11.cpp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11CntlDL11.cpp 508 2013-04-20 18:43:28Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -13,20 +13,24 @@
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 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 504 2013-04-13 15:37:24Z mueller $
|
||||
\version $Id: Rw11CntlDL11.cpp 508 2013-04-20 18:43:28Z 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"
|
||||
|
||||
@@ -141,6 +145,8 @@ 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;
|
||||
|
||||
Rw11CntlBase<Rw11UnitDL11,1>::Dump(os, ind, " ^");
|
||||
return;
|
||||
}
|
||||
@@ -161,6 +167,42 @@ int Rw11CntlDL11::AttnHandler(const RlinkServer::AttnArgs& args)
|
||||
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);
|
||||
}
|
||||
|
||||
623
tools/src/librw11/Rw11CntlRK11.cpp
Normal file
623
tools/src/librw11/Rw11CntlRK11.cpp
Normal file
@@ -0,0 +1,623 @@
|
||||
// $Id: Rw11CntlRK11.cpp 509 2013-04-21 20:46:20Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
// Other credits:
|
||||
// the boot code 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
|
||||
// 2013-04-20 508 1.0 Initial version
|
||||
// 2013-02-10 485 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11CntlRK11.cpp 509 2013-04-21 20:46:20Z 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_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_CRESET;
|
||||
const uint16_t Rw11CntlRK11::kRKCS_WRITE;
|
||||
const uint16_t Rw11CntlRK11::kRKCS_READ;
|
||||
const uint16_t Rw11CntlRK11::kRKCS_WCHK;
|
||||
const uint16_t Rw11CntlRK11::kRKCS_SEEK;
|
||||
const uint16_t Rw11CntlRK11::kRKCS_RCHK;
|
||||
const uint16_t Rw11CntlRK11::kRKCS_DRESET;
|
||||
const uint16_t Rw11CntlRK11::kRKCS_WLOCK;
|
||||
const uint16_t Rw11CntlRK11::kRKCS_M_GO;
|
||||
|
||||
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_busy(false),
|
||||
fRd_rkcs(0),
|
||||
fRd_rkda(0),
|
||||
fRd_addr(0),
|
||||
fRd_lba(0),
|
||||
fRd_nwrd(0),
|
||||
fRd_ovr(false)
|
||||
{
|
||||
// must here because Unit have a back-pointer (not available at Rw11CntlBase)
|
||||
for (size_t i=0; i<NUnit(); i++) {
|
||||
fspUnit[i].reset(new Rw11UnitRK11(this, i));
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! 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("Rw11CntlDL11::Start",
|
||||
"Bad state: started, no lam, not enable, not found");
|
||||
|
||||
// setup primary info clist
|
||||
fPrimClist.Clear();
|
||||
Cpu().AddIbrb(fPrimClist, fBase);
|
||||
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.AddIbrb(clist, fBase);
|
||||
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[] = { // rk05 boot loader - from simh pdp11_rk.c
|
||||
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
|
||||
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_busy: " << fRd_busy << 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_ovr: " << fRd_ovr << endl;
|
||||
|
||||
Rw11CntlBase<Rw11UnitRK11,8>::Dump(os, ind, " ^");
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int Rw11CntlRK11::AttnHandler(const RlinkServer::AttnArgs& args)
|
||||
{
|
||||
RlinkCommandList* pclist;
|
||||
size_t off;
|
||||
|
||||
GetPrimInfo(args, pclist, off);
|
||||
|
||||
uint16_t rkwc = (*pclist)[off+fPC_rkwc].Data();
|
||||
uint16_t rkba = (*pclist)[off+fPC_rkba].Data();
|
||||
uint16_t rkda = (*pclist)[off+fPC_rkda].Data();
|
||||
//uint16_t rkmr = (*pclist)[off+fPC_rkmr].Data();
|
||||
uint16_t rkcs = (*pclist)[off+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 = (2*nwrd+unit.BlockSize()-1)/unit.BlockSize();
|
||||
|
||||
uint16_t rker = 0;
|
||||
uint16_t rkds = unit.Rkds();
|
||||
|
||||
if (fTraceLevel>0) {
|
||||
RlogMsg lmsg(LogFile());
|
||||
lmsg << "-I RK11 cs=" << RosPrintBvi(rkcs,8)
|
||||
<< " da=" << RosPrintBvi(rkda,8)
|
||||
<< " ad=" << RosPrintBvi(addr,8,18)
|
||||
<< " fu=" << fu
|
||||
<< " dchs=" << dr
|
||||
<< "," << RosPrintf(cy,"d",3)
|
||||
<< "," << hd
|
||||
<< "," << RosPrintf(se,"d",2)
|
||||
<< " lba,nw=" << RosPrintf(lba,"d",4)
|
||||
<< "," << RosPrintf(nwrd,"d",5);
|
||||
}
|
||||
|
||||
// check for general abort conditions
|
||||
if (fu != kRKCS_CRESET && // function not control reset
|
||||
(!unit.Virt())) { // and drive not attached
|
||||
rker = kRKER_M_NXD; // --> abort with NXD error
|
||||
|
||||
} else if (fu != kRKCS_WRITE && // function neither write
|
||||
fu != kRKCS_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 == kRKCS_SEEK || fu == kRKCS_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);
|
||||
bool queue = false;
|
||||
|
||||
// now handle the functions
|
||||
if (fu == kRKCS_CRESET) { // Control reset -----------------
|
||||
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_CRESET);
|
||||
fRd_busy = false;
|
||||
|
||||
} else if (fu == kRKCS_WRITE) { // Write -------------------------
|
||||
// Note: WRITE+FMT is just WRITE
|
||||
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; // not yet supported FIXME
|
||||
queue = true;
|
||||
|
||||
} else if (fu == kRKCS_READ) { // Read --------------------------
|
||||
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; // not yet supported FIXME
|
||||
queue = true;
|
||||
|
||||
} else if (fu == kRKCS_WCHK) { // Write Check -------------------
|
||||
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; // not yet supported FIXME
|
||||
queue = true;
|
||||
|
||||
} else if (fu == kRKCS_SEEK) { // Seek --------------------------
|
||||
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 == kRKCS_RCHK) { // Read Check --------------------
|
||||
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; // not yet supported FIXME
|
||||
queue = true;
|
||||
|
||||
} else if (fu == kRKCS_DRESET) { // Drive Reset -------------------
|
||||
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
|
||||
cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr); // issue seek done
|
||||
|
||||
} else if (fu == kRKCS_WLOCK) { // Write Lock --------------------
|
||||
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 (queue) { // to be handled in RdmaHandlder
|
||||
if (rker) { // abort on case of errors
|
||||
cpu.AddWibr(clist, fBase+kRKER, rker);
|
||||
cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
|
||||
LogRker(rker);
|
||||
} else { // or queue action
|
||||
fRd_busy = true;
|
||||
fRd_rkcs = rkcs;
|
||||
fRd_rkda = rkda;
|
||||
fRd_addr = addr;
|
||||
fRd_lba = lba;
|
||||
fRd_nwrd = nwrd;
|
||||
fRd_ovr = ovr;
|
||||
Server().QueueAction(boost::bind(&Rw11CntlRK11::RdmaHandler, this));
|
||||
}
|
||||
|
||||
} else { // handled here
|
||||
Server().Exec(clist);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int Rw11CntlRK11::RdmaHandler()
|
||||
{
|
||||
uint16_t rker = 0;
|
||||
uint16_t fu = (fRd_rkcs>>kRKCS_V_FUNC) & kRKCS_B_FUNC;
|
||||
uint16_t dr = (fRd_rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
|
||||
Rw11UnitRK11& unit = *fspUnit[dr];
|
||||
Rw11Cpu& cpu = Cpu();
|
||||
|
||||
uint8_t buf[512];
|
||||
|
||||
if (fu == kRKCS_WRITE) { // Write -------------------------
|
||||
// Note: WRITE+FMT is like WRITE
|
||||
RlinkCommandList clist;
|
||||
size_t bsize = (fRd_nwrd>256) ? 256 : fRd_nwrd;
|
||||
cpu.AddRMem(clist, fRd_addr, (uint16_t*) buf, bsize,
|
||||
Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap);
|
||||
Server().Exec(clist);
|
||||
// FIXME_code: handle rdma I/O error
|
||||
RerrMsg emsg;
|
||||
bool rc = unit.VirtWrite(fRd_lba, 1, buf, emsg);
|
||||
if (!rc) {
|
||||
RlogMsg lmsg(LogFile());
|
||||
lmsg << emsg;
|
||||
rker |= kRKER_M_CSE; // forward disk I/O error
|
||||
}
|
||||
if (rker == 0) {
|
||||
fRd_nwrd -= bsize;
|
||||
fRd_addr += 2*bsize;
|
||||
fRd_lba += 1;
|
||||
}
|
||||
if (rker==0 && fRd_nwrd>0) // not error and not yet done
|
||||
return 1; // requeue
|
||||
|
||||
} else if (fu == kRKCS_READ) {
|
||||
if ((fRd_rkcs&kRKCS_M_FMT) == 0) { // Read --------------------------
|
||||
RerrMsg emsg;
|
||||
bool rc = unit.VirtRead(fRd_lba, 1, buf, emsg);
|
||||
if (!rc) {
|
||||
RlogMsg lmsg(LogFile());
|
||||
lmsg << emsg;
|
||||
rker |= kRKER_M_CSE; // forward disk I/O error
|
||||
}
|
||||
|
||||
if (rker == 0) {
|
||||
RlinkCommandList clist;
|
||||
size_t bsize = (fRd_nwrd>256) ? 256 : fRd_nwrd;
|
||||
cpu.AddWMem(clist, fRd_addr, (uint16_t*) buf, bsize,
|
||||
Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap);
|
||||
Server().Exec(clist);
|
||||
// FIXME_code: handle rdma I/O error
|
||||
fRd_nwrd -= bsize;
|
||||
fRd_addr += 2*bsize;
|
||||
fRd_lba += 1;
|
||||
}
|
||||
if (rker==0 && fRd_nwrd>0) // not error and not yet done
|
||||
return 1; // requeue
|
||||
|
||||
} else { // Read Format -------------------
|
||||
uint16_t cy = fRd_lba / (unit.NHead()*unit.NSector());
|
||||
uint16_t da = cy<<kRKDA_V_CYL;
|
||||
RlinkCommandList clist;
|
||||
cpu.AddWMem(clist, fRd_addr, &da, 1,
|
||||
Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap);
|
||||
Server().Exec(clist);
|
||||
// FIXME_code: handle rdma I/O error
|
||||
fRd_nwrd -= 1;
|
||||
fRd_addr += 2;
|
||||
fRd_lba += 1;
|
||||
if (rker==0 && fRd_nwrd>0) // not error and not yet done
|
||||
return 1; // requeue
|
||||
}
|
||||
|
||||
} else if (fu == kRKCS_WCHK) { // Write Check -------------------
|
||||
uint16_t bufmem[256];
|
||||
RlinkCommandList clist;
|
||||
size_t bsize = (fRd_nwrd>256) ? 256 : fRd_nwrd;
|
||||
cpu.AddRMem(clist, fRd_addr, bufmem, bsize,
|
||||
Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap);
|
||||
Server().Exec(clist);
|
||||
// FIXME_code: handle rdma I/O error
|
||||
RerrMsg emsg;
|
||||
bool rc = unit.VirtRead(fRd_lba, 1, buf, emsg);
|
||||
if (!rc) {
|
||||
RlogMsg lmsg(LogFile());
|
||||
lmsg << emsg;
|
||||
rker |= kRKER_M_CSE; // forward disk I/O error
|
||||
}
|
||||
if (rker == 0) {
|
||||
uint16_t* pmem = bufmem;
|
||||
uint16_t* pdsk = (uint16_t*) &buf;
|
||||
for (size_t i=0; i<bsize; i++) {
|
||||
if (*pmem++ != *pdsk++) rker |= kRKER_M_WCE;
|
||||
}
|
||||
fRd_nwrd -= bsize;
|
||||
fRd_addr += 2*bsize;
|
||||
fRd_lba += 1;
|
||||
}
|
||||
// determine abort criterion
|
||||
bool stop = (rker & ~kRKER_M_WCE) != 0 ||
|
||||
((rker & kRKER_M_WCE) && (fRd_rkcs & kRKCS_M_SSE));
|
||||
if (!stop && fRd_nwrd>0) // not error and not yet done
|
||||
return 1; // requeue
|
||||
|
||||
} else if (fu == kRKCS_RCHK) { // Read Check --------------------
|
||||
// Note: no DMA transfer done; done here to keep logic similar to read
|
||||
size_t bsize = (fRd_nwrd>256) ? 256 : fRd_nwrd;
|
||||
fRd_nwrd -= bsize;
|
||||
fRd_addr += 2*bsize;
|
||||
fRd_lba += 1;
|
||||
if (rker==0 && fRd_nwrd>0) // not error and not yet done
|
||||
return 1; // requeue
|
||||
|
||||
} else {
|
||||
throw Rexception("Rw11CntlDL11::RdmaHandler",
|
||||
"Bad state: bad function code");
|
||||
}
|
||||
|
||||
// common handling for dma transfer completion
|
||||
if (fRd_ovr) rker |= kRKER_M_OVR;
|
||||
|
||||
RlinkCommandList clist;
|
||||
|
||||
uint16_t ba = fRd_addr & 0177776; // get lower 16 bits
|
||||
uint16_t mex = (fRd_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(fRd_lba, cy,hd,se);
|
||||
uint16_t da = (fRd_rkda & kRKDA_M_DRSEL) | (cy<<kRKDA_V_CYL) |
|
||||
(hd<<kRKDA_V_SUR) | se;
|
||||
|
||||
cpu.AddIbrb(clist, fBase);
|
||||
if (rker) {
|
||||
cpu.AddWibr(clist, fBase+kRKER, rker);
|
||||
LogRker(rker);
|
||||
}
|
||||
cpu.AddWibr(clist, fBase+kRKWC, uint16_t((-fRd_nwrd)&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);
|
||||
|
||||
Server().Exec(clist);
|
||||
|
||||
fRd_busy = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void Rw11CntlRK11::LogRker(uint16_t rker)
|
||||
{
|
||||
RlogMsg lmsg(LogFile());
|
||||
lmsg << "-E RK11 er=" << RosPrintBvi(rker,8) << " ERROR ABORT";
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
154
tools/src/librw11/Rw11CntlRK11.hpp
Normal file
154
tools/src/librw11/Rw11CntlRK11.hpp
Normal file
@@ -0,0 +1,154 @@
|
||||
// $Id: Rw11CntlRK11.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-10 485 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11CntlRK11.hpp 509 2013-04-21 20:46:20Z mueller $
|
||||
\brief Declaration of class Rw11CntlRK11.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_Rw11CntlRK11
|
||||
#define included_Retro_Rw11CntlRK11 1
|
||||
|
||||
#include "Rw11CntlBase.hpp"
|
||||
#include "Rw11UnitRK11.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);
|
||||
|
||||
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 register address offset
|
||||
static const uint16_t kRKER = 002; //!< RKER register address offset
|
||||
static const uint16_t kRKCS = 004; //!< RKCS register address offset
|
||||
static const uint16_t kRKWC = 006; //!< RKWC register address offset
|
||||
static const uint16_t kRKBA = 010; //!< RKBA register address offset
|
||||
static const uint16_t kRKDA = 012; //!< RKDA register address offset
|
||||
static const uint16_t kRKMR = 014; //!< RKMR register address 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_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_CRESET = 0;
|
||||
static const uint16_t kRKCS_WRITE = 1;
|
||||
static const uint16_t kRKCS_READ = 2;
|
||||
static const uint16_t kRKCS_WCHK = 3;
|
||||
static const uint16_t kRKCS_SEEK = 4;
|
||||
static const uint16_t kRKCS_RCHK = 5;
|
||||
static const uint16_t kRKCS_DRESET = 6;
|
||||
static const uint16_t kRKCS_WLOCK = 7;
|
||||
static const uint16_t kRKCS_M_GO = kWBit00;
|
||||
|
||||
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;
|
||||
|
||||
protected:
|
||||
int AttnHandler(const RlinkServer::AttnArgs& args);
|
||||
int RdmaHandler();
|
||||
void LogRker(uint16_t rker);
|
||||
|
||||
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
|
||||
|
||||
bool fRd_busy; //!< Rdma: busy flag
|
||||
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
|
||||
bool fRd_ovr; //!< Rdma: overrun condition found
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
//#include "Rw11CntlRK11.ipp"
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11Cpu.cpp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11Cpu.cpp 506 2013-04-14 21:54:03Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -13,13 +13,14 @@
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 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 504 2013-04-13 15:37:24Z mueller $
|
||||
\version $Id: Rw11Cpu.cpp 506 2013-04-14 21:54:03Z mueller $
|
||||
\brief Implemenation of Rw11Cpu.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
@@ -94,6 +95,10 @@ const uint16_t Rw11Cpu::kCp_cpurust_recrsv;
|
||||
const uint16_t Rw11Cpu::kCp_cpurust_sfail;
|
||||
const uint16_t Rw11Cpu::kCp_cpurust_vfail;
|
||||
|
||||
const uint16_t Rw11Cpu::kCp_ah_m_addr;
|
||||
const uint16_t Rw11Cpu::kCp_ah_m_22bit;
|
||||
const uint16_t Rw11Cpu::kCp_ah_m_ubmap;
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Constructor
|
||||
|
||||
@@ -262,6 +267,51 @@ int Rw11Cpu::AddWibr(RlinkCommandList& clist, uint16_t ibaddr, uint16_t data)
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! 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) & kCp_ah_m_addr;
|
||||
ah |= mode & (kCp_ah_m_22bit|kCp_ah_m_ubmap);
|
||||
int ind = clist.AddWreg(fBase+kCp_addr_al, al);
|
||||
clist.AddWreg(fBase+kCp_addr_ah, ah);
|
||||
return ind;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int Rw11Cpu::AddRMem(RlinkCommandList& clist, uint32_t addr,
|
||||
uint16_t* buf, size_t size, uint16_t mode)
|
||||
{
|
||||
int ind = AddLalh(clist, addr, mode);
|
||||
while (size > 0) {
|
||||
size_t bsize = (size>256) ? 256 : size;
|
||||
clist.AddRblk(fBase+kCp_addr_memi, 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)
|
||||
{
|
||||
int ind = AddLalh(clist, addr, mode);
|
||||
while (size > 0) {
|
||||
size_t bsize = (size>256) ? 256 : size;
|
||||
clist.AddWblk(fBase+kCp_addr_memi, 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)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11Cpu.hpp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11Cpu.hpp 506 2013-04-14 21:54:03Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -13,6 +13,7 @@
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 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
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -20,7 +21,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11Cpu.hpp 504 2013-04-13 15:37:24Z mueller $
|
||||
\version $Id: Rw11Cpu.hpp 506 2013-04-14 21:54:03Z mueller $
|
||||
\brief Declaration of class Rw11Cpu.
|
||||
*/
|
||||
|
||||
@@ -55,6 +56,7 @@ namespace Retro {
|
||||
typedef cmap_t::const_iterator cmap_cit_t;
|
||||
typedef cmap_t::value_type cmap_val_t;
|
||||
|
||||
|
||||
explicit Rw11Cpu(const std::string& type);
|
||||
virtual ~Rw11Cpu();
|
||||
|
||||
@@ -82,6 +84,15 @@ namespace Retro {
|
||||
int AddWibr(RlinkCommandList& clist, uint16_t ibaddr,
|
||||
uint16_t data);
|
||||
|
||||
int AddLalh(RlinkCommandList& clist, uint32_t addr,
|
||||
uint16_t mode=kCp_ah_m_22bit);
|
||||
int AddRMem(RlinkCommandList& clist, uint32_t addr,
|
||||
uint16_t* buf, size_t size,
|
||||
uint16_t mode=kCp_ah_m_22bit);
|
||||
int AddWMem(RlinkCommandList& clist, uint32_t addr,
|
||||
const uint16_t* buf, size_t size,
|
||||
uint16_t mode=kCp_ah_m_22bit);
|
||||
|
||||
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,
|
||||
@@ -145,6 +156,10 @@ namespace Retro {
|
||||
static const uint16_t kCp_cpurust_sfail = 0xa; //!< sequencer failure
|
||||
static const uint16_t kCp_cpurust_vfail = 0xb; //!< vmbox failure
|
||||
|
||||
static const uint16_t kCp_ah_m_addr = 0x003f; //!<
|
||||
static const uint16_t kCp_ah_m_22bit = kWBit06; //!<
|
||||
static const uint16_t kCp_ah_m_ubmap = kWBit07; //!<
|
||||
|
||||
private:
|
||||
Rw11Cpu() {} //!< default ctor blocker
|
||||
|
||||
|
||||
116
tools/src/librw11/Rw11UnitDisk.cpp
Normal file
116
tools/src/librw11/Rw11UnitDisk.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
// $Id: Rw11UnitDisk.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-04-19 507 1.0 Initial version
|
||||
// 2013-02-19 490 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11UnitDisk.cpp 509 2013-04-21 20:46:20Z 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(),
|
||||
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::<ctor>",
|
||||
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 << " 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
|
||||
78
tools/src/librw11/Rw11UnitDisk.hpp
Normal file
78
tools/src/librw11/Rw11UnitDisk.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
// $Id: Rw11UnitDisk.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-19 507 1.0 Initial version
|
||||
// 2013-02-19 490 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11UnitDisk.hpp 509 2013-04-21 20:46:20Z 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;
|
||||
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);
|
||||
|
||||
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;
|
||||
size_t fNCyl;
|
||||
size_t fNHead;
|
||||
size_t fNSect;
|
||||
size_t fBlksize;
|
||||
size_t fNBlock;
|
||||
bool fWProt;
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#include "Rw11UnitDisk.ipp"
|
||||
|
||||
#endif
|
||||
116
tools/src/librw11/Rw11UnitDisk.ipp
Normal file
116
tools/src/librw11/Rw11UnitDisk.ipp
Normal file
@@ -0,0 +1,116 @@
|
||||
// $Id: Rw11UnitDisk.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-19 507 1.0 Initial version
|
||||
// 2013-02-19 490 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11UnitDisk.ipp 509 2013-04-21 20:46:20Z 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 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 void Rw11UnitDisk::SetWProt(bool wprot)
|
||||
{
|
||||
fWProt = wprot;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool Rw11UnitDisk::WProt() const
|
||||
{
|
||||
return fWProt;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Retro
|
||||
57
tools/src/librw11/Rw11UnitDiskBase.hpp
Normal file
57
tools/src/librw11/Rw11UnitDiskBase.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// $Id: Rw11UnitDiskBase.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-22 490 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11UnitDiskBase.hpp 509 2013-04-21 20:46:20Z 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 AttachSetup();
|
||||
virtual void DetachCleanup();
|
||||
|
||||
protected:
|
||||
TC* fpCntl;
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#include "Rw11UnitDiskBase.ipp"
|
||||
|
||||
#endif
|
||||
98
tools/src/librw11/Rw11UnitDiskBase.ipp
Normal file
98
tools/src/librw11/Rw11UnitDiskBase.ipp
Normal file
@@ -0,0 +1,98 @@
|
||||
// $Id: Rw11UnitDiskBase.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-14 506 1.0 Initial version
|
||||
// 2013-02-22 490 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11UnitDiskBase.ipp 509 2013-04-21 20:46:20Z 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>::AttachSetup()
|
||||
{
|
||||
Virt()->Setup(BlockSize(), NBlock());
|
||||
Cntl().UnitSetup(Index());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
template <class TC>
|
||||
void Rw11UnitDiskBase<TC>::DetachCleanup()
|
||||
{
|
||||
SetWProt(false);
|
||||
Cntl().UnitSetup(Index());
|
||||
return;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
78
tools/src/librw11/Rw11UnitRK11.cpp
Normal file
78
tools/src/librw11/Rw11UnitRK11.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
// $Id: Rw11UnitRK11.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-04-20 508 1.0 Initial version
|
||||
// 2013-02-05 483 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11UnitRK11.cpp 509 2013-04-21 20:46:20Z 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";
|
||||
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
|
||||
54
tools/src/librw11/Rw11UnitRK11.hpp
Normal file
54
tools/src/librw11/Rw11UnitRK11.hpp
Normal file
@@ -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
|
||||
53
tools/src/librw11/Rw11UnitRK11.ipp
Normal file
53
tools/src/librw11/Rw11UnitRK11.ipp
Normal file
@@ -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
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11UnitTerm.cpp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11UnitTerm.cpp 508 2013-04-20 18:43:28Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -19,14 +19,16 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11UnitTerm.cpp 504 2013-04-13 15:37:24Z mueller $
|
||||
\version $Id: Rw11UnitTerm.cpp 508 2013-04-20 18:43:28Z 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"
|
||||
|
||||
@@ -45,9 +47,19 @@ namespace Retro {
|
||||
|
||||
Rw11UnitTerm::Rw11UnitTerm(Rw11Cntl* pcntl, size_t index)
|
||||
: Rw11UnitVirt<Rw11VirtTerm>(pcntl, index),
|
||||
fRcv7bit(false),
|
||||
fRcvQueue()
|
||||
{}
|
||||
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
|
||||
@@ -68,6 +80,42 @@ const std::string& Rw11UnitTerm::ChannelId() const
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! 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|crlf|", 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();
|
||||
@@ -111,12 +159,75 @@ size_t Rw11UnitTerm::Rcv(uint8_t* buf, size_t count)
|
||||
bool Rw11UnitTerm::Snd(const uint8_t* buf, size_t count)
|
||||
{
|
||||
bool ok = true;
|
||||
if (fpVirt) {
|
||||
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(buf, count, emsg);
|
||||
ok = fpVirt->Snd(bufout, bufcnt, emsg);
|
||||
// FIXME_code: handler errors
|
||||
} else {
|
||||
for (size_t i=0; i<count; i++) cout << buf[i] << flush;
|
||||
|
||||
} 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;
|
||||
}
|
||||
@@ -131,7 +242,11 @@ bool Rw11UnitTerm::RcvCallback(const uint8_t* buf, size_t count)
|
||||
boost::lock_guard<RlinkConnect> lock(Connect());
|
||||
|
||||
bool que_empty_old = fRcvQueue.empty();
|
||||
for (size_t i=0; i<count; i++) fRcvQueue.push_back(buf[i]);
|
||||
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;
|
||||
@@ -153,7 +268,9 @@ void Rw11UnitTerm::Dump(std::ostream& os, int ind, const char* text) const
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "Rw11UnitTerm @ " << this << endl;
|
||||
|
||||
os << bl << " fRcv7bit: " << fRcv7bit << 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();
|
||||
@@ -179,6 +296,12 @@ void Rw11UnitTerm::Dump(std::ostream& os, int ind, const char* text) const
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11UnitTerm.hpp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11UnitTerm.hpp 508 2013-04-20 18:43:28Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -13,6 +13,7 @@
|
||||
//
|
||||
// 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-02-19 490 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -20,13 +21,15 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11UnitTerm.hpp 504 2013-04-13 15:37:24Z mueller $
|
||||
\version $Id: Rw11UnitTerm.hpp 508 2013-04-20 18:43:28Z mueller $
|
||||
\brief Declaration of class Rw11UnitTerm.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_Rw11UnitTerm
|
||||
#define included_Retro_Rw11UnitTerm 1
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <deque>
|
||||
|
||||
#include "Rw11VirtTerm.hpp"
|
||||
@@ -42,8 +45,15 @@ namespace Retro {
|
||||
|
||||
const std::string& ChannelId() const;
|
||||
|
||||
void SetRcv7bit(bool rcv7bit);
|
||||
bool Rcv7bit() 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();
|
||||
@@ -57,12 +67,25 @@ namespace Retro {
|
||||
|
||||
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 AttachSetup();
|
||||
|
||||
protected:
|
||||
bool fRcv7bit; //<! discard parity bit on input
|
||||
bool fTo7bit; //<! discard parity bit on output
|
||||
bool fToEnpc; //<! escape non-printabls 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11UnitTerm.ipp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11UnitTerm.ipp 508 2013-04-20 18:43:28Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -13,13 +13,14 @@
|
||||
//
|
||||
// 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 504 2013-04-13 15:37:24Z mueller $
|
||||
\version $Id: Rw11UnitTerm.ipp 508 2013-04-20 18:43:28Z mueller $
|
||||
\brief Implemenation (inline) of Rw11UnitTerm.
|
||||
*/
|
||||
|
||||
@@ -29,18 +30,60 @@ namespace Retro {
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void Rw11UnitTerm::SetRcv7bit(bool rcv7bit)
|
||||
inline void Rw11UnitTerm::SetTo7bit(bool to7bit)
|
||||
{
|
||||
fRcv7bit = rcv7bit;
|
||||
fTo7bit = to7bit;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool Rw11UnitTerm::Rcv7bit() const
|
||||
inline void Rw11UnitTerm::SetToEnpc(bool toenpc)
|
||||
{
|
||||
return fRcv7bit;
|
||||
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
|
||||
|
||||
99
tools/src/librw11/Rw11VirtDisk.cpp
Normal file
99
tools/src/librw11/Rw11VirtDisk.cpp
Normal file
@@ -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
|
||||
71
tools/src/librw11/Rw11VirtDisk.hpp
Normal file
71
tools/src/librw11/Rw11VirtDisk.hpp
Normal file
@@ -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
|
||||
55
tools/src/librw11/Rw11VirtDisk.ipp
Normal file
55
tools/src/librw11/Rw11VirtDisk.ipp
Normal file
@@ -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
|
||||
178
tools/src/librw11/Rw11VirtDiskFile.cpp
Normal file
178
tools/src/librw11/Rw11VirtDiskFile.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
// $Id: Rw11VirtDiskFile.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-04-14 506 1.0 Initial version
|
||||
// 2013-02-13 488 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11VirtDiskFile.cpp 509 2013-04-21 20:46:20Z 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() + string("' failed: "),
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat sbuf;
|
||||
if (::fstat(fd, &sbuf) < 0) {
|
||||
emsg.InitErrno("Rw11VirtDiskFile::Open()",
|
||||
string("stat() for '") + fUrl.Path() + string("' 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()", string("write() failed: "),
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (seekpos+nbyt > fSize) fSize = seekpos+nbyt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool Rw11VirtDiskFile::Seek(size_t seekpos, RerrMsg& emsg)
|
||||
{
|
||||
if (::lseek(fFd, seekpos, SEEK_SET) < 0) {
|
||||
emsg.InitErrno("Rw11VirtDiskFile::Seek()", string("seek() failed: "),
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
Rw11VirtDisk::Dump(os, ind, " ^");
|
||||
return;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
61
tools/src/librw11/Rw11VirtDiskFile.hpp
Normal file
61
tools/src/librw11/Rw11VirtDiskFile.hpp
Normal file
@@ -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
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11VirtTerm.cpp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11VirtTerm.cpp 508 2013-04-20 18:43:28Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11VirtTerm.cpp 504 2013-04-13 15:37:24Z mueller $
|
||||
\version $Id: Rw11VirtTerm.cpp 508 2013-04-20 18:43:28Z mueller $
|
||||
\brief Implemenation of Rw11VirtTerm.
|
||||
*/
|
||||
#include <memory>
|
||||
@@ -49,10 +49,10 @@ Rw11VirtTerm::Rw11VirtTerm(Rw11Unit* punit)
|
||||
fChannelId(),
|
||||
fRcvCb()
|
||||
{
|
||||
fStats.Define(kStatNVTRcvPoll, "NVTRcvPoll", "RcvPollHandler() calls");
|
||||
fStats.Define(kStatNVTSnd, "NVTSnd", "Snd() calls");
|
||||
fStats.Define(kStatNVTRcvByt, "NVTRcvByt", "bytes received");
|
||||
fStats.Define(kStatNVTSndByt, "NVTSndByt", "bytes send");
|
||||
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");
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11VirtTermTcp.cpp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11VirtTermTcp.cpp 508 2013-04-20 18:43:28Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -13,13 +13,14 @@
|
||||
//
|
||||
// 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.cpp 504 2013-04-13 15:37:24Z mueller $
|
||||
\version $Id: Rw11VirtTermTcp.cpp 508 2013-04-20 18:43:28Z mueller $
|
||||
\brief Implemenation of Rw11VirtTermTcp.
|
||||
*/
|
||||
|
||||
@@ -70,6 +71,8 @@ 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
|
||||
|
||||
@@ -78,13 +81,18 @@ Rw11VirtTermTcp::Rw11VirtTermTcp(Rw11Unit* punit)
|
||||
fFdListen(-1),
|
||||
fFd(-1),
|
||||
fState(ts_Closed),
|
||||
fTcpTrace(false)
|
||||
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" ,
|
||||
"ListenPollHandler() calls");
|
||||
fStats.Define(kStatNVTAccept, "NVTAccept", "socket accepts");
|
||||
fStats.Define(kStatNVTRcvRaw, "NVTRcvRaw", "raw bytes received");
|
||||
fStats.Define(kStatNVTSndRaw, "NVTSndRaw", "raw bytes send");
|
||||
"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");
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
@@ -96,7 +104,7 @@ Rw11VirtTermTcp::~Rw11VirtTermTcp()
|
||||
Server().RemovePollHandler(fFdListen);
|
||||
close(fFdListen);
|
||||
}
|
||||
if (fFd > 2) {
|
||||
if (Connected()) {
|
||||
Server().RemovePollHandler(fFd);
|
||||
close(fFd);
|
||||
}
|
||||
@@ -182,6 +190,17 @@ 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) {
|
||||
@@ -231,6 +250,7 @@ void Rw11VirtTermTcp::Dump(std::ostream& os, int ind, const char* text) const
|
||||
}
|
||||
os << bl << " fState: " << t_state << endl;
|
||||
os << bl << " fTcpTrace: " << fTcpTrace << endl;
|
||||
os << bl << " fSndPreConQue.size" << fSndPreConQue.size() << endl;
|
||||
Rw11VirtTerm::Dump(os, ind, " ^");
|
||||
return;
|
||||
}
|
||||
@@ -265,11 +285,14 @@ int Rw11VirtTermTcp::ListenPollHandler(const pollfd& pfd)
|
||||
|
||||
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
|
||||
@@ -278,6 +301,17 @@ int Rw11VirtTermTcp::ListenPollHandler(const pollfd& pfd)
|
||||
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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: Rw11VirtTermTcp.hpp 504 2013-04-13 15:37:24Z mueller $
|
||||
// $Id: Rw11VirtTermTcp.hpp 508 2013-04-20 18:43:28Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
@@ -13,6 +13,7 @@
|
||||
//
|
||||
// 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
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -20,13 +21,15 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rw11VirtTermTcp.hpp 504 2013-04-13 15:37:24Z mueller $
|
||||
\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 {
|
||||
@@ -45,7 +48,9 @@ namespace Retro {
|
||||
|
||||
// statistics counter indices
|
||||
enum stats {
|
||||
kStatNVTListenPoll = Rw11VirtTerm::kDimStat,
|
||||
kStatNVTPreConSave = Rw11VirtTerm::kDimStat,
|
||||
kStatNVTPreConDrop,
|
||||
kStatNVTListenPoll,
|
||||
kStatNVTAccept,
|
||||
kStatNVTRcvRaw,
|
||||
kStatNVTSndRaw,
|
||||
@@ -54,6 +59,7 @@ namespace Retro {
|
||||
|
||||
protected:
|
||||
|
||||
bool Connected() const;
|
||||
int ListenPollHandler(const pollfd& pfd);
|
||||
int RcvPollHandler(const pollfd& pfd);
|
||||
|
||||
@@ -79,6 +85,8 @@ namespace Retro {
|
||||
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,
|
||||
@@ -94,10 +102,11 @@ namespace Retro {
|
||||
int fFd;
|
||||
telnet_state fState;
|
||||
bool fTcpTrace;
|
||||
std::deque<uint8_t> fSndPreConQue;
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
//#include "Rw11VirtTermTcp.ipp"
|
||||
#include "Rw11VirtTermTcp.ipp"
|
||||
|
||||
#endif
|
||||
|
||||
43
tools/src/librw11/Rw11VirtTermTcp.ipp
Normal file
43
tools/src/librw11/Rw11VirtTermTcp.ipp
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user