mirror of
https://github.com/wfjm/w11.git
synced 2026-02-14 20:16:24 +00:00
- ibdr_dl11
- now xbuf.val in bit 15 and 8;
- use rbuf instead xbuf for rdry reporting
- remove maintenance mode
- use ib_rlim_slv; add RLIM_CEV, drop CE_USEC
- ibdr_pc11
- pbuf.pval in bit 15 and 8
- move rbusy reporting from pbuf to rbuf register
- ibdr_maxisys,ibdr_minisys: adapt to new ibdr_dl11 iface
- tb_rlink_tba_pdp11core_ibdr.dat: adapt to new ibdr_dl11 iface
- tcl/rw11/util.tcl: setup_tt: rename dlrlim to dlrrlim
- oskit/*/*_boot.tcl: use dlrrlim instead of dlrlim
- Rw11CntlDL11,Rw11CntlPC11: adapt to new dl11,pc11 iface
- tools/asm-11/lib/defs_{dl,pc}.mac: added definition file
- tools/oskit/hook/hook_ibmon_{pca,tta}.tcl: added imon hook file
296 lines
8.8 KiB
C++
296 lines
8.8 KiB
C++
// $Id: Rw11CntlDL11.cpp 1126 2019-04-06 17:37:40Z mueller $
|
|
//
|
|
// Copyright 2013-2019 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 3, 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
|
|
// 2019-04-06 1126 1.4 xbuf.val in msb; rrdy in rbuf (new iface)
|
|
// 2019-02-23 1114 1.3.2 use std::bind instead of lambda
|
|
// 2018-12-15 1082 1.3.1 use lambda instead of boost::bind
|
|
// 2017-05-14 897 1.3 add RcvChar(),TraceChar(); trace received chars
|
|
// 2017-04-02 865 1.2.3 Dump(): add detail arg
|
|
// 2017-03-03 858 1.2.2 use cntl name as message prefix
|
|
// 2017-02-25 855 1.2.1 shorten ctor code; RcvNext() --> RcvQueueNext()
|
|
// 2014-12-30 625 1.2 adopt to Rlink V4 attn logic
|
|
// 2014-12-25 621 1.1 adopt to 4k word ibus window and
|
|
// 2013-05-04 516 1.0.2 add RxRlim support (receive interrupt rate limit)
|
|
// 2013-04-20 508 1.0.1 add trace support
|
|
// 2013-03-06 495 1.0 Initial version
|
|
// 2013-02-05 483 0.1 First draft
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/*!
|
|
\brief Implemenation of Rw11CntlDL11.
|
|
*/
|
|
|
|
#include <functional>
|
|
|
|
#include "librtools/RosFill.hpp"
|
|
#include "librtools/RosPrintBvi.hpp"
|
|
#include "librtools/RosPrintf.hpp"
|
|
#include "librtools/Rexception.hpp"
|
|
#include "librtools/RlogMsg.hpp"
|
|
|
|
#include "Rw11CntlDL11.hpp"
|
|
|
|
using namespace std;
|
|
using namespace std::placeholders;
|
|
|
|
/*!
|
|
\class Retro::Rw11CntlDL11
|
|
\brief FIXME_docs
|
|
*/
|
|
|
|
// all method definitions in namespace Retro
|
|
namespace Retro {
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
// constants definitions
|
|
|
|
const uint16_t Rw11CntlDL11::kIbaddr;
|
|
const int Rw11CntlDL11::kLam;
|
|
|
|
const uint16_t Rw11CntlDL11::kRCSR;
|
|
const uint16_t Rw11CntlDL11::kRBUF;
|
|
const uint16_t Rw11CntlDL11::kXCSR;
|
|
const uint16_t Rw11CntlDL11::kXBUF;
|
|
|
|
const uint16_t Rw11CntlDL11::kProbeOff;
|
|
const bool Rw11CntlDL11::kProbeInt;
|
|
const bool Rw11CntlDL11::kProbeRem;
|
|
|
|
const uint16_t Rw11CntlDL11::kRCSR_M_RLIM;
|
|
const uint16_t Rw11CntlDL11::kRCSR_V_RLIM;
|
|
const uint16_t Rw11CntlDL11::kRCSR_B_RLIM;
|
|
const uint16_t Rw11CntlDL11::kRCSR_V_TYPE;
|
|
const uint16_t Rw11CntlDL11::kRCSR_B_TYPE;
|
|
const uint16_t Rw11CntlDL11::kRCSR_M_RDONE;
|
|
const uint16_t Rw11CntlDL11::kRCSR_M_FCLR;
|
|
const uint16_t Rw11CntlDL11::kRBUF_M_RRDY;
|
|
const uint16_t Rw11CntlDL11::kRBUF_V_SIZE;
|
|
const uint16_t Rw11CntlDL11::kRBUF_B_SIZE;
|
|
const uint16_t Rw11CntlDL11::kRBUF_M_BUF;
|
|
|
|
const uint16_t Rw11CntlDL11::kXCSR_V_RLIM;
|
|
const uint16_t Rw11CntlDL11::kXCSR_B_RLIM;
|
|
const uint16_t Rw11CntlDL11::kXCSR_M_XRDY;
|
|
const uint16_t Rw11CntlDL11::kXBUF_M_VAL;
|
|
const uint16_t Rw11CntlDL11::kXBUF_V_SIZE;
|
|
const uint16_t Rw11CntlDL11::kXBUF_B_SIZE;
|
|
const uint16_t Rw11CntlDL11::kXBUF_M_BUF;
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! Default constructor
|
|
|
|
Rw11CntlDL11::Rw11CntlDL11()
|
|
: Rw11CntlBase<Rw11UnitDL11,1>("dl11"),
|
|
fPC_xbuf(0),
|
|
fPC_rbuf(0),
|
|
fRxRlim(0)
|
|
{
|
|
// must be here because Units have a back-ptr (not available at Rw11CntlBase)
|
|
fspUnit[0].reset(new Rw11UnitDL11(this, 0)); // single unit controller
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! Destructor
|
|
|
|
Rw11CntlDL11::~Rw11CntlDL11()
|
|
{}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
|
|
void Rw11CntlDL11::Config(const std::string& name, uint16_t base, int lam)
|
|
{
|
|
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
|
|
return;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
|
|
void Rw11CntlDL11::Start()
|
|
{
|
|
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
|
|
throw Rexception("Rw11CntlDL11::Start",
|
|
"Bad state: started, no lam, not enable, not found");
|
|
|
|
// add device register address ibus and rbus mappings
|
|
// done here because now Cntl bound to Cpu and Cntl probed
|
|
Cpu().AllIAddrMapInsert(Name()+".rcsr", Base() + kRCSR);
|
|
Cpu().AllIAddrMapInsert(Name()+".rbuf", Base() + kRBUF);
|
|
Cpu().AllIAddrMapInsert(Name()+".xcsr", Base() + kXCSR);
|
|
Cpu().AllIAddrMapInsert(Name()+".xbuf", Base() + kXBUF);
|
|
|
|
// setup primary info clist
|
|
fPrimClist.Clear();
|
|
fPrimClist.AddAttn();
|
|
fPC_xbuf = Cpu().AddRibr(fPrimClist, fBase+kXBUF);
|
|
fPC_rbuf = Cpu().AddRibr(fPrimClist, fBase+kRBUF);
|
|
|
|
// add attn handler
|
|
Server().AddAttnHandler(bind(&Rw11CntlDL11::AttnHandler, this, _1),
|
|
uint16_t(1)<<fLam, this);
|
|
fStarted = true;
|
|
return;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
|
|
void Rw11CntlDL11::UnitSetup(size_t /*ind*/)
|
|
{
|
|
Rw11Cpu& cpu = Cpu();
|
|
uint16_t rcsr = (fRxRlim<<kRCSR_V_RLIM) & kRCSR_M_RLIM;
|
|
RlinkCommandList clist;
|
|
cpu.AddWibr(clist, fBase+kRCSR, rcsr);
|
|
Server().Exec(clist);
|
|
return;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
|
|
void Rw11CntlDL11::Wakeup()
|
|
{
|
|
if (!fspUnit[0]->RcvQueueEmpty()) {
|
|
RlinkCommandList clist;
|
|
size_t ircsr = Cpu().AddRibr(clist, fBase+kRCSR);
|
|
Server().Exec(clist);
|
|
uint16_t rcsr = clist[ircsr].Data();
|
|
if ((rcsr & kRCSR_M_RDONE) == 0) RcvChar(); // send if RBUF not full
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
|
|
void Rw11CntlDL11::SetRxRlim(uint16_t rlim)
|
|
{
|
|
if (rlim > kRCSR_B_RLIM)
|
|
throw Rexception("Rw11CntlDL11::SetRxRlim","Bad args: rlim too large");
|
|
|
|
fRxRlim = rlim;
|
|
UnitSetup(0);
|
|
return;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
|
|
uint16_t Rw11CntlDL11::RxRlim() const
|
|
{
|
|
return fRxRlim;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
|
|
void Rw11CntlDL11::Dump(std::ostream& os, int ind, const char* text,
|
|
int detail) const
|
|
{
|
|
RosFill bl(ind);
|
|
os << bl << (text?text:"--") << "Rw11CntlDL11 @ " << this << endl;
|
|
os << bl << " fPC_xbuf: " << fPC_xbuf << endl;
|
|
os << bl << " fPC_rbuf: " << fPC_rbuf << endl;
|
|
os << bl << " fRxRlim: " << fRxRlim << endl;
|
|
|
|
Rw11CntlBase<Rw11UnitDL11,1>::Dump(os, ind, " ^", detail);
|
|
return;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
|
|
int Rw11CntlDL11::AttnHandler(RlinkServer::AttnArgs& args)
|
|
{
|
|
fStats.Inc(kStatNAttnHdl);
|
|
Server().GetAttnInfo(args, fPrimClist);
|
|
|
|
uint16_t xbuf = fPrimClist[fPC_xbuf].Data();
|
|
uint16_t rbuf = fPrimClist[fPC_rbuf].Data();
|
|
|
|
uint8_t ochr = xbuf & kXBUF_M_BUF;
|
|
bool xval = xbuf & kXBUF_M_VAL;
|
|
bool rrdy = rbuf & kRBUF_M_RRDY;
|
|
|
|
if (fTraceLevel>0) TraceChar('t', xbuf, ochr);
|
|
if (xval) fspUnit[0]->Snd(&ochr, 1);
|
|
if (rrdy && !fspUnit[0]->RcvQueueEmpty()) RcvChar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
// RcvQueueEmpty() must be false !!
|
|
|
|
void Rw11CntlDL11::RcvChar()
|
|
{
|
|
uint8_t ichr = fspUnit[0]->RcvQueueNext();
|
|
if (fTraceLevel>0) TraceChar('r', 0, ichr);
|
|
RlinkCommandList clist;
|
|
Cpu().AddWibr(clist, fBase+kRBUF, ichr);
|
|
Server().Exec(clist);
|
|
return;
|
|
}
|
|
|
|
//------------------------------------------+-----------------------------------
|
|
//! FIXME_docs
|
|
void Rw11CntlDL11::TraceChar(char dir, uint16_t xbuf, uint8_t chr)
|
|
{
|
|
bool xval = xbuf & kXBUF_M_VAL;
|
|
RlogMsg lmsg(LogFile());
|
|
lmsg << "-I " << Name() << ":" << ' ' << dir << 'x';
|
|
if (dir == 't') {
|
|
lmsg << " xbuf=" << RosPrintBvi(xbuf,8)
|
|
<< " xval=" << xval;
|
|
} else {
|
|
lmsg << " ";
|
|
}
|
|
lmsg << " rcvq=" << RosPrintf(fspUnit[0]->RcvQueueSize(),"d",3);
|
|
if (xval || dir != 't') {
|
|
lmsg << " char=";
|
|
if (chr>=040 && chr<0177) {
|
|
lmsg << "'" << char(chr) << "'";
|
|
} else {
|
|
lmsg << RosPrintBvi(chr,8);
|
|
lmsg << " " << ((chr&0200) ? "|" : " ");
|
|
uint8_t chr7 = chr & 0177;
|
|
if (chr7 < 040) {
|
|
switch (chr7) {
|
|
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;
|
|
case 033: lmsg << "ESC"; break;
|
|
default: lmsg << "^" << char('@'+chr7);
|
|
}
|
|
} else {
|
|
if (chr7 < 0177) {
|
|
lmsg << "'" << char(chr7) << "'";
|
|
} else {
|
|
lmsg << "DEL";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
} // end namespace Retro
|