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

Subversion Repositories w11

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

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

Line No. Rev Author Line
1 29 wfjm
// $Id: Rw11CntlRK11.cpp 647 2015-02-17 22:35:36Z mueller $
2 20 wfjm
//
3 28 wfjm
// Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 20 wfjm
// Other credits: 
5 25 wfjm
//   the boot code is from the simh project and Copyright Robert M Supnik
6 20 wfjm
// 
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 29 wfjm
// 2015-02-17   647   2.0.1  use Nwrd2Nblk(); BUGFIX: revise RdmaPostExecCB()
19 28 wfjm
// 2015-01-04   628   2.0    use Rw11RdmaDisk
20
// 2014-12-30   625   1.2    adopt to Rlink V4 attn logic
21
// 2014-12-25   621   1.1    adopt to 4k word ibus window
22 25 wfjm
// 2014-06-14   562   1.0.1  Add stats
23 20 wfjm
// 2013-04-20   508   1.0    Initial version
24
// 2013-02-10   485   0.1    First draft
25
// ---------------------------------------------------------------------------
26
 
27
/*!
28
  \file
29 29 wfjm
  \version $Id: Rw11CntlRK11.cpp 647 2015-02-17 22:35:36Z mueller $
30 20 wfjm
  \brief   Implemenation of Rw11CntlRK11.
31
*/
32
 
33
#include "boost/bind.hpp"
34
#include "boost/foreach.hpp"
35
#define foreach_ BOOST_FOREACH
36
 
37
#include "librtools/RosFill.hpp"
38
#include "librtools/RosPrintBvi.hpp"
39
#include "librtools/RosPrintf.hpp"
40
#include "librtools/Rexception.hpp"
41
#include "librtools/RlogMsg.hpp"
42
 
43
#include "Rw11CntlRK11.hpp"
44
 
45
using namespace std;
46
 
47
/*!
48
  \class Retro::Rw11CntlRK11
49
  \brief FIXME_docs
50
*/
51
 
