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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [tools/] [src/] [librw11/] [Rw11CntlRHRP.cpp] - Blame information for rev 30

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 wfjm
// $Id: Rw11CntlRHRP.cpp 680 2015-05-14 13:29:46Z mueller $
2
//
3
// Copyright 2015- 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
// This program is free software; you may redistribute and/or modify it under
8
// the terms of the GNU General Public License as published by the Free
9
// Software Foundation, either version 2, or at your option any later version.
10
//
11
// This program is distributed in the hope that it will be useful, but
12
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
13
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
// for complete details.
15
// 
16
// Revision History: 
17
// Date         Rev Version  Comment
18
// 2015-05-14   680   1.0    Initial version
19
// 2015-03-21   659   0.1    First draft
20
// ---------------------------------------------------------------------------
21
 
22
/*!
23
  \file
24
  \version $Id: Rw11CntlRHRP.cpp 680 2015-05-14 13:29:46Z mueller $
25
  \brief   Implemenation of Rw11CntlRHRP.
26
*/
27
 
28
#include "boost/bind.hpp"
29
#include "boost/foreach.hpp"
30
#define foreach_ BOOST_FOREACH
31
 
32
#include "librtools/RosFill.hpp"
33
#include "librtools/RosPrintBvi.hpp"
34
#include "librtools/RosPrintf.hpp"
35
#include "librtools/Rexception.hpp"
36
#include "librtools/RlogMsg.hpp"
37
 
38
#include "Rw11CntlRHRP.hpp"
39
 
40
using namespace std;
41
 
42
/*!
43
  \class Retro::Rw11CntlRHRP
44
  \brief FIXME_docs
45
*/
46
 
