w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
Rw11CntlTM11.cpp
Go to the documentation of this file.
1// $Id: Rw11CntlTM11.cpp 1183 2019-07-10 18:48:41Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2015-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4// Other credits:
5// the boot code is from the simh project and Copyright Robert M Supnik
6//
7// Revision History:
8// Date Rev Version Comment
9// 2019-07-10 1183 1.1 support odd record length
10// 2019-07-08 1182 1.0.11 BUGFIX: AddNormalExit(): get tmds logic right
11// 2019-04-19 1133 1.0.10 use ExecWibr()
12// 2019-04-14 1131 1.0.9 proper unit init, call UnitSetupAll() in Start()
13// 2019-02-23 1114 1.0.8 use std::bind instead of lambda
14// 2018-12-15 1082 1.0.7 use std::bind or lambda instead of boost::bind
15// 2018-12-09 1080 1.0.6 use HasVirt(); Virt() returns ref
16// 2018-10-28 1062 1.0.5 replace boost/foreach
17// 2017-04-02 865 1.0.4 Dump(): add detail arg
18// 2017-03-03 858 1.0.3 use cntl name as message prefix
19// 2017-02-26 857 1.0.2 use kCPAH_M_UBM22
20// 2015-06-06 690 1.0.1 BUGFIX: AddFastExit() check for Virt() defined
21// 2015-06-04 686 1.0 Initial version
22// 2015-05-17 683 0.1 First draft
23// ---------------------------------------------------------------------------
24
29#include <functional>
30
31#include "librtools/RosFill.hpp"
35#include "librtools/RlogMsg.hpp"
36
37#include "Rw11CntlTM11.hpp"
38
39using namespace std;
40using namespace std::placeholders;
41
47// all method definitions in namespace Retro
48namespace Retro {
49
50//------------------------------------------+-----------------------------------
51// constants definitions
52
53const uint16_t Rw11CntlTM11::kIbaddr;
54const int Rw11CntlTM11::kLam;
55
56const uint16_t Rw11CntlTM11::kTMSR;
57const uint16_t Rw11CntlTM11::kTMCR;
58const uint16_t Rw11CntlTM11::kTMBC;
59const uint16_t Rw11CntlTM11::kTMBA;
60const uint16_t Rw11CntlTM11::kTMDB;
61const uint16_t Rw11CntlTM11::kTMRL;
62
63const uint16_t Rw11CntlTM11::kProbeOff;
66
67const uint16_t Rw11CntlTM11::kTMSR_M_ICMD;
68const uint16_t Rw11CntlTM11::kTMSR_M_EOF;
69const uint16_t Rw11CntlTM11::kTMSR_M_PAE;
70const uint16_t Rw11CntlTM11::kTMSR_M_EOT;
71const uint16_t Rw11CntlTM11::kTMSR_M_RLE;
72const uint16_t Rw11CntlTM11::kTMSR_M_BTE;
73const uint16_t Rw11CntlTM11::kTMSR_M_NXM;
74const uint16_t Rw11CntlTM11::kTMSR_M_ONL;
75const uint16_t Rw11CntlTM11::kTMSR_M_BOT;
76const uint16_t Rw11CntlTM11::kTMSR_M_WRL;
77const uint16_t Rw11CntlTM11::kTMSR_M_REW;
78const uint16_t Rw11CntlTM11::kTMSR_M_TUR;
79
80const uint16_t Rw11CntlTM11::kTMCR_V_ERR;
81const uint16_t Rw11CntlTM11::kTMCR_V_DEN;
82const uint16_t Rw11CntlTM11::kTMCR_B_DEN;
83const uint16_t Rw11CntlTM11::kTMCR_V_UNIT;
84const uint16_t Rw11CntlTM11::kTMCR_B_UNIT;
85const uint16_t Rw11CntlTM11::kTMCR_M_RDY;
86const uint16_t Rw11CntlTM11::kTMCR_V_EA;
87const uint16_t Rw11CntlTM11::kTMCR_B_EA;
88const uint16_t Rw11CntlTM11::kTMCR_V_FUNC;
89const uint16_t Rw11CntlTM11::kTMCR_B_FUNC;
90const uint16_t Rw11CntlTM11::kTMCR_M_GO;
91
92const uint16_t Rw11CntlTM11::kFUNC_UNLOAD;
93const uint16_t Rw11CntlTM11::kFUNC_READ;
94const uint16_t Rw11CntlTM11::kFUNC_WRITE ;
95const uint16_t Rw11CntlTM11::kFUNC_WEOF;
96const uint16_t Rw11CntlTM11::kFUNC_SFORW;
97const uint16_t Rw11CntlTM11::kFUNC_SBACK;
98const uint16_t Rw11CntlTM11::kFUNC_WEIRG;
99const uint16_t Rw11CntlTM11::kFUNC_REWIND;
100
101const uint16_t Rw11CntlTM11::kRFUNC_WUNIT;
102const uint16_t Rw11CntlTM11::kRFUNC_DONE;
103
104const uint16_t Rw11CntlTM11::kTMCR_M_RICMD;
105const uint16_t Rw11CntlTM11::kTMCR_M_RPAE;
106const uint16_t Rw11CntlTM11::kTMCR_M_RRLE;
107const uint16_t Rw11CntlTM11::kTMCR_M_RBTE;
108const uint16_t Rw11CntlTM11::kTMCR_M_RNXM;
109const uint16_t Rw11CntlTM11::kTMCR_M_REAENA;
110const uint16_t Rw11CntlTM11::kTMCR_V_REA;
111const uint16_t Rw11CntlTM11::kTMCR_B_REA;
112
113const uint16_t Rw11CntlTM11::kTMRL_M_EOF;
114const uint16_t Rw11CntlTM11::kTMRL_M_EOT;
115const uint16_t Rw11CntlTM11::kTMRL_M_ONL;
116const uint16_t Rw11CntlTM11::kTMRL_M_BOT;
117const uint16_t Rw11CntlTM11::kTMRL_M_WRL;
118const uint16_t Rw11CntlTM11::kTMRL_M_REW;
119
120//------------------------------------------+-----------------------------------
122
124 : Rw11CntlBase<Rw11UnitTM11,4>("tm11"),
125 fPC_tmcr(0),
126 fPC_tmsr(0),
127 fPC_tmbc(0),
128 fPC_tmba(0),
129 fRd_tmcr(0),
130 fRd_tmsr(0),
131 fRd_tmbc(0),
132 fRd_tmba(0),
133 fRd_addr(0),
134 fRd_nwrd(0),
135 fRd_fu(0),
136 fRd_rddone(0),
137 fRd_opcode(0),
138 fBuf(),
139 fRdma(this,
140 std::bind(&Rw11CntlTM11::RdmaPreExecCB, this, _1, _2, _3, _4),
141 std::bind(&Rw11CntlTM11::RdmaPostExecCB, this, _1, _2, _3, _4))
142{
143 // must be here because Units have a back-ptr (not available at Rw11CntlBase)
144 for (size_t i=0; i<NUnit(); i++) {
145 fspUnit[i].reset(new Rw11UnitTM11(this, i));
146 }
147
148 fStats.Define(kStatNFuncUnload , "NFuncUnload" , "func UNLOAD");
149 fStats.Define(kStatNFuncRead , "NFuncRead" , "func READ");
150 fStats.Define(kStatNFuncWrite , "NFuncWrite" , "func WRITE");
151 fStats.Define(kStatNFuncWeof , "NFuncWeof" , "func WEOF");
152 fStats.Define(kStatNFuncSforw , "NFuncSforw" , "func SFORW");
153 fStats.Define(kStatNFuncSback , "NFuncSback" , "func SBACK");
154 fStats.Define(kStatNFuncWrteg , "NFuncWrteg" , "func WRTEG");
155 fStats.Define(kStatNFuncRewind , "NFuncRewind" , "func REWIND");
156}
157
158//------------------------------------------+-----------------------------------
160
162{}
163
164//------------------------------------------+-----------------------------------
166
167void Rw11CntlTM11::Config(const std::string& name, uint16_t base, int lam)
168{
169 ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
170 return;
171}
172
173//------------------------------------------+-----------------------------------
175
177{
178 if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
179 throw Rexception("Rw11CntlTM11::Start",
180 "Bad state: started, no lam, not enable, not found");
181
182 // add device register address ibus and rbus mappings
183 // done here because now Cntl bound to Cpu and Cntl probed
184 Cpu().AllIAddrMapInsert(Name()+".sr", Base() + kTMSR);
185 Cpu().AllIAddrMapInsert(Name()+".cr", Base() + kTMCR);
186 Cpu().AllIAddrMapInsert(Name()+".bc", Base() + kTMBC);
187 Cpu().AllIAddrMapInsert(Name()+".ba", Base() + kTMBA);
188 Cpu().AllIAddrMapInsert(Name()+".db", Base() + kTMDB);
189 Cpu().AllIAddrMapInsert(Name()+".rl", Base() + kTMRL);
190
191 // ensure unit status is initialized
192 UnitSetupAll();
193
194 // setup primary info clist
201
202 // add attn handler
204 uint16_t(1)<<fLam, this);
205
206 fStarted = true;
207 return;
208}
209
210//------------------------------------------+-----------------------------------
212
214{
215 Rw11UnitTM11& unit = *fspUnit[ind];
216
217 uint16_t tmds = 0;
218 if (unit.HasVirt()) { // file attached
219 tmds |= kTMRL_M_ONL;
220 if (unit.Virt().WProt()) tmds |= kTMRL_M_WRL;
221 if (unit.Virt().Bot()) tmds |= kTMRL_M_BOT;
222 }
223 unit.SetTmds(tmds);
224 Cpu().ExecWibr(fBase+kTMCR, (uint16_t(ind)<<kTMCR_V_RUNIT)|
226 fBase+kTMRL, tmds);
227
228 return;
229}
230
231//------------------------------------------+-----------------------------------
233
234bool Rw11CntlTM11::BootCode(size_t unit, std::vector<uint16_t>& code,
235 uint16_t& aload, uint16_t& astart)
236{
237 uint16_t kBOOT_START = 02000;
238 uint16_t bootcode[] = { // tm11 boot loader - from simh pdp11_tm.c (v3.9)
239 0046524, // boot_start: "TM"
240 0012706, kBOOT_START, // mov #boot_start, sp
241 0012700, uint16_t(unit), // mov #unit_num, r0
242 0012701, 0172526, // mov #172526, r1 ; #tmba
243 0005011, // clr (r1) ; tmba = 0
244 0012741, 0177777, // mov #-1, -(r1) ; tmbc = -1
245 0010002, // mov r0,r2
246 0000302, // swab r2
247 0062702, 0060011, // add #60011, r2
248 0010241, // mov r2, -(r1) ; tmcr = space + go
249 0105711, // tstb (r1) ; test tmcr.rdy
250 0100376, // bpl .-2
251 0010002, // mov r0,r2 ; note: tmbc=0 now
252 0000302, // swab r2
253 0062702, 0060003, // add #60003, r2 ; note: tmbc still = 0!
254 0010211, // mov r2, (r1) ; tmcr = read + go
255 0105711, // tstb (r1) ; test tmcr.rdy
256 0100376, // bpl .-2
257 0005002, // clr r2
258 0005003, // clr r3
259 0012704, uint16_t(kBOOT_START+020), // mov #boot_start+20, r4
260 0005005, // clr r5
261 0005007 // clr r7
262 };
263
264 code.clear();
265 code.insert(code.end(), std::begin(bootcode), std::end(bootcode));
266 aload = kBOOT_START;
267 astart = kBOOT_START+2;
268 return true;
269}
270
271//------------------------------------------+-----------------------------------
273
274void Rw11CntlTM11::Dump(std::ostream& os, int ind, const char* text,
275 int detail) const
276{
277 RosFill bl(ind);
278 os << bl << (text?text:"--") << "Rw11CntlTM11 @ " << this << endl;
279 os << bl << " fPC_tmcr: " << RosPrintf(fPC_tmcr,"d",6) << endl;
280 os << bl << " fPC_tmsr: " << RosPrintf(fPC_tmsr,"d",6) << endl;
281 os << bl << " fPC_tmbc: " << RosPrintf(fPC_tmbc,"d",6) << endl;
282 os << bl << " fPC_tmba: " << RosPrintf(fPC_tmba,"d",6) << endl;
283 os << bl << " fRd_tmcr: " << RosPrintBvi(fRd_tmcr,8) << endl;
284 os << bl << " fRd_tmsr: " << RosPrintBvi(fRd_tmsr,8) << endl;
285 os << bl << " fRd_tmbc: " << RosPrintBvi(fRd_tmbc,8) << endl;
286 os << bl << " fRd_tmba: " << RosPrintBvi(fRd_tmba,8) << endl;
287 os << bl << " fRd_addr: " << RosPrintBvi(fRd_addr,8,18) << endl;
288 os << bl << " fRd_nwrd: " << RosPrintf(fRd_nwrd,"d",6) << endl;
289 os << bl << " fRd_fu: " << fRd_fu << endl;
290 os << bl << " fRd_rddone: " << RosPrintf(fRd_rddone,"d",6) << endl;
291 os << bl << " fRd_opcode: " << fRd_opcode << endl;
292 os << bl << " fBuf.size: " << RosPrintf(fBuf.size(),"d",6) << endl;
293 fRdma.Dump(os, ind+2, "fRdma: ", detail);
294 Rw11CntlBase<Rw11UnitTM11,4>::Dump(os, ind, " ^", detail);
295 return;
296}
297
298//------------------------------------------+-----------------------------------
300
302{
305
306 uint16_t tmcr = fPrimClist[fPC_tmcr].Data();
307 uint16_t tmsr = fPrimClist[fPC_tmsr].Data();
308 uint16_t tmbc = fPrimClist[fPC_tmbc].Data();
309 uint16_t tmba = fPrimClist[fPC_tmba].Data();
310
311 uint16_t unum = (tmcr>>kTMCR_V_UNIT) & kTMCR_B_UNIT;
312 uint16_t ea = (tmcr>>kTMCR_V_EA) & kTMCR_B_EA;
313 uint16_t fu = (tmcr>>kTMCR_V_FUNC) & kTMCR_B_FUNC;
314
315 uint32_t addr = uint32_t(ea)<<16 | uint32_t(tmba);
316
317 // Note: a zero tmbc translates into nbyt=64k !
318 // correct behaviour, the boot loaded actually issues a read
319 // with tmbc=0 to read the boot block into memory !!
320 uint32_t nbyt = (~uint32_t(tmbc)&0xffff) + 1; // transfer size in bytes
321
322 //Rw11Cpu& cpu = Cpu();
323 RlinkCommandList clist;
324
325 if (fTraceLevel>0) {
326 RlogMsg lmsg(LogFile());
327 static const char* fumnemo[8] =
328 {"un ","rd ","wr ","we ","sf ","sb ","wi ","re "};
329 lmsg << "-I " << Name() << ":"
330 << " fu=" << fumnemo[fu&07]
331 << " un=" << unum
332 << " cr=" << RosPrintBvi(tmcr,8)
333 << " ad=" << RosPrintBvi(addr,8,18)
334 << " bc=" << RosPrintBvi(tmbc,8)
335 << " nb=";
336 if (nbyt==65536) lmsg << " (0)"; else lmsg << RosPrintf(nbyt,"d",5);
337 }
338
339 // check for spurious interrupts (either RDY=1 or RDY=0 and rdma busy)
340 if ((tmcr & kTMCR_M_RDY) || fRdma.IsActive()) {
341 RlogMsg lmsg(LogFile());
342 lmsg << "-E " << Name() << ": err"
343 << " cr=" << RosPrintBvi(tmcr,8)
344 << " spurious lam: "
345 << (fRdma.IsActive() ? "RDY=0 and Rdma busy" : "RDY=1");
346 return 0;
347 }
348
349 // check for general abort conditions: invalid unit number
350 if (unum >= NUnit()) {
352 Server().Exec(clist);
353 return 0;
354 }
355
356 Rw11UnitTM11& unit = *fspUnit[unum];
357
358 // check for general abort conditions:
359 // - unit not attached
360 // - write to a write locked unit
361 bool wcmd = fu == kFUNC_WRITE ||
362 fu == kFUNC_WEIRG ||
363 fu == kFUNC_WEOF;
364
365 if ((!unit.HasVirt()) || (wcmd && unit.Virt().WProt()) ) {
367 Server().Exec(clist);
368 return 0;
369 }
370
371 // remember request parameters for call back and error exit handling
372 fRd_tmcr = tmcr;
373 fRd_tmsr = tmsr;
374 fRd_tmbc = tmbc;
375 fRd_tmba = tmba;
376 fRd_addr = addr;
377 fRd_fu = fu;
378
379 // now handle the functions
380 int opcode = Rw11VirtTape::kOpCodeOK;
381 RerrMsg emsg;
382
383 if (fu == kFUNC_UNLOAD) { // Unload ------------------------
385 unit.Detach();
386 AddFastExit(clist, opcode, 0);
387 RlogMsg lmsg(LogFile());
388 lmsg << "-I " << Name() << ":"
389 << " unit " << unum << "unload";
390
391 } else if (fu == kFUNC_READ) { // Read --------------------------
393 size_t nwalloc = (nbyt+1)/2;
394 if (fBuf.size() < nwalloc) fBuf.resize(nwalloc);
395 bool rc = unit.VirtReadRecord(nbyt, reinterpret_cast<uint8_t*>(fBuf.data()),
396 fRd_rddone, fRd_opcode, emsg);
397 if (!rc) WriteLog("read", emsg);
398 if ((!rc) || fRd_rddone == 0) {
399 AddFastExit(clist, fRd_opcode, 0);
400 } else {
401 size_t nwdma = fRd_rddone/2;
402 fRdma.QueueWMem(addr, fBuf.data(), nwdma, Rw11Cpu::kCPAH_M_UBM22);
403 }
404
405 } else if (fu == kFUNC_WRITE || // Write -------------------------
406 fu == kFUNC_WEIRG) {
408 size_t nwdma = (nbyt+1)/2;
409 if (fBuf.size() < nwdma) fBuf.resize(nwdma);
410 fRdma.QueueRMem(addr, fBuf.data(), nwdma, Rw11Cpu::kCPAH_M_UBM22);
411
412 } else if (fu == kFUNC_WEOF) { // Write Eof ---------------------
414 if (!unit.VirtWriteEof(emsg)) WriteLog("weof", emsg);
415 AddFastExit(clist, opcode, 0);
416
417 } else if (fu == kFUNC_SFORW) { // Space forward -----------------
419 size_t ndone;
420 if (!unit.VirtSpaceForw(nbyt, ndone, opcode, emsg)) WriteLog("sback", emsg);
421 AddFastExit(clist, opcode, ndone);
422
423 } else if (fu == kFUNC_SBACK) { // Space Backward ----------------
425 size_t ndone;
426 if (!unit.VirtSpaceBack(nbyt, ndone, opcode, emsg)) WriteLog("sback", emsg);
427 AddFastExit(clist, opcode, ndone);
428
429 } else if (fu == kFUNC_REWIND) { // Rewind ------------------------
431 if (!unit.VirtRewind(opcode, emsg)) WriteLog("rewind", emsg);
432 AddFastExit(clist, opcode, 0);
433 }
434
435 if (clist.Size()) { // if handled directly
436 Server().Exec(clist); // doit
437 }
438
439 return 0;
440}
441
442//------------------------------------------+-----------------------------------
444
445void Rw11CntlTM11::RdmaPreExecCB(int /*stat*/, size_t /*nwdone*/,
446 size_t /*nwnext*/, RlinkCommandList& /*clist*/)
447{
448 // noop for TM11
449 return;
450}
451
452//------------------------------------------+-----------------------------------
454
455void Rw11CntlTM11::RdmaPostExecCB(int stat, size_t ndone,
456 RlinkCommandList& /*clist*/, size_t /*ncmd*/)
457{
458 if (stat == Rw11Rdma::kStatusBusy) return;
459
460 uint16_t tmcr = 0;
461 // handle Rdma aborts
462 if (stat == Rw11Rdma::kStatusFailRdma) tmcr |= kTMCR_M_RNXM;
463
464 // finally to TM11 register update
465 RlinkCommandList clist1;
466 AddNormalExit(clist1, ndone, tmcr);
467 Server().Exec(clist1);
468 return;
469}
470
471//------------------------------------------+-----------------------------------
473
475{
476 Rw11Cpu& cpu = Cpu();
477
478 tmcr |= (kRFUNC_DONE<<kTMCR_V_FUNC);
479 cpu.AddWibr(clist, fBase+kTMCR, tmcr);
480 if (fTraceLevel>1) {
481 RlogMsg lmsg(LogFile());
482 lmsg << "-I " << Name() << ": err "
483 << " cr=" << RosPrintBvi(tmcr,8);
484 }
485
486 return;
487}
488
489//------------------------------------------+-----------------------------------
491
492void Rw11CntlTM11::AddFastExit(RlinkCommandList& clist, int opcode, size_t ndone)
493{
494 uint16_t unum = (fRd_tmcr>>kTMCR_V_UNIT) & kTMCR_B_UNIT;
495 Rw11UnitTM11& unit = *fspUnit[unum];
496 Rw11Cpu& cpu = Cpu();
497
498 uint16_t tmcr = 0;
499 uint16_t tmds = 0;
500
501 // AddFastExit() is also called after UNLOAD, which calls unit.Detach()
502 // So unlike in all other cases, HasVirt() may be false, so check on this
503 if (unit.HasVirt()) {
504 tmds |= kTMRL_M_ONL;
505 if (unit.Virt().WProt()) tmds |= kTMRL_M_WRL;
506 if (unit.Virt().Bot()) tmds |= kTMRL_M_BOT;
507 if (unit.Virt().Eot()) tmds |= kTMRL_M_EOT;
508 }
509
510 switch (opcode) {
511
514 break;
515
517 tmds |= kTMRL_M_EOF;
518 break;
519
520 default:
521 tmcr |= kTMCR_M_RBTE;
522 break;
523 }
524
525 uint16_t tmbc = fRd_tmbc + uint16_t(ndone);
526
527 unit.SetTmds(tmds);
528 cpu.AddWibr(clist, fBase+kTMCR, (uint16_t(unum)<<kTMCR_V_RUNIT)|
530 cpu.AddWibr(clist, fBase+kTMRL, tmds);
531 if (ndone) cpu.AddWibr(clist, fBase+kTMBC, tmbc);
532 tmcr |= (kRFUNC_DONE<<kTMCR_V_FUNC);
533 cpu.AddWibr(clist, fBase+kTMCR, tmcr);
534
535 if (fTraceLevel>1) WriteExitLog(tmcr, fRd_addr, tmbc, tmds);
536
537 return;
538}
539
540//------------------------------------------+-----------------------------------
542
544 uint16_t tmcr)
545{
546 uint16_t unum = (fRd_tmcr>>kTMCR_V_UNIT) & kTMCR_B_UNIT;
547 Rw11UnitTM11& unit = *fspUnit[unum];
548 Rw11Cpu& cpu = Cpu();
549
550 uint32_t addr = fRd_addr + 2*ndone;
551 uint16_t tmbc = fRd_tmbc + 2*uint16_t(ndone);
552 size_t nbyt = 2*ndone;
553
554 if (fRd_fu == kFUNC_READ) { // handle READ
555 if (fRd_rddone & 0x1) { // odd rlen corrections
556 addr += 1;
557 tmbc += 1;
558 }
559
560 switch (fRd_opcode) {
561
563 if (fRd_rddone & 0x1) { // write trailing byte
564 nbyt += 1;
565 Cpu().AddLalh(clist, fRd_addr + 2*ndone, Rw11Cpu::kCPAH_M_UBM22);
567 clist.AddWreg(Rw11Cpu::kCPMEM, fBuf[ndone]);
568 }
569 break;
570
572 tmcr |= kTMCR_M_RRLE;
573 break;
574
576 tmcr |= kTMCR_M_RPAE;
577 break;
578
579 default:
580 tmcr |= kTMCR_M_RBTE;
581 break;
582 }
583
584 } else { // handle WRITE or WEIRG
585 int opcode;
586 RerrMsg emsg;
587 if (fRd_tmbc & 0x1) { // odd rlen corrections
588 nbyt -= 1;
589 addr -= 1;
590 tmbc -= 1;
591 }
592
593 if (!unit.VirtWriteRecord(nbyt, reinterpret_cast<uint8_t*>(fBuf.data()),
594 opcode, emsg))
595 WriteLog("write", emsg);
596 }
597
598 // now Virt status up-to-date, even for writes
599 uint16_t tmds = kTMRL_M_ONL;
600 if (unit.Virt().WProt()) tmds |= kTMRL_M_WRL;
601 if (unit.Virt().Bot()) tmds |= kTMRL_M_BOT;
602 if (unit.Virt().Eot()) tmds |= kTMRL_M_EOT;
603
604 uint16_t tmba = uint16_t(addr & 0xfffe);
605 uint16_t ea = uint16_t((addr>>16)&0x0003);
606 tmcr |= kTMCR_M_REAENA | (ea<<kTMCR_V_REA);
607
608 unit.SetTmds(tmds);
609 cpu.AddWibr(clist, fBase+kTMCR, (uint16_t(unum)<<kTMCR_V_RUNIT)|
611 cpu.AddWibr(clist, fBase+kTMRL, tmds);
612 cpu.AddWibr(clist, fBase+kTMBC, tmbc);
613 cpu.AddWibr(clist, fBase+kTMBA, tmba);
614 tmcr |= (kRFUNC_DONE<<kTMCR_V_FUNC);
615 cpu.AddWibr(clist, fBase+kTMCR, tmcr);
616
617 if (fTraceLevel>1) WriteExitLog(tmcr, addr, tmbc, tmds);
618
619 return;
620}
621
622//------------------------------------------+-----------------------------------
624
625void Rw11CntlTM11::WriteLog(const char* func, RerrMsg& emsg)
626{
627 RlogMsg lmsg(LogFile());
628 lmsg << "-E " << Name() << ":"
629 << " error for func=" << func
630 << ":" << emsg;
631
632 return;
633}
634
635//------------------------------------------+-----------------------------------
637
638void Rw11CntlTM11::WriteExitLog(uint16_t tmcr, uint32_t addr,
639 uint16_t tmbc, uint16_t tmds)
640{
641 uint16_t unum = (fRd_tmcr>>kTMCR_V_UNIT) & kTMCR_B_UNIT;
642 RlogMsg lmsg(LogFile());
643
645 uint16_t nbyt = tmbc - fRd_tmbc;
646 lmsg << "-I " << Name() << (err ? ": err " : ": ok ")
647 << " un=" << unum
648 << " cr=" << RosPrintBvi(tmcr,8)
649 << " ad=" << RosPrintBvi(addr,8,18)
650 << " bc=" << RosPrintBvi(tmbc,8)
651 << " nb=" << RosPrintf(nbyt,"d",5)
652 << " ds=" << RosPrintBvi(tmds,8);
653 if (tmds & kTMRL_M_EOF) lmsg << " EOF";
654 if (tmds & kTMRL_M_EOT) lmsg << " EOT";
655 if (tmds & kTMRL_M_BOT) lmsg << " BOT";
656 return;
657}
658
659} // end namespace Retro
FIXME_docs.
Definition: RerrMsg.hpp:25
FIXME_docs.
Definition: Rexception.hpp:29
size_t AddWreg(uint16_t addr, uint16_t data)
FIXME_docs.
size_t AddAttn()
FIXME_docs.
size_t Size() const
FIXME_docs.
void AddAttnHandler(attnhdl_t &&attnhdl, uint16_t mask, void *cdata=nullptr)
FIXME_docs.
void GetAttnInfo(AttnArgs &args, RlinkCommandList &clist)
FIXME_docs.
bool Exec(RlinkCommandList &clist, RerrMsg &emsg)
FIXME_docs.
Definition: RlinkServer.ipp:60
FIXME_docs.
Definition: RlogMsg.hpp:24
I/O appicator to generate fill characters.
Definition: RosFill.hpp:24
void Inc(size_t ind, double val=1.)
FIXME_docs.
Definition: Rstats.ipp:29
void Define(size_t ind, const std::string &name, const std::string &text)
FIXME_docs.
Definition: Rstats.cpp:72
Implemenation (inline) of Rw11CntlBase.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
virtual size_t NUnit() const
FIXME_docs.
std::shared_ptr< Rw11UnitTM11 > fspUnit[NU]
static const uint16_t kTMDB
TMDB reg offset.
static const uint16_t kTMRL_M_WRL
WRL: write locked.
void WriteExitLog(uint16_t tmcr, uint32_t addr, uint16_t tmbc, uint16_t tmds)
FIXME_docs.
uint32_t fRd_addr
Rdma: current addr.
static const uint16_t kTMSR_M_WRL
WRL: write locked.
static const uint16_t kTMCR_M_GO
static const uint16_t kTMSR_M_NXM
NXM: non-existent mem.
static const int kLam
TM11 default lam.
static const uint16_t kTMRL_M_ONL
ONL: online.
void RdmaPostExecCB(int stat, size_t ndone, RlinkCommandList &clist, size_t ncmd)
FIXME_docs.
static const uint16_t kTMSR_M_EOT
EOT: end-of-tape seen.
static const uint16_t kTMCR_M_RICMD
static const uint16_t kTMCR_B_REA
size_t fPC_tmsr
PrimClist: tmsr index.
static const uint16_t kFUNC_UNLOAD
static const uint16_t kTMRL_M_REW
REW: tape rewinding.
int fRd_opcode
Rdma: read opcode.
static const uint16_t kTMSR_M_BTE
BTE: bad tape error.
static const uint16_t kFUNC_SBACK
virtual bool BootCode(size_t unit, std::vector< uint16_t > &code, uint16_t &aload, uint16_t &astart)
FIXME_docs.
uint16_t fRd_fu
Rdma: request fu code.
static const bool kProbeRem
probr rem active
uint16_t fRd_tmbc
Rdma: request tmbc.
void Config(const std::string &name, uint16_t base, int lam)
FIXME_docs.
static const uint16_t kTMCR_M_RPAE
static const uint16_t kTMCR_B_FUNC
virtual void UnitSetup(size_t ind)
FIXME_docs.
static const uint16_t kTMSR_M_TUR
TUR: unit ready.
static const uint16_t kTMCR_V_EA
static const uint16_t kTMSR
TMSR reg offset.
static const uint16_t kTMSR_M_ONL
ONL: online.
size_t fRd_rddone
Rdma: bytes read.
static const uint16_t kTMCR
TMCR reg offset.
static const uint16_t kTMSR_M_REW
REW: tape rewound.
static const uint16_t kFUNC_REWIND
size_t fPC_tmba
PrimClist: tmba index.
static const uint16_t kTMCR_M_RRLE
void AddFastExit(RlinkCommandList &clist, int opcode, size_t ndone)
FIXME_docs.
static const uint16_t kRFUNC_WUNIT
Rw11Rdma fRdma
Rdma controller.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
static const uint16_t kTMBA
TMBA reg offset.
size_t fPC_tmbc
PrimClist: tmbc index.
static const uint16_t kTMCR_V_REA
static const uint16_t kIbaddr
TM11 default address.
virtual void Start()
FIXME_docs.
uint16_t fRd_tmcr
Rdma: request tmcr.
std::vector< uint16_t > fBuf
data buffer
void WriteLog(const char *func, RerrMsg &emsg)
FIXME_docs.
static const uint16_t kTMSR_M_EOF
EOF: end-of-file seen.
static const uint16_t kTMRL
TMRL reg offset.
static const uint16_t kTMCR_M_REAENA
~Rw11CntlTM11()
Destructor.
static const uint16_t kTMCR_M_RDY
uint16_t fRd_tmba
Rdma: request tmba.
static const uint16_t kRFUNC_DONE
static const uint16_t kTMSR_M_BOT
BOT: at begin-of-tape.
static const uint16_t kTMCR_B_EA
static const uint16_t kTMCR_V_DEN
static const uint16_t kFUNC_SFORW
int AttnHandler(RlinkServer::AttnArgs &args)
FIXME_docs.
@ kStatNFuncSback
func SBACK
@ kStatNFuncRead
func READ
@ kStatNFuncRewind
func REWIND
@ kStatNFuncWrite
func WRITE
@ kStatNFuncSforw
func SFORW
@ kStatNFuncUnload
func UNLOAD
@ kStatNFuncWeof
func WEOF
@ kStatNFuncWrteg
func WRTEG
static const uint16_t kTMSR_M_ICMD
ICMD: invalid cmd.
static const uint16_t kTMSR_M_PAE
PAE: parity error.
static const uint16_t kFUNC_READ
static const uint16_t kTMCR_B_UNIT
void RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext, RlinkCommandList &clist)
FIXME_docs.
Rw11CntlTM11()
Default constructor.
static const uint16_t kTMCR_M_RBTE
static const uint16_t kTMCR_M_RNXM
void AddNormalExit(RlinkCommandList &clist, size_t ndone, uint16_t tmcr=0)
FIXME_docs.
uint32_t fRd_nwrd
Rdma: current nwrd.
static const uint16_t kTMCR_V_FUNC
static const uint16_t kTMCR_B_DEN
static const uint16_t kTMRL_M_EOT
EOT: end-of-tape seen.
static const uint16_t kTMSR_M_RLE
RLE: record lgth error.
static const bool kProbeInt
probe int active
static const uint16_t kTMCR_V_UNIT
static const uint16_t kTMRL_M_EOF
EOF: end-of-file seen.
static const uint16_t kFUNC_WEIRG
static const uint16_t kProbeOff
probe address offset (tmcr)
static const uint16_t kTMRL_M_BOT
BOT: at begin-of-tape.
static const uint16_t kFUNC_WRITE
size_t fPC_tmcr
PrimClist: tmcr index.
static const uint16_t kTMBC
TMBC reg offset.
static const uint16_t kTMCR_V_RUNIT
void AddErrorExit(RlinkCommandList &clist, uint16_t tmcr)
FIXME_docs.
static const uint16_t kFUNC_WEOF
static const uint16_t kTMCR_V_ERR
uint16_t fRd_tmsr
Rdma: request tmsr.
int fLam
attn bit number (-1 of none)
Definition: Rw11Cntl.hpp:110
uint32_t fTraceLevel
trace level; 0=off;1=cntl
Definition: Rw11Cntl.hpp:114
RlinkCommandList fPrimClist
clist for attn primary info
Definition: Rw11Cntl.hpp:115
uint16_t Base() const
FIXME_docs.
Definition: Rw11Cntl.ipp:88
Rstats fStats
statistics
Definition: Rw11Cntl.hpp:116
Rw11Probe fProbe
controller probe context
Definition: Rw11Cntl.hpp:113
Rw11Cpu & Cpu() const
FIXME_docs.
Definition: Rw11Cntl.ipp:32
void ConfigCntl(const std::string &name, uint16_t base, int lam, uint16_t probeoff, bool probeint, bool proberem)
FIXME_docs.
Definition: Rw11Cntl.cpp:156
bool fStarted
true if Start() called
Definition: Rw11Cntl.hpp:112
bool fEnable
enable flag
Definition: Rw11Cntl.hpp:111
RlinkServer & Server() const
FIXME_docs.
Definition: Rw11Cntl.ipp:48
const std::string & Name() const
FIXME_docs.
Definition: Rw11Cntl.ipp:80
RlogFile & LogFile() const
FIXME_docs.
Definition: Rw11Cntl.ipp:64
virtual void UnitSetupAll()
FIXME_docs.
Definition: Rw11Cntl.cpp:113
uint16_t fBase
controller base address
Definition: Rw11Cntl.hpp:109
FIXME_docs.
Definition: Rw11Cpu.hpp:66
static const uint16_t kCPMEM
CPMEM reg offset.
Definition: Rw11Cpu.hpp:187
void AllIAddrMapInsert(const std::string &name, uint16_t ibaddr)
FIXME_docs.
Definition: Rw11Cpu.cpp:902
static const uint16_t kCPMEMBE_M_BE0
membe: be0 flag
Definition: Rw11Cpu.hpp:232
int AddLalh(RlinkCommandList &clist, uint32_t addr, uint16_t mode=kCPAH_M_22BIT)
FIXME_docs.
Definition: Rw11Cpu.cpp:408
void ExecWibr(uint16_t ibaddr0, uint16_t data0, uint16_t ibaddr1=0, uint16_t data1=0, uint16_t ibaddr2=0, uint16_t data2=0)
FIXME_docs.
Definition: Rw11Cpu.cpp:491
int AddMembe(RlinkCommandList &clist, uint16_t be, bool stick=false)
FIXME_docs.
Definition: Rw11Cpu.cpp:344
int AddWibr(RlinkCommandList &clist, uint16_t ibaddr, uint16_t data)
FIXME_docs.
Definition: Rw11Cpu.cpp:365
int AddRibr(RlinkCommandList &clist, uint16_t ibaddr)
FIXME_docs.
Definition: Rw11Cpu.cpp:354
static const uint16_t kCPAH_M_UBM22
ubmap+22bit
Definition: Rw11Cpu.hpp:228
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
Definition: Rw11Rdma.cpp:110
bool IsActive() const
FIXME_docs.
Definition: Rw11Rdma.ipp:77
@ kStatusFailRdma
last rdma transfer failed
Definition: Rw11Rdma.hpp:86
@ kStatusBusy
more chunks to come
Definition: Rw11Rdma.hpp:84
void QueueWMem(uint32_t addr, const uint16_t *block, size_t size, uint16_t mode)
FIXME_docs.
Definition: Rw11Rdma.cpp:98
void QueueRMem(uint32_t addr, uint16_t *block, size_t size, uint16_t mode)
FIXME_docs.
Definition: Rw11Rdma.cpp:86
void SetTmds(uint16_t tmds)
FIXME_docs.
bool VirtWriteRecord(size_t nbyte, const uint8_t *data, int &opcode, RerrMsg &emsg)
FIXME_docs.
bool VirtSpaceForw(size_t nrec, size_t &ndone, int &opcode, RerrMsg &emsg)
FIXME_docs.
bool VirtSpaceBack(size_t nrec, size_t &ndone, int &opcode, RerrMsg &emsg)
FIXME_docs.
bool VirtRewind(int &opcode, RerrMsg &emsg)
FIXME_docs.
bool VirtWriteEof(RerrMsg &emsg)
FIXME_docs.
bool VirtReadRecord(size_t nbyte, uint8_t *data, size_t &ndone, int &opcode, RerrMsg &emsg)
FIXME_docs.
TV & Virt()
FIXME_docs.
virtual void Detach()
FIXME_docs.
bool HasVirt() const
FIXME_docs.
@ kOpCodeRecLenErr
record length error
@ kOpCodeBot
ended at BOT
@ kOpCodeOK
operation OK
@ kOpCodeEof
ended at EOF
@ kOpCodeBadParity
record with parity error
bool Eot() const
FIXME_docs.
bool Bot() const
FIXME_docs.
virtual bool WProt() const
FIXME_docs.
Definition: Rw11Virt.cpp:52
RosPrintfS< bool > RosPrintf(bool value, const char *form=0, int width=0, int prec=0)
Creates a print object for the formatted output of a bool value.
Definition: RosPrintf.ipp:38
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47
bool Found() const
FIXME_docs.
Definition: Rw11Probe.cpp:52