52
// all method definitions in namespace Retro
53
namespace Retro {
54
 
55
//------------------------------------------+-----------------------------------
56
// constants definitions
57
 
58
const uint16_t Rw11CntlRK11::kIbaddr;
59
const int      Rw11CntlRK11::kLam;
60
 
61
const uint16_t Rw11CntlRK11::kRKDS;
62
const uint16_t Rw11CntlRK11::kRKER;
63
const uint16_t Rw11CntlRK11::kRKCS;
64
const uint16_t Rw11CntlRK11::kRKWC;
65
const uint16_t Rw11CntlRK11::kRKBA;
66
const uint16_t Rw11CntlRK11::kRKDA;
67
const uint16_t Rw11CntlRK11::kRKMR;
68
 
69
const uint16_t Rw11CntlRK11::kProbeOff;
70
const bool     Rw11CntlRK11::kProbeInt;
71
const bool     Rw11CntlRK11::kProbeRem;
72
 
73
const uint16_t Rw11CntlRK11::kRKDS_M_ID;
74
const uint16_t Rw11CntlRK11::kRKDS_V_ID;
75
const uint16_t Rw11CntlRK11::kRKDS_B_ID;
76
const uint16_t Rw11CntlRK11::kRKDS_M_HDEN;
77
const uint16_t Rw11CntlRK11::kRKDS_M_DRU;
78
const uint16_t Rw11CntlRK11::kRKDS_M_SIN;
79
const uint16_t Rw11CntlRK11::kRKDS_M_SOK;
80
const uint16_t Rw11CntlRK11::kRKDS_M_DRY;
81
const uint16_t Rw11CntlRK11::kRKDS_M_ADRY;
82
const uint16_t Rw11CntlRK11::kRKDS_M_WPS;
83
const uint16_t Rw11CntlRK11::kRKDS_B_SC;
84
 
85
const uint16_t Rw11CntlRK11::kRKER_M_DRE;
86
const uint16_t Rw11CntlRK11::kRKER_M_OVR;
87
const uint16_t Rw11CntlRK11::kRKER_M_WLO;
88
const uint16_t Rw11CntlRK11::kRKER_M_PGE;
89
const uint16_t Rw11CntlRK11::kRKER_M_NXM;
90
const uint16_t Rw11CntlRK11::kRKER_M_NXD;
91
const uint16_t Rw11CntlRK11::kRKER_M_NXC;
92
const uint16_t Rw11CntlRK11::kRKER_M_NXS;
93
const uint16_t Rw11CntlRK11::kRKER_M_CSE;
94
const uint16_t Rw11CntlRK11::kRKER_M_WCE;
95
 
96
const uint16_t Rw11CntlRK11::kRKCS_M_MAINT;
97
const uint16_t Rw11CntlRK11::kRKCS_M_IBA;
98
const uint16_t Rw11CntlRK11::kRKCS_M_FMT;
99
const uint16_t Rw11CntlRK11::kRKCS_M_RWA;
100
const uint16_t Rw11CntlRK11::kRKCS_M_SSE;
101
const uint16_t Rw11CntlRK11::kRKCS_M_MEX;
102
const uint16_t Rw11CntlRK11::kRKCS_V_MEX;
103
const uint16_t Rw11CntlRK11::kRKCS_B_MEX;
104
const uint16_t Rw11CntlRK11::kRKCS_V_FUNC;
105
const uint16_t Rw11CntlRK11::kRKCS_B_FUNC;
106
const uint16_t Rw11CntlRK11::kRKCS_M_GO;
107
 
108 29 wfjm
const uint16_t Rw11CntlRK11::kFUNC_CRESET;
109
const uint16_t Rw11CntlRK11::kFUNC_WRITE;
110
const uint16_t Rw11CntlRK11::kFUNC_READ;
111
const uint16_t Rw11CntlRK11::kFUNC_WCHK;
112
const uint16_t Rw11CntlRK11::kFUNC_SEEK;
113
const uint16_t Rw11CntlRK11::kFUNC_RCHK;
114
const uint16_t Rw11CntlRK11::kFUNC_DRESET;
115
const uint16_t Rw11CntlRK11::kFUNC_WLOCK;
116
 
117 20 wfjm
const uint16_t Rw11CntlRK11::kRKDA_M_DRSEL;
118
const uint16_t Rw11CntlRK11::kRKDA_V_DRSEL;
119
const uint16_t Rw11CntlRK11::kRKDA_B_DRSEL;
120
const uint16_t Rw11CntlRK11::kRKDA_M_CYL;
121
const uint16_t Rw11CntlRK11::kRKDA_V_CYL;
122
const uint16_t Rw11CntlRK11::kRKDA_B_CYL;
123
const uint16_t Rw11CntlRK11::kRKDA_M_SUR;
124
const uint16_t Rw11CntlRK11::kRKDA_V_SUR;
125
const uint16_t Rw11CntlRK11::kRKDA_B_SUR;
126
const uint16_t Rw11CntlRK11::kRKDA_B_SC;
127
 
128
const uint16_t Rw11CntlRK11::kRKMR_M_RID;
129
const uint16_t Rw11CntlRK11::kRKMR_V_RID;
130
const uint16_t Rw11CntlRK11::kRKMR_M_CRDONE;
131
const uint16_t Rw11CntlRK11::kRKMR_M_SBCLR;
132
const uint16_t Rw11CntlRK11::kRKMR_M_CRESET;
133
const uint16_t Rw11CntlRK11::kRKMR_M_FDONE;
134
 
135
//------------------------------------------+-----------------------------------
136
//! Default constructor
137
 
138
Rw11CntlRK11::Rw11CntlRK11()
139
  : Rw11CntlBase<Rw11UnitRK11,8>("rk11"),
140
    fPC_rkwc(0),
141
    fPC_rkba(0),
142
    fPC_rkda(0),
143
    fPC_rkmr(0),
144
    fPC_rkcs(0),
145
    fRd_rkcs(0),
146
    fRd_rkda(0),
147
    fRd_addr(0),
148
    fRd_lba(0),
149
    fRd_nwrd(0),
150 28 wfjm
    fRd_fu(0),
151
    fRd_ovr(false),
152
    fRdma(this,
153 29 wfjm
          boost::bind(&Rw11CntlRK11::RdmaPreExecCB,  this, _1, _2, _3, _4),
154 28 wfjm
          boost::bind(&Rw11CntlRK11::RdmaPostExecCB, this, _1, _2, _3, _4))
155 20 wfjm
{
156 28 wfjm
  // must be here because Units have a back-ptr (not available at Rw11CntlBase)
157 20 wfjm
  for (size_t i=0; i<NUnit(); i++) {
158
    fspUnit[i].reset(new Rw11UnitRK11(this, i));
159
  }
160 25 wfjm
 
161
  fStats.Define(kStatNFuncCreset , "NFuncCreset"  , "func CRESET");
162
  fStats.Define(kStatNFuncWrite  , "NFuncWrite"   , "func WRITE");
163
  fStats.Define(kStatNFuncRead   , "NFuncRead"    , "func READ");
164
  fStats.Define(kStatNFuncWchk   , "NFuncWchk"    , "func WCHK");
165
  fStats.Define(kStatNFuncSeek   , "NFuncSeek"    , "func SEEK");
166
  fStats.Define(kStatNFuncRchk   , "NFuncRchk"    , "func RCHK");
167
  fStats.Define(kStatNFuncDreset , "NFuncDreset"  , "func DRESET");
168
  fStats.Define(kStatNFuncWlock  , "NFuncWlock "  , "func WLOCK");
169 20 wfjm
}
170
 
171
//------------------------------------------+-----------------------------------
172
//! Destructor
173
 
174
Rw11CntlRK11::~Rw11CntlRK11()
175
{}
176
 
177
//------------------------------------------+-----------------------------------
178
//! FIXME_docs
179
 
180
void Rw11CntlRK11::Config(const std::string& name, uint16_t base, int lam)
181
{
182
  ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
183
  return;
184
}
185
 
186
//------------------------------------------+-----------------------------------
187
//! FIXME_docs
188
 
189
void Rw11CntlRK11::Start()
190
{
191
  if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
192 25 wfjm
    throw Rexception("Rw11CntlRK11::Start",
193 20 wfjm
                     "Bad state: started, no lam, not enable, not found");
194
 
195 28 wfjm
  // add device register address ibus and rbus mappings
196
  // done here because now Cntl bound to Cpu and Cntl probed
197
  Cpu().AllAddrMapInsert(Name()+".ds", Base() + kRKDS);
198
  Cpu().AllAddrMapInsert(Name()+".er", Base() + kRKER);
199
  Cpu().AllAddrMapInsert(Name()+".cs", Base() + kRKCS);
200
  Cpu().AllAddrMapInsert(Name()+".wc", Base() + kRKWC);
201
  Cpu().AllAddrMapInsert(Name()+".ba", Base() + kRKBA);
202
  Cpu().AllAddrMapInsert(Name()+".da", Base() + kRKDA);
203
  Cpu().AllAddrMapInsert(Name()+".mr", Base() + kRKMR);
204
 
205 20 wfjm
  // setup primary info clist
206
  fPrimClist.Clear();
207 28 wfjm
  fPrimClist.AddAttn();
208 20 wfjm
  fPC_rkwc = Cpu().AddRibr(fPrimClist, fBase+kRKWC);
209
  fPC_rkba = Cpu().AddRibr(fPrimClist, fBase+kRKBA);
210
  fPC_rkda = Cpu().AddRibr(fPrimClist, fBase+kRKDA);
211
  fPC_rkmr = Cpu().AddRibr(fPrimClist, fBase+kRKMR); // read to monitor CRDONE
212
  fPC_rkcs = Cpu().AddRibr(fPrimClist, fBase+kRKCS);
213
 
214
  // add attn handler
215
  Server().AddAttnHandler(boost::bind(&Rw11CntlRK11::AttnHandler, this, _1),
216
                          uint16_t(1)<<fLam, (void*)this);
217
 
218
  fStarted = true;
219
  return;
220
}
221
 
222
//------------------------------------------+-----------------------------------
223
//! FIXME_docs
224
 
225
void Rw11CntlRK11::UnitSetup(size_t ind)
226
{
227
  Rw11UnitRK11& unit = *fspUnit[ind];
228
  Rw11Cpu& cpu  = Cpu();
229
  RlinkCommandList clist;
230
 
231
  uint16_t rkds = ind<<kRKDS_V_ID;
232
  if (unit.Virt()) {                        // file attached
233
    rkds |= kRKDS_M_HDEN;                   // always high density
234
    rkds |= kRKDS_M_SOK;                    // always sector counter OK ?FIXME?
235
    rkds |= kRKDS_M_DRY;                    // drive available
236
    rkds |= kRKDS_M_ADRY;                   // access available
237
    if (unit.WProt())                       // in case write protected
238
      rkds |= kRKDS_M_WPS;
239
  }
240
  unit.SetRkds(rkds);
241
  cpu.AddWibr(clist, fBase+kRKDS, rkds);
242
  Server().Exec(clist);
243
 
244
  return;
245
}
246
 
247
//------------------------------------------+-----------------------------------
248
//! FIXME_docs
249
 
250
bool Rw11CntlRK11::BootCode(size_t unit, std::vector<uint16_t>& code,
251
                            uint16_t& aload, uint16_t& astart)
252
{
253
  uint16_t kBOOT_START = 02000;
254 25 wfjm
  uint16_t bootcode[] = {      // rk11 boot loader - from simh pdp11_rk.c (v3.9)
255 21 wfjm
    0042113,                   // "KD"
256
    0012706, kBOOT_START,      // MOV #boot_start, SP
257
    0012700, uint16_t(unit),   // MOV #unit, R0        ; unit number
258
    0010003,                   // MOV R0, R3
259
    0000303,                   // SWAB R3
260
    0006303,                   // ASL R3
261
    0006303,                   // ASL R3
262
    0006303,                   // ASL R3
263
    0006303,                   // ASL R3
264
    0006303,                   // ASL R3
265
    0012701, 0177412,          // MOV #RKDA, R1        ; rkda
266
    0010311,                   // MOV R3, (R1)         ; load da
267
    0005041,                   // CLR -(R1)            ; clear ba
268
    0012741, 0177000,          // MOV #-256.*2, -(R1)  ; load wc
269
    0012741, 0000005,          // MOV #READ+GO, -(R1)  ; read & go
270
    0005002,                   // CLR R2
271
    0005003,                   // CLR R3
272 25 wfjm
    0012704, uint16_t(kBOOT_START+020),  // MOV #START+20, R4 ; ?? unclear ??
273 21 wfjm
    0005005,                   // CLR R5
274
    0105711,                   // TSTB (R1)
275
    0100376,                   // BPL .-4
276
    0105011,                   // CLRB (R1)
277
    0005007                    // CLR PC     (5007)
278 20 wfjm
  };
279
 
280
  code.clear();
281
  foreach_ (uint16_t& w, bootcode) code.push_back(w);
282
  aload  = kBOOT_START;
283
  astart = kBOOT_START+2;
284
  return true;
285
}
286
 
287
//------------------------------------------+-----------------------------------
288
//! FIXME_docs
289
 
290
void Rw11CntlRK11::Dump(std::ostream& os, int ind, const char* text) const
291
{
292
  RosFill bl(ind);
293
  os << bl << (text?text:"--") << "Rw11CntlRK11 @ " << this << endl;
294
  os << bl << "  fPC_rkwc:        " << fPC_rkwc << endl;
295
  os << bl << "  fPC_rkba:        " << fPC_rkba << endl;
296
  os << bl << "  fPC_rkda:        " << fPC_rkda << endl;
297
  os << bl << "  fPC_rkmr:        " << fPC_rkmr << endl;
298
  os << bl << "  fPC_rkcs:        " << fPC_rkcs << endl;
299
  os << bl << "  fRd_rkcs:        " << fRd_rkcs << endl;
300
  os << bl << "  fRd_rkda:        " << fRd_rkda << endl;
301
  os << bl << "  fRd_addr:        " << fRd_addr << endl;
302
  os << bl << "  fRd_lba:         " << fRd_lba  << endl;
303
  os << bl << "  fRd_nwrd:        " << fRd_nwrd << endl;
304 28 wfjm
  os << bl << "  fRd_fu:          " << fRd_fu  << endl;
305 20 wfjm
  os << bl << "  fRd_ovr:         " << fRd_ovr  << endl;
306 28 wfjm
  fRdma.Dump(os, ind+2, "fRdma: ");
307 20 wfjm
  Rw11CntlBase<Rw11UnitRK11,8>::Dump(os, ind, " ^");
308
  return;
309
}
310
 
311
//------------------------------------------+-----------------------------------
312
//! FIXME_docs
313
 
314 28 wfjm
int Rw11CntlRK11::AttnHandler(RlinkServer::AttnArgs& args)
315 20 wfjm
{
316 28 wfjm
  fStats.Inc(kStatNAttnHdl);
317
  Server().GetAttnInfo(args, fPrimClist);
318 20 wfjm
 
319 28 wfjm
  uint16_t rkwc = fPrimClist[fPC_rkwc].Data();
320
  uint16_t rkba = fPrimClist[fPC_rkba].Data();
321
  uint16_t rkda = fPrimClist[fPC_rkda].Data();
322
  //uint16_t rkmr = fPrimClist[fPC_rkmr].Data();
323
  uint16_t rkcs = fPrimClist[fPC_rkcs].Data();
324 20 wfjm
 
325
  uint16_t se   =  rkda                 & kRKDA_B_SC;
326
  uint16_t hd   = (rkda>>kRKDA_V_SUR)   & kRKDA_B_SUR;
327
  uint16_t cy   = (rkda>>kRKDA_V_CYL)   & kRKDA_B_CYL;
328
  uint16_t dr   = (rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
329
 
330
  bool go       =  rkcs & kRKCS_M_GO;
331
  uint16_t fu   = (rkcs>>kRKCS_V_FUNC)  & kRKCS_B_FUNC;
332
  uint16_t mex  = (rkcs>>kRKCS_V_MEX)   & kRKCS_B_MEX;
333
  uint32_t addr = uint32_t(mex)<<16 | uint32_t(rkba);
334
 
335
  // Note: apparently are operands first promoted to 32 bit -> mask after ~ !
336
  uint32_t nwrd = (~uint32_t(rkwc)&0xffff) + 1; // transfer size in words
337
 
338
  if (!go) {
339
    RlogMsg lmsg(LogFile());
340
    lmsg << "-I RK11 cs=" << RosPrintBvi(rkcs,8)
341
         << "  go=0, spurious attn, dropped";
342
    return 0;
343
  }
344
 
345
  // all 8 units are always available, but check anyway
346
  if (dr > NUnit())
347
    throw Rexception("Rw11CntlRK11::AttnHandler","Bad state: dr > NUnit()");
348
 
349
  Rw11UnitRK11& unit = *fspUnit[dr];
350
  Rw11Cpu& cpu = Cpu();
351
  RlinkCommandList clist;
352
 
353
  uint32_t lba  = unit.Chs2Lba(cy,hd,se);
354 29 wfjm
  uint32_t nblk = unit.Nwrd2Nblk(nwrd);
355 20 wfjm
 
356
  uint16_t rker = 0;
357
  uint16_t rkds = unit.Rkds();
358
 
359
  if (fTraceLevel>0) {
360
    RlogMsg lmsg(LogFile());
361 28 wfjm
    static const char* fumnemo[8] = {"cr","w ","r ","wc","sk","rc","dr","wl"};
362
 
363 20 wfjm
    lmsg << "-I RK11 cs=" << RosPrintBvi(rkcs,8)
364
         << " da=" << RosPrintBvi(rkda,8)
365
         << " ad=" << RosPrintBvi(addr,8,18)
366 28 wfjm
         << " fu=" << fumnemo[fu&0x7]
367 20 wfjm
         << " dchs=" << dr
368
         << "," << RosPrintf(cy,"d",3)
369
         << "," << hd
370
         << "," << RosPrintf(se,"d",2)
371
         << " lba,nw=" << RosPrintf(lba,"d",4)
372
         << "," << RosPrintf(nwrd,"d",5);
373
  }
374
 
375
  // check for general abort conditions
376 29 wfjm
  if (fu != kFUNC_CRESET &&                 // function not control reset
377 20 wfjm
      (!unit.Virt())) {                     //   and drive not attached
378
    rker = kRKER_M_NXD;                     //   --> abort with NXD error
379
 
380 29 wfjm
  } else if (fu != kFUNC_WRITE &&           // function neither write
381
             fu != kFUNC_READ &&            //   nor read
382 20 wfjm
             (rkcs & (kRKCS_M_FMT|kRKCS_M_RWA))) { // and FMT or RWA set 
383
    rker = kRKER_M_PGE;                     //   --> abort with PGE error
384
  } else if (rkcs & kRKCS_M_RWA) {          // RWA not supported
385
    rker = kRKER_M_DRE;                     //   --> abort with DRE error
386
  }
387
 
388
  if (rker) {
389
    cpu.AddWibr(clist, fBase+kRKER, rker);
390 29 wfjm
    if (fu == kFUNC_SEEK || fu == kFUNC_DRESET)
391 20 wfjm
      cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_SBCLR | (1u<<dr));
392
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
393
    LogRker(rker);
394
    Server().Exec(clist);
395
    return 0;
396
  }
397
 
398 29 wfjm
  // check for overrun (read/write beyond cylinder 203)
399 20 wfjm
  // if found, truncate request length
400
  bool ovr = lba + nblk > unit.NBlock();
401
  if (ovr) nwrd = (unit.NBlock()-lba) * (unit.BlockSize()/2);
402
 
403 28 wfjm
  // remember request parameters for call back
404
  fRd_rkcs  = rkcs;
405
  fRd_rkda  = rkda;
406
  fRd_addr  = addr;
407
  fRd_lba   = lba;
408
  fRd_nwrd  = nwrd;
409
  fRd_ovr   = ovr;
410
  fRd_fu    = fu;
411
 
412 20 wfjm
  // now handle the functions
413 29 wfjm
  if (fu == kFUNC_CRESET) {                 // Control reset -----------------
414 25 wfjm
    fStats.Inc(kStatNFuncCreset);
415 20 wfjm
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_CRESET);
416
 
417 29 wfjm
  } else if (fu == kFUNC_WRITE) {           // Write -------------------------
418 20 wfjm
                                            //   Note: WRITE+FMT is just WRITE
419 25 wfjm
    fStats.Inc(kStatNFuncWrite);
420 20 wfjm
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
421
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
422
    if (unit.WProt())           rker |= kRKER_M_WLO;
423 28 wfjm
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
424
    if (rker) {
425
      AddErrorExit(clist, rker);
426
    } else {
427
      fRdma.QueueDiskWrite(addr, nwrd,
428
                           Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
429
                           lba, &unit);
430
    }
431 20 wfjm
 
432 29 wfjm
  } else if (fu == kFUNC_READ) {            // Read --------------------------
433 25 wfjm
    fStats.Inc(kStatNFuncRead);
434 20 wfjm
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
435
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
436 28 wfjm
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
437
    if (rker) {
438
      AddErrorExit(clist, rker);
439
    } else {
440
      fRdma.QueueDiskRead(addr, nwrd,
441
                          Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
442
                          lba, &unit);
443
    }
444
 
445 29 wfjm
  } else if (fu == kFUNC_WCHK) {            // Write Check -------------------
446 25 wfjm
    fStats.Inc(kStatNFuncWchk);
447 20 wfjm
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
448
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
449 28 wfjm
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
450
    if (rker) {
451
      AddErrorExit(clist, rker);
452
    } else {
453
      fRdma.QueueDiskWriteCheck(addr, nwrd,
454
                                Rw11Cpu::kCp_ah_m_22bit|Rw11Cpu::kCp_ah_m_ubmap,
455
                                lba, &unit);
456
    }
457 20 wfjm
 
458 29 wfjm
  } else if (fu == kFUNC_SEEK) {            // Seek --------------------------
459 25 wfjm
    fStats.Inc(kStatNFuncSeek);
460 20 wfjm
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
461
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
462
    if (rker) {
463
      cpu.AddWibr(clist, fBase+kRKER, rker);
464
      cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_SBCLR | (1u<<dr));
465
      cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
466
      LogRker(rker);
467
    } else {
468
      cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
469
      rkds &= ~kRKDS_B_SC;                  // replace current sector number
470
      rkds |= se;
471
      unit.SetRkds(rkds);
472
      cpu.AddWibr(clist, fBase+kRKDS, rkds);
473
      cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr); // issue seek done
474
    }