47
// all method definitions in namespace Retro
48
namespace Retro {
49
 
50
//------------------------------------------+-----------------------------------
51
// constants definitions
52
 
53
const uint16_t Rw11CntlRHRP::kIbaddr;
54
const int      Rw11CntlRHRP::kLam;
55
 
56
const uint16_t Rw11CntlRHRP::kRPCS1;
57
const uint16_t Rw11CntlRHRP::kRPWC;
58
const uint16_t Rw11CntlRHRP::kRPBA;
59
const uint16_t Rw11CntlRHRP::kRPDA;
60
const uint16_t Rw11CntlRHRP::kRPCS2;
61
const uint16_t Rw11CntlRHRP::kRPDS;
62
const uint16_t Rw11CntlRHRP::kRPER1;
63
const uint16_t Rw11CntlRHRP::kRPAS;
64
const uint16_t Rw11CntlRHRP::kRPLA;
65
const uint16_t Rw11CntlRHRP::kRPDB;
66
const uint16_t Rw11CntlRHRP::kRPMR1;
67
const uint16_t Rw11CntlRHRP::kRPDT;
68
const uint16_t Rw11CntlRHRP::kRPSN;
69
const uint16_t Rw11CntlRHRP::kRPOF;
70
const uint16_t Rw11CntlRHRP::kRPDC;
71
const uint16_t Rw11CntlRHRP::kRxM13;
72
const uint16_t Rw11CntlRHRP::kRxM14;
73
const uint16_t Rw11CntlRHRP::kRxM15;
74
const uint16_t Rw11CntlRHRP::kRPEC1;
75
const uint16_t Rw11CntlRHRP::kRPEC2;
76
const uint16_t Rw11CntlRHRP::kRPBAE;
77
const uint16_t Rw11CntlRHRP::kRPCS3;
78
 
79
const uint16_t Rw11CntlRHRP::kProbeOff;
80
const bool     Rw11CntlRHRP::kProbeInt;
81
const bool     Rw11CntlRHRP::kProbeRem;
82
 
83
const uint16_t Rw11CntlRHRP::kRPCS1_M_SC;
84
const uint16_t Rw11CntlRHRP::kRPCS1_M_TRE;
85
const uint16_t Rw11CntlRHRP::kRPCS1_M_DVA;
86
const uint16_t Rw11CntlRHRP::kRPCS1_M_BAE;
87
const uint16_t Rw11CntlRHRP::kRPCS1_V_BAE;
88
const uint16_t Rw11CntlRHRP::kRPCS1_B_BAE;
89
const uint16_t Rw11CntlRHRP::kRPCS1_M_RDY;
90
const uint16_t Rw11CntlRHRP::kRPCS1_M_IE;
91
const uint16_t Rw11CntlRHRP::kRPCS1_V_FUNC;
92
const uint16_t Rw11CntlRHRP::kRPCS1_B_FUNC;
93
const uint16_t Rw11CntlRHRP::kRPCS1_M_GO;
94
 
95
const uint16_t Rw11CntlRHRP::kFUNC_WCD;
96
const uint16_t Rw11CntlRHRP::kFUNC_WCHD;
97
const uint16_t Rw11CntlRHRP::kFUNC_WRITE;
98
const uint16_t Rw11CntlRHRP::kFUNC_WHD;
99
const uint16_t Rw11CntlRHRP::kFUNC_READ;
100
const uint16_t Rw11CntlRHRP::kFUNC_RHD;
101
 
102
const uint16_t Rw11CntlRHRP::kRFUNC_WUNIT;
103
const uint16_t Rw11CntlRHRP::kRFUNC_CUNIT;
104
const uint16_t Rw11CntlRHRP::kRFUNC_DONE;
105
const uint16_t Rw11CntlRHRP::kRFUNC_WIDLY;
106
 
107
const uint16_t Rw11CntlRHRP::kRPCS1_V_RUNIT;
108
const uint16_t Rw11CntlRHRP::kRPCS1_B_RUNIT;
109
const uint16_t Rw11CntlRHRP::kRPCS1_M_RATA;
110
const uint16_t Rw11CntlRHRP::kRPCS1_V_RIDLY;
111
const uint16_t Rw11CntlRHRP::kRPCS1_B_RIDLY;
112
 
113
const uint16_t Rw11CntlRHRP::kRPDA_V_TA;
114
const uint16_t Rw11CntlRHRP::kRPDA_B_TA;
115
const uint16_t Rw11CntlRHRP::kRPDA_B_SA;
116
 
117
const uint16_t Rw11CntlRHRP::kRPCS2_M_RWCO;
118
const uint16_t Rw11CntlRHRP::kRPCS2_M_WCE;
119
const uint16_t Rw11CntlRHRP::kRPCS2_M_NED;
120
const uint16_t Rw11CntlRHRP::kRPCS2_M_NEM;
121
const uint16_t Rw11CntlRHRP::kRPCS2_M_PGE;
122
const uint16_t Rw11CntlRHRP::kRPCS2_M_MXF;
123
const uint16_t Rw11CntlRHRP::kRPCS2_M_OR;
124
const uint16_t Rw11CntlRHRP::kRPCS2_M_IR;
125
const uint16_t Rw11CntlRHRP::kRPCS2_M_CLR;
126
const uint16_t Rw11CntlRHRP::kRPCS2_M_PAT;
127
const uint16_t Rw11CntlRHRP::kRPCS2_M_BAI;
128
const uint16_t Rw11CntlRHRP::kRPCS2_M_UNIT2;
129
const uint16_t Rw11CntlRHRP::kRPCS2_B_UNIT;
130
 
131
const uint16_t Rw11CntlRHRP::kRPDS_M_ATA;
132
const uint16_t Rw11CntlRHRP::kRPDS_M_ERP;
133
const uint16_t Rw11CntlRHRP::kRPDS_M_MOL;
134
const uint16_t Rw11CntlRHRP::kRPDS_M_WRL;
135
const uint16_t Rw11CntlRHRP::kRPDS_M_LBT;
136
const uint16_t Rw11CntlRHRP::kRPDS_M_DPR;
137
const uint16_t Rw11CntlRHRP::kRPDS_M_DRY;
138
const uint16_t Rw11CntlRHRP::kRPDS_M_VV;
139
const uint16_t Rw11CntlRHRP::kRPDS_M_OM ;
140
 
141
const uint16_t Rw11CntlRHRP::kRPER1_M_UNS;
142
const uint16_t Rw11CntlRHRP::kRPER1_M_WLE;
143
const uint16_t Rw11CntlRHRP::kRPER1_M_IAE;
144
const uint16_t Rw11CntlRHRP::kRPER1_M_AOE;
145
const uint16_t Rw11CntlRHRP::kRPER1_M_RMR;
146
const uint16_t Rw11CntlRHRP::kRPER1_M_ILF;
147
 
148
const uint16_t Rw11CntlRHRP::kRPDC_B_CA;
149
 
150
const uint16_t Rw11CntlRHRP::kRPCS3_M_IE;
151
const uint16_t Rw11CntlRHRP::kRPCS3_M_RSEARDONE;
152
const uint16_t Rw11CntlRHRP::kRPCS3_M_RPACKDONE;
153
const uint16_t Rw11CntlRHRP::kRPCS3_M_RPOREDONE;
154
const uint16_t Rw11CntlRHRP::kRPCS3_M_RSEEKDONE;
155
 
156
//------------------------------------------+-----------------------------------
157
//! Default constructor
158
 
159
Rw11CntlRHRP::Rw11CntlRHRP()
160
  : Rw11CntlBase<Rw11UnitRHRP,4>("rhrp"),
161
    fPC_rpcs1(0),
162
    fPC_rpcs2(0),
163
    fPC_rpcs3(0),
164
    fPC_rpwc(0),
165
    fPC_rpba(0),
166
    fPC_rpbae(0),
167
    fPC_cunit(0),
168
    fPC_rpds(0),
169
    fPC_rpda(0),
170
    fPC_rpdc(0),
171
    fRd_rpcs1(0),
172
    fRd_rpcs2(0),
173
    fRd_rpcs3(0),
174
    fRd_rpwc(0),
175
    fRd_rpba(0),
176
    fRd_rpbae(0),
177
    fRd_rpds(0),
178
    fRd_rpda(0),
179
    fRd_rpdc(0),
180
    fRd_addr(0),
181
    fRd_lba(0),
182
    fRd_nwrd(0),
183
    fRd_fu(0),
184
    fRd_ovr(false),
185
    fRdma(this,
186
          boost::bind(&Rw11CntlRHRP::RdmaPreExecCB,  this, _1, _2, _3, _4),
187
          boost::bind(&Rw11CntlRHRP::RdmaPostExecCB, this, _1, _2, _3, _4))
188
{
189
  // must be here because Units have a back-ptr (not available at Rw11CntlBase)
190
  for (size_t i=0; i<NUnit(); i++) {
191
    fspUnit[i].reset(new Rw11UnitRHRP(this, i));
192
  }
193
 
194
  fStats.Define(kStatNFuncWchk   , "NFuncWchk"    , "func WCHK");
195
  fStats.Define(kStatNFuncWrite  , "NFuncWrite"   , "func WRITE");
196
  fStats.Define(kStatNFuncRead   , "NFuncRead"    , "func READ");
197
  fStats.Define(kStatNFuncSear   , "NFuncSear"    , "func SEARCH (loc)");
198
  fStats.Define(kStatNFuncPack   , "NFuncPack"    , "func PACK ACK (loc)");
199
  fStats.Define(kStatNFuncPore   , "NFuncPore"    , "func PORT REL (loc)");
200
  fStats.Define(kStatNFuncSeek   , "NFuncSeek"    , "func SEEK (loc)");
201
}
202
 
203
//------------------------------------------+-----------------------------------
204
//! Destructor
205
 
206
Rw11CntlRHRP::~Rw11CntlRHRP()
207
{}
208
 
209
//------------------------------------------+-----------------------------------
210
//! FIXME_docs
211
 
212
void Rw11CntlRHRP::Config(const std::string& name, uint16_t base, int lam)
213
{
214
  ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
215
  return;
216
}
217
 
218
//------------------------------------------+-----------------------------------
219
//! FIXME_docs
220
 
221
void Rw11CntlRHRP::Start()
222
{
223
  if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
224
    throw Rexception("Rw11CntlRHRP::Start",
225
                     "Bad state: started, no lam, not enable, not found");
226
 
227
  // add device register address ibus and rbus mappings
228
  // done here because now Cntl bound to Cpu and Cntl probed
229
  Cpu().AllIAddrMapInsert(Name()+".cs1", Base() + kRPCS1);
230
  Cpu().AllIAddrMapInsert(Name()+".wc",  Base() + kRPWC);
231
  Cpu().AllIAddrMapInsert(Name()+".ba",  Base() + kRPBA);
232
  Cpu().AllIAddrMapInsert(Name()+".da",  Base() + kRPDA);
233
  Cpu().AllIAddrMapInsert(Name()+".cs2", Base() + kRPCS2);
234
  Cpu().AllIAddrMapInsert(Name()+".ds",  Base() + kRPDS);
235
  Cpu().AllIAddrMapInsert(Name()+".er1", Base() + kRPER1);
236
  Cpu().AllIAddrMapInsert(Name()+".as",  Base() + kRPAS);
237
  Cpu().AllIAddrMapInsert(Name()+".la",  Base() + kRPLA);
238
  Cpu().AllIAddrMapInsert(Name()+".db",  Base() + kRPDB);
239
  Cpu().AllIAddrMapInsert(Name()+".mr1", Base() + kRPMR1);
240
  Cpu().AllIAddrMapInsert(Name()+".dt",  Base() + kRPDT);
241
  Cpu().AllIAddrMapInsert(Name()+".sn",  Base() + kRPSN);
242
  Cpu().AllIAddrMapInsert(Name()+".of",  Base() + kRPOF);
243
  Cpu().AllIAddrMapInsert(Name()+".dc",  Base() + kRPDC);
244
  Cpu().AllIAddrMapInsert(Name()+".m13", Base() + kRxM13);
245
  Cpu().AllIAddrMapInsert(Name()+".m14", Base() + kRxM14);
246
  Cpu().AllIAddrMapInsert(Name()+".m15", Base() + kRxM15);
247
  Cpu().AllIAddrMapInsert(Name()+".ec1", Base() + kRPEC1);
248
  Cpu().AllIAddrMapInsert(Name()+".ec2", Base() + kRPEC2);
249
  Cpu().AllIAddrMapInsert(Name()+".bae", Base() + kRPBAE);
250
  Cpu().AllIAddrMapInsert(Name()+".cs3", Base() + kRPCS3);
251
 
252
  // setup primary info clist
253
  fPrimClist.Clear();
254
  fPrimClist.AddAttn();
255
  fPC_rpcs1 = Cpu().AddRibr(fPrimClist, fBase+kRPCS1);
256
  fPC_rpcs2 = Cpu().AddRibr(fPrimClist, fBase+kRPCS2);
257
  fPC_rpcs3 = Cpu().AddRibr(fPrimClist, fBase+kRPCS3);
258
  fPC_rpwc  = Cpu().AddRibr(fPrimClist, fBase+kRPWC);
259
  fPC_rpba  = Cpu().AddRibr(fPrimClist, fBase+kRPBA);
260
  fPC_rpbae = Cpu().AddRibr(fPrimClist, fBase+kRPBAE);
261
 
262
  fPC_cunit = Cpu().AddWibr(fPrimClist, fBase+kRPCS1,
263
                            (kRFUNC_CUNIT << kRPCS1_V_FUNC) );
264
 
265
  fPC_rpds  = Cpu().AddRibr(fPrimClist, fBase+kRPDS);
266
  fPC_rpda  = Cpu().AddRibr(fPrimClist, fBase+kRPDA);
267
  fPC_rpdc  = Cpu().AddRibr(fPrimClist, fBase+kRPDC);
268
 
269
  // add attn handler
270
  Server().AddAttnHandler(boost::bind(&Rw11CntlRHRP::AttnHandler, this, _1),
271
                          uint16_t(1)<<fLam, (void*)this);
272
 
273
  fStarted = true;
274
  return;
275
}
276
 
277
//------------------------------------------+-----------------------------------
278
//! FIXME_docs
279
 
280
void Rw11CntlRHRP::UnitSetup(size_t ind)
281
{
282
  Rw11UnitRHRP& unit = *fspUnit[ind];
283
  RlinkCommandList clist;
284
  Rw11Cpu& cpu  = Cpu();
285
 
286
  // only two mayor drive states are used
287
  //  power medium  wlock : ds flags
288
  //   off    ---     --- : dpr=0  mol=0  wrl=0  (disabled, type=off)
289
  //    on    off     --- : dpr=1  mol=0  wrl=0  (enabled, no file attached)
290
  //    on     on      no : dpr=1  mol=1  wrl=0  (file attached)
291
  //    on     on     yes : dpr=1  mol=1  wrl=1  (file attached + wlock)
292
 
293
  uint16_t rpds = 0;
294
 
295
  if (unit.Type() != "off") {               // is enabled
296
    rpds |= kRPDS_M_DPR;
297
    if (unit.Virt()) {                        // file attached
298
      rpds |= kRPDS_M_MOL;                    // -> set MOL
299
      rpds |= kRPDS_M_ERP;                    // -> clear ER1 via ERP=1
300
      if (unit.WProt()) rpds |= kRPDS_M_WRL; // in case write protected
301
    }
302
    if ((unit.Rpds() ^ rpds) & kRPDS_M_MOL) { // mol state change ?
303
      rpds |= kRPDS_M_ATA;                      // cause attentions
304
      rpds |= kRPDS_M_VV;                       // reset volume valid
305
    }
306
  }
307
 
308
  unit.SetRpds(rpds);                       // remember new DS
309
  cpu.AddWibr(clist, fBase+kRPCS1,          // setup unit
310
              (ind << kRPCS1_V_RUNIT) |
311
              (kRFUNC_WUNIT << kRPCS1_V_FUNC) );
312
  cpu.AddWibr(clist, fBase+kRPDT, unit.Rpdt()); // setup DT
313
  cpu.AddWibr(clist, fBase+kRPDS, rpds);        // setup DS
314
  Server().Exec(clist);
315
 
316
  return;
317
}
318
 
319
//------------------------------------------+-----------------------------------
320
//! FIXME_docs
321
 
322
bool Rw11CntlRHRP::BootCode(size_t unit, std::vector<uint16_t>& code,
323
                            uint16_t& aload, uint16_t& astart)
324
{
325
  uint16_t kBOOT_START = 02000;
326
  uint16_t bootcode[] = {      // rh/rp boot loader - from simh pdp11_rp.c (v3.9)
327
    0042102,                   // "BD"
328
    0012706, kBOOT_START,      // mov #boot_start, sp
329
    0012700, uint16_t(unit),   // mov #unit, r0
330
    0012701, 0176700,          // mov #RPCS1, r1
331
    0012761, 0000040, 0000010, // mov #CS2_CLR, 10(r1) ; reset
332
    0010061, 0000010,          // mov r0, 10(r1)       ; set unit
333
    0012711, 0000021,          // mov #RIP+GO, (r1)    ; pack ack
334
    0012761, 0010000, 0000032, // mov #FMT16B, 32(r1)  ; 16b mode
335
    0012761, 0177000, 0000002, // mov #-512., 2(r1)    ; set wc
336
    0005061, 0000004,          // clr 4(r1)            ; clr ba
337
    0005061, 0000006,          // clr 6(r1)            ; clr da
338
    0005061, 0000034,          // clr 34(r1)           ; clr cyl
339
    0012711, 0000071,          // mov #READ+GO, (r1)   ; read 
340
    0105711,                   // tstb (r1)            ; wait
341
    0100376,                   // bpl .-2
342
    0005002,                   // clr R2
343
    0005003,                   // clr R3
344
    0012704, uint16_t(kBOOT_START+020), // mov #start+020, r4
345
    0005005,                   // clr R5
346
    0105011,                   // clrb (r1)
347
    0005007                    // clr PC
348
    };
349
 
350
  code.clear();
351
  foreach_ (uint16_t& w, bootcode) code.push_back(w);
352
  aload  = kBOOT_START;
353
  astart = kBOOT_START+2;
354
  return true;
355
}
356
 
357
//------------------------------------------+-----------------------------------
358
//! FIXME_docs
359
 
360
void Rw11CntlRHRP::Dump(std::ostream& os, int ind, const char* text) const
361
{
362
  RosFill bl(ind);
363
  os << bl << (text?text:"--") << "Rw11CntlRHRP @ " << this << endl;
364
  os << bl << "  fPC_rpcs1:       " << RosPrintf(fPC_rpcs1,"d",6) << endl;
365
  os << bl << "  fPC_rpcs2:       " << RosPrintf(fPC_rpcs2,"d",6) << endl;
366
  os << bl << "  fPC_rpcs3:       " << RosPrintf(fPC_rpcs3,"d",6) << endl;
367
  os << bl << "  fPC_rpwc:        " << RosPrintf(fPC_rpwc,"d",6) << endl;
368
  os << bl << "  fPC_rpba:        " << RosPrintf(fPC_rpba,"d",6) << endl;
369
  os << bl << "  fPC_rpbae:       " << RosPrintf(fPC_rpbae,"d",6) << endl;
370
  os << bl << "  fPC_cunit:       " << RosPrintf(fPC_cunit,"d",6) << endl;
371
  os << bl << "  fPC_rpds:        " << RosPrintf(fPC_rpds,"d",6) << endl;
372
  os << bl << "  fPC_rpda:        " << RosPrintf(fPC_rpda,"d",6) << endl;
373
  os << bl << "  fPC_rpdc:        " << RosPrintf(fPC_rpdc,"d",6) << endl;
374
  os << bl << "  fRd_rpcs1:       " << RosPrintBvi(fRd_rpcs1) << endl;
375
  os << bl << "  fRd_rpcs2:       " << RosPrintBvi(fRd_rpcs2) << endl;
376
  os << bl << "  fRd_rpcs3:       " << RosPrintBvi(fRd_rpcs3) << endl;
377
  os << bl << "  fRd_rpwc:        " << RosPrintBvi(fRd_rpwc) << endl;
378
  os << bl << "  fRd_rpba:        " << RosPrintBvi(fRd_rpba) << endl;
379
  os << bl << "  fRd_rpbae:       " << RosPrintBvi(fRd_rpbae) << endl;
380
  os << bl << "  fRd_rpds:        " << RosPrintBvi(fRd_rpds) << endl;
381
  os << bl << "  fRd_rpda:        " << RosPrintBvi(fRd_rpda) << endl;
382
  os << bl << "  fRd_rpdc:        " << RosPrintBvi(fRd_rpdc) << endl;
383
  os << bl << "  fRd_addr:        " << RosPrintBvi(fRd_addr,8,22) << endl;
384
  os << bl << "  fRd_lba:         " << RosPrintf(fRd_lba,"d",6)  << endl;
385
  os << bl << "  fRd_nwrd:        " << RosPrintf(fRd_nwrd,"d",6) << endl;
386
  os << bl << "  fRd_fu:          " << RosPrintf(fRd_fu,"d",6) << endl;
387
  os << bl << "  fRd_ovr:         " << fRd_ovr  << endl;
388
  fRdma.Dump(os, ind+2, "fRdma: ");
389
  Rw11CntlBase<Rw11UnitRHRP,4>::Dump(os, ind, " ^");
390
  return;
391
}
392
 
393
//------------------------------------------+-----------------------------------
394
//! FIXME_docs
395
 
396
int Rw11CntlRHRP::AttnHandler(RlinkServer::AttnArgs& args)
397
{
398
  fStats.Inc(kStatNAttnHdl);
399
  Server().GetAttnInfo(args, fPrimClist);
400
 
401
  uint16_t rpcs1 = fPrimClist[fPC_rpcs1].Data();
402
  uint16_t rpcs2 = fPrimClist[fPC_rpcs2].Data();
403
  uint16_t rpcs3 = fPrimClist[fPC_rpcs3].Data();
404
  uint16_t rpwc  = fPrimClist[fPC_rpwc ].Data();
405
  uint16_t rpba  = fPrimClist[fPC_rpba ].Data();
406
  uint16_t rpbae = fPrimClist[fPC_rpbae].Data();
407
  uint16_t rpds  = fPrimClist[fPC_rpds ].Data();
408
  uint16_t rpda  = fPrimClist[fPC_rpda ].Data();
409
  uint16_t rpdc  = fPrimClist[fPC_rpdc ].Data();
410
 
411
  uint16_t unum  = rpcs2 & kRPCS2_B_UNIT;
412
  uint16_t fu    = (rpcs1>>kRPCS1_V_FUNC)  & kRPCS1_B_FUNC;
413
 
414
  uint32_t addr = uint32_t(rpbae)<<16 | uint32_t(rpba);
415
 
416
  uint16_t sa   =  rpda              & kRPDA_B_SA;
417
  uint16_t ta   = (rpda>>kRPDA_V_TA) & kRPDA_B_TA;
418
  uint16_t ca   =  rpdc              & kRPDC_B_CA;
419
 
420
  uint32_t nwrd = (~uint32_t(rpwc)&0xffff) + 1; // transfer size in words
421
 
422
  // all 4 units are always available, but check anyway
423
  if (unum > NUnit())
424
    throw Rexception("Rw11CntlRHRP::AttnHandler","Bad state: unum > NUnit()");
425
 
426
  Rw11UnitRHRP& unit = *fspUnit[unum];
427
  //Rw11Cpu& cpu = Cpu();
428
  RlinkCommandList clist;
429
 
430
  uint32_t lba  = unit.Chs2Lba(ca,ta,sa);
431
  uint32_t nblk = unit.Nwrd2Nblk(nwrd);
432
 
433
  if (fTraceLevel>0) {
434
    RlogMsg lmsg(LogFile());
435
    static const char* fumnemo[32] =
436
      {"00 ","01 ","02 ","03 ","04 ","05 ","06 ","07 ",    // 00---
437
       "10 ","11 ","12 ","13 ","14 ","15 ","16 ","17 ",    // 01---
438
       "20 ","21 ","22 ","23 ","wc ","wch","26 ","27 ",    // 10---
439
       "wr ","wrh","32 ","33 ","rd ","rdh","36 ","37 "};   // 11---
440
    lmsg << "-I RHRP"
441
         << " fu=" << fumnemo[fu&037]
442
         << " cs=" << RosPrintBvi(rpcs1,8)
443
         << "," << RosPrintBvi(rpcs2,8)
444
         << " ad=" << RosPrintBvi(addr,8,22)
445
         << " pa=" << unum
446
         << "," << RosPrintf(ca,"d",3)
447
         << "," << RosPrintf(ta,"d",2)
448
         << "," << RosPrintf(sa,"d",2)
449
         << " la,nw=" << RosPrintf(lba,"d",6)
450
         << ",";
451
    if (nwrd==65536) lmsg << "  (0)"; else lmsg << RosPrintf(nwrd,"d",5);
452
  }
453
 
454
  // handle cs3 done flags, just count them
455
  if (rpcs3 & kRPCS3_M_RSEARDONE) fStats.Inc(kStatNFuncSear);
456
  if (rpcs3 & kRPCS3_M_RPOREDONE) fStats.Inc(kStatNFuncPore);
457
  if (rpcs3 & kRPCS3_M_RPACKDONE) fStats.Inc(kStatNFuncPack);
458
  if (rpcs3 & kRPCS3_M_RSEEKDONE) fStats.Inc(kStatNFuncSeek);
459
 
460
  // check for overrun (read/write beyond last track
461
  // if found, truncate request length
462
  bool ovr = lba + nblk > unit.NBlock();
463
  if (ovr) nwrd = (unit.NBlock()-lba) * (unit.BlockSize()/2);
464
 
465
  // remember request parameters for call back and error exit handling
466
 
467
  fRd_rpcs1 = rpcs1;
468
  fRd_rpcs2 = rpcs2;
469
  fRd_rpcs3 = rpcs3;
470
  fRd_rpwc  = rpwc;
471
  fRd_rpba  = rpba;
472
  fRd_rpbae = rpbae;
473
  fRd_rpds  = rpds;
474
  fRd_rpda  = rpda;
475
  fRd_rpdc  = rpdc;
476
  fRd_addr  = addr;
477
  fRd_lba   = lba;
478
  fRd_nwrd  = nwrd;
479
  fRd_fu    = fu;
480
  fRd_ovr   = ovr;
481
 
482
  // check for general abort conditions
483
  // note: only 'data transfer' functions handled via backend
484
  //       SEEK and others are done in ibdr_rhrp autonomously
485
 
486
  // not attached --> signal drive unsave status
487
  if (! unit.Virt()) {                      // not attached
488
    AddErrorExit(clist, kRPER1_M_UNS);      // signal UNS (drive unsafe)
489
    Server().Exec(clist);                   // doit
490
    return 0;
491
  }
492
 
493
  // invalid disk address
494
  if (ca > unit.NCylinder() || ta > unit.NHead() || sa > unit.NSector()) {
495
    AddErrorExit(clist, kRPER1_M_IAE);      // signal IAE (invalid address err)
496
    Server().Exec(clist);                   // doit
497
    return 0;
498
  }
499
 
500
  // now handle the functions
501
  if (fu == kFUNC_WRITE) {                  // Write -------------------------
502
    fStats.Inc(kStatNFuncWrite);
503
    if (unit.WProt()) {                     // write on write locked drive ?
504
      AddErrorExit(clist, kRPER1_M_WLE);    // signal WLE (write lock error)
505
    } else {
506
      fRdma.QueueDiskWrite(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
507
    }
508
 
509
  } else if (fu == kFUNC_WCD) {             // Write Check -------------------
510
    fStats.Inc(kStatNFuncWchk );
511
    fRdma.QueueDiskWriteCheck(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
512
 
513
  } else if (fu == kFUNC_READ ) {           // Read --------------------------
514
    fStats.Inc(kStatNFuncRead);
515
    fRdma.QueueDiskRead(addr, nwrd, Rw11Cpu::kCPAH_M_22BIT, lba, &unit);
516
 
517
  } else {
518
    // FIXME: handle other special functions (currently simply error out !!)
519
    AddErrorExit(clist, kRPER1_M_ILF);      // signal ILF (invalid function)
520
    Server().Exec(clist);                   // doit
521
    return 0;
522
  }
523
 
524
  if (clist.Size()) {                       // if handled directly
525
    Server().Exec(clist);                   // doit
526
  }
527
 
528
  return 0;
529
}
530
 
531
//------------------------------------------+-----------------------------------
532
//! FIXME_docs
533
 
534
void Rw11CntlRHRP::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
535
                                 RlinkCommandList& clist)
536
{
537
  // if last chunk and not doing WCD add a labo and normal exit csr update
538
  if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kFUNC_WCD) {
539
    clist.AddLabo();
540
    AddNormalExit(clist, nwdone+nwnext, 0, 0);
541
  }
542
  return;
543
}
544
 
545
//------------------------------------------+-----------------------------------
546
//! FIXME_docs
547
 
548
void Rw11CntlRHRP::RdmaPostExecCB(int stat, size_t ndone,
549
                                  RlinkCommandList& clist, size_t ncmd)
550
{
551
  if (stat == Rw11Rdma::kStatusBusy) return;
552
 
553
  uint16_t rper1 = 0;
554
  uint16_t rpcs2 = 0;
555
 
556
  if (fRd_fu == kFUNC_WCD) {
557
    size_t nwcok = fRdma.WriteCheck(ndone);
558
    if (nwcok != ndone) {                   // if mismatch found
559
      rpcs2 = kRPCS2_M_WCE;
560
      if (ndone & 0x1) rpcs2 = kRPCS2_M_RWCO; // failed in odd word !
561
      ndone = nwcok;                        // truncate word count
562
    }
563
  }
564
 
565
  // handle Rdma aborts
566
  if (stat == Rw11Rdma::kStatusFailRdma) rpcs2 = kRPCS2_M_NEM;
567
 
568
  // check for fused csr updates
569
  if (clist.Size() > ncmd) {
570
    uint8_t  ccode = clist[ncmd].Command();
571
    uint16_t cdata = clist[ncmd].Data();
572
    if (ccode != RlinkCommand::kCmdLabo || (rper1 != 0 && cdata == 0))
573
      throw Rexception("Rw11CntlRHRP::RdmaPostExecCB",
574
                       "Bad state: Labo not found or missed abort");
575
    if (cdata == 0) return;
576
  }
577
 
578
  // finally to RHRP register update
579
  RlinkCommandList clist1;
580
  AddNormalExit(clist1, ndone, rper1, rpcs2);
581
  Server().Exec(clist1);
582
  return;
583
}
584
 
585
//------------------------------------------+-----------------------------------
586
//! FIXME_docs
587
 
588
void Rw11CntlRHRP::AddErrorExit(RlinkCommandList& clist, uint16_t rper1)
589
{
590
  Rw11Cpu& cpu  = Cpu();
591
 
592
  cpu.AddWibr(clist, fBase+kRPCS1, (kRFUNC_CUNIT<<kRPCS1_V_FUNC) );
593
  cpu.AddWibr(clist, fBase+kRPER1, rper1);
594
 
595
  // use ATA termination ! Comes late, but should be ok
596
  cpu.AddWibr(clist, fBase+kRPCS1, kRPCS1_M_RATA|(kRFUNC_DONE<<kRPCS1_V_FUNC) );
597
 
598
  if (fTraceLevel>1) {
599
    RlogMsg lmsg(LogFile());
600
    lmsg << "-I RHRP"
601
         << "   err "
602
         << " cs1=" << RosPrintBvi(fRd_rpcs1,8)
603
         << " er1=" << RosPrintBvi(rper1,2,16);
604
  }
605
 
606
  return;
607
}
608
 
609
//------------------------------------------+-----------------------------------
610
//! FIXME_docs
611
 
612
void Rw11CntlRHRP::AddNormalExit(RlinkCommandList& clist, size_t ndone,
613
                                 uint16_t rper1, uint16_t rpcs2)
614
{
615
  Rw11Cpu& cpu  = Cpu();
616
  uint16_t unum  = fRd_rpcs2 & kRPCS2_B_UNIT;
617
  Rw11UnitRHRP& unit = *fspUnit[unum];
618
 
619
  size_t nblk    = unit.Nwrd2Nblk(ndone);
620
  uint32_t addr  = fRd_addr + 2*ndone;
621
  size_t   lba   = fRd_lba  + nblk;
622
 
623
  uint16_t ba   = addr & 0177776;           // get lower 16 bits
624
  uint16_t bae  = (addr>>16) & 077;         // get upper  6 bits
625
 
626
  uint16_t sa;
627
  uint16_t ta;
628
  uint16_t ca;
629
  unit.Lba2Chs(lba, ca,ta,sa);
630
  uint16_t da   = (ta<<kRPDA_V_TA) | sa;
631
  uint16_t wc   = fRd_rpwc + uint16_t(ndone);
632
 
633
  if (fRd_ovr) rper1 |= kRPER1_M_AOE;
634
 
635
  cpu.AddWibr(clist, fBase+kRPWC,  wc);
636
  cpu.AddWibr(clist, fBase+kRPBA,  ba);
637
  cpu.AddWibr(clist, fBase+kRPBAE, bae);
638
 
639
  cpu.AddWibr(clist, fBase+kRPCS1, (kRFUNC_CUNIT<<kRPCS1_V_FUNC) );
640
  cpu.AddWibr(clist, fBase+kRPDA,  da);
641
  cpu.AddWibr(clist, fBase+kRPDC,  ca);
642
 
643
  if (rper1)  cpu.AddWibr(clist, fBase+kRPER1, rper1);
644
  if (rpcs2)  cpu.AddWibr(clist, fBase+kRPER1, rpcs2);
645
 
646
  cpu.AddWibr(clist, fBase+kRPCS1, (kRFUNC_DONE<<kRPCS1_V_FUNC) );
647
 
648
  if (fTraceLevel>1) {
649
    RlogMsg lmsg(LogFile());
650
    if (rper1 || rpcs2) {
651
      lmsg << "-I RHRP"
652
           << "   err "
653
           << " er1=" << RosPrintBvi(rper1,2,16)
654
           << " cs2=" << RosPrintBvi(rpcs2,2,8)
655
           << endl;
656
    }
657
    lmsg << "-I RHRP"
658
         << (rper1==0 ? "    ok " :"   err ")
659
         << " we=" << RosPrintBvi(wc,8) << "," << RosPrintBvi(rper1,8)
660
         << " ad=" << RosPrintBvi(addr,8,22)
661
         << " pa=" << unum
662
         << "," << RosPrintf(ca,"d",3)
663
         << "," << RosPrintf(ta,"d",2)
664
         << "," << RosPrintf(sa,"d",2)
665
         << " ca,da=" << RosPrintBvi(ca,8,10) << "," << RosPrintBvi(da,8);
666
  }
667
 
668
  return;
669
}
670
 
671
 
672
} // end namespace Retro

powered by: WebSVN 2.1.0

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