475
 
476 29 wfjm
  } else if (fu == kFUNC_RCHK) {            // Read Check --------------------
477 25 wfjm
    fStats.Inc(kStatNFuncRchk);
478 20 wfjm
    if (se >= unit.NSector())   rker |= kRKER_M_NXS;
479
    if (cy >= unit.NCylinder()) rker |= kRKER_M_NXC;
480 28 wfjm
    if (rkcs & kRKCS_M_IBA) rker |= kRKER_M_DRE;  // IBA not supported
481
    if (rker) {
482
      AddErrorExit(clist, rker);
483
    } else {
484
      AddNormalExit(clist, nwrd, 0);        // no action, virt disks don't err
485
    }
486
 
487 29 wfjm
  } else if (fu == kFUNC_DRESET) {          // Drive Reset -------------------
488 25 wfjm
    fStats.Inc(kStatNFuncDreset);
489 20 wfjm
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
490
    cpu.AddWibr(clist, fBase+kRKMR, 1u<<dr);   // issue seek done
491
 
492 29 wfjm
  } else if (fu == kFUNC_WLOCK) {           // Write Lock --------------------
493 25 wfjm
    fStats.Inc(kStatNFuncWlock);
494 20 wfjm
    rkds |= kRKDS_M_WPS;                    // set RKDS write protect flag
495
    unit.SetRkds(rkds);
496
    unit.SetWProt(true);
497
    cpu.AddWibr(clist, fBase+kRKDS, rkds);
498
    cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
499
  }
500
 
501 28 wfjm
  if (clist.Size()) {                       // if handled directly
502
    Server().Exec(clist);                   // doit
503 20 wfjm
  }
504
  return 0;
505
}
506
 
507
//------------------------------------------+-----------------------------------
508
//! FIXME_docs
509
 
510 29 wfjm
void Rw11CntlRK11::RdmaPreExecCB(int stat, size_t nwdone, size_t nwnext,
511 28 wfjm
                                 RlinkCommandList& clist)
512 20 wfjm
{
513 28 wfjm
  // if last chunk and not doing WCHK add a labo and normal exit csr update
514 29 wfjm
  if (stat == Rw11Rdma::kStatusBusyLast && fRd_fu != kFUNC_WCHK) {
515 28 wfjm
    clist.AddLabo();
516 29 wfjm
    AddNormalExit(clist, nwdone+nwnext, 0);
517 28 wfjm
  }
518
  return;
519
}
520 20 wfjm
 
521 28 wfjm
//------------------------------------------+-----------------------------------
522
//! FIXME_docs
523 20 wfjm
 
524 28 wfjm
void Rw11CntlRK11::RdmaPostExecCB(int stat, size_t ndone,
525
                                  RlinkCommandList& clist, size_t ncmd)
526
{
527
  if (stat == Rw11Rdma::kStatusBusy) return;
528 20 wfjm
 
529 28 wfjm
  uint16_t rker = 0;
530
 
531
  // handle write check
532 29 wfjm
  if (fRd_fu == kFUNC_WCHK) {
533 28 wfjm
    size_t nwcok = fRdma.WriteCheck(ndone);
534
    if (nwcok != ndone) {                   // if mismatch found
535
      rker |= kRKER_M_WCE;                  // set error flag
536
      if (fRd_rkcs & kRKCS_M_SSE) {         // if 'stop-on-soft' requested
537
        ndone = nwcok;                      // truncate word count
538 20 wfjm
      }
539
    }
540 28 wfjm
  }
541
 
542
  // handle Rdma aborts
543
  if (stat == Rw11Rdma::kStatusFailRdma) rker |= kRKER_M_NXM;
544 20 wfjm
 
545 28 wfjm
  // check for fused csr updates
546
  if (clist.Size() > ncmd) {
547
    uint8_t  ccode = clist[ncmd].Command();
548
    uint16_t cdata = clist[ncmd].Data();
549
    if (ccode != RlinkCommand::kCmdLabo || (rker != 0 && cdata == 0))
550
      throw Rexception("Rw11CntlRK11::RdmaPostExecCB",
551
                       "Bad state: Labo not found or missed abort");
552
    if (cdata == 0) return;
553 20 wfjm
  }
554
 
555 28 wfjm
  // finally to RK11 register update
556
  RlinkCommandList clist1;
557
  AddNormalExit(clist1, ndone, rker);
558
  Server().Exec(clist1);
559 20 wfjm
 
560 28 wfjm
  return;
561
}
562
 
563
//------------------------------------------+-----------------------------------
564
//! FIXME_docs
565
 
566
void Rw11CntlRK11::LogRker(uint16_t rker)
567
{
568
  RlogMsg lmsg(LogFile());
569
  lmsg << "-E RK11 er=" << RosPrintBvi(rker,8) << "  ERROR ABORT";
570
}
571
 
572
//------------------------------------------+-----------------------------------
573
//! FIXME_docs
574
 
575
void Rw11CntlRK11::AddErrorExit(RlinkCommandList& clist, uint16_t rker)
576
{
577
  Rw11Cpu& cpu = Cpu();
578
  cpu.AddWibr(clist, fBase+kRKER, rker);
579
  cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
580
  LogRker(rker);
581
  return;
582
}
583
 
584
//------------------------------------------+-----------------------------------
585
//! FIXME_docs
586
 
587
void Rw11CntlRK11::AddNormalExit(RlinkCommandList& clist, size_t ndone,
588
                                 uint16_t rker)
589
{
590
  Rw11Cpu& cpu  = Cpu();
591
  uint16_t dr   = (fRd_rkda>>kRKDA_V_DRSEL) & kRKDA_B_DRSEL;
592
  Rw11UnitRK11& unit = *fspUnit[dr];
593
 
594 29 wfjm
  size_t nblk   = unit.Nwrd2Nblk(ndone);
595 28 wfjm
 
596
  uint32_t addr = fRd_addr + 2*ndone;
597
  size_t   lba  = fRd_lba  + nblk;
598
  uint32_t nrest = fRd_nwrd - ndone;
599
 
600
  uint16_t ba   = addr & 0177776;           // get lower 16 bits
601
  uint16_t mex  = (addr>>16) & 03;          // get upper  2 bits
602 20 wfjm
  uint16_t cs   = (fRd_rkcs & ~kRKCS_M_MEX) | (mex << kRKCS_V_MEX);
603
  uint16_t se;
604
  uint16_t hd;
605
  uint16_t cy;
606 28 wfjm
  unit.Lba2Chs(lba, cy,hd,se);
607 20 wfjm
  uint16_t da   = (fRd_rkda & kRKDA_M_DRSEL) | (cy<<kRKDA_V_CYL) |
608
                  (hd<<kRKDA_V_SUR) | se;
609
 
610 28 wfjm
  if (fRd_ovr) rker |= kRKER_M_OVR;
611
 
612 20 wfjm
  if (rker) {
613
    cpu.AddWibr(clist, fBase+kRKER, rker);
614
    LogRker(rker);
615
  }
616 28 wfjm
  cpu.AddWibr(clist, fBase+kRKWC, uint16_t((-nrest)&0177777));
617 20 wfjm
  cpu.AddWibr(clist, fBase+kRKBA, ba);
618
  cpu.AddWibr(clist, fBase+kRKDA, da);
619
  if (cs != fRd_rkcs)
620
    cpu.AddWibr(clist, fBase+kRKCS, cs);
621
  cpu.AddWibr(clist, fBase+kRKMR, kRKMR_M_FDONE);
622
 
623 28 wfjm
  return;
624 20 wfjm
}
625
 
626
 
627
} // end namespace Retro

powered by: WebSVN 2.1.0

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