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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.7/] [rtl/] [ibus/] [ibdr_rhrp.vhd] - Blame information for rev 36

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

Line No. Rev Author Line
1 32 wfjm
-- $Id: ibdr_rhrp.vhd 692 2015-06-21 11:53:24Z mueller $
2 30 wfjm
--
3
-- Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
--
14
------------------------------------------------------------------------------
15
-- Module Name:    ibdr_rhrp - syn
16
-- Description:    ibus dev(rem): RHRP
17
--
18
-- Dependencies:   ram_1swar_gen
19
-- Test bench:     -
20
-- Target Devices: generic
21
-- Tool versions:  ise 14.7; viv 2014.4; ghdl 0.31
22
--
23
-- Synthesized (xst):
24
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
25 32 wfjm
-- 2015-06-20   692 14.7  131013 xc6slx16-2   212  406    8  142 s  8.7
26 30 wfjm
-- 2015-05-14   680 14.7  131013 xc6slx16-2   211  408    8  131 s  8.8
27
-- 2015-04-06   664 14.7  131013 xc6slx16-2   177  331    8  112 s  8.7
28
--
29
-- Revision History: 
30
-- Date         Rev Version  Comment
31 32 wfjm
-- 2015-06-20   692   1.0.3  BUGFIX: fix func-go when drive/init busy checks
32
-- 2015-06-05   690   1.0.2  use 'not unit' for lsb of rpsn to avoid SI detect
33
--                           BUGFIX: set rmr only for write to busy unit
34 31 wfjm
-- 2015-05-15   682   1.0.1  correct ibsel range select logic
35 30 wfjm
-- 2015-05-14   680   1.0    Initial version
36
-- 2015-03-15   658   0.1    First draft
37
------------------------------------------------------------------------------
38
 
39
library ieee;
40
use ieee.std_logic_1164.all;
41
use ieee.numeric_std.all;
42
 
43
use work.slvtypes.all;
44
use work.memlib.all;
45
use work.iblib.all;
46
 
47
-- ----------------------------------------------------------------------------
48
entity ibdr_rhrp is                     -- ibus dev(rem): RH+RP
49
                                        -- fixed address: 176700
50
  port (
51
    CLK : in slbit;                     -- clock
52
    CE_USEC : in slbit;                 -- usec pulse
53
    BRESET : in slbit;                  -- ibus reset
54
    ITIMER : in slbit;                  -- instruction timer
55
    RB_LAM : out slbit;                 -- remote attention
56
    IB_MREQ : in ib_mreq_type;          -- ibus request
57
    IB_SRES : out ib_sres_type;         -- ibus response
58
    EI_REQ : out slbit;                 -- interrupt request
59
    EI_ACK : in slbit                   -- interrupt acknowledge
60
  );
61
 
62
  -- by default xst uses a binary encoding for the main fsm.
63
  -- that give quite sub-optimal results, so force one-hot
64
  attribute fsm_encoding : string;
65
  attribute fsm_encoding of ibdr_rhrp : entity is "one-hot";
66
 
67
end entity ibdr_rhrp;
68
 
69
architecture syn of ibdr_rhrp is
70
 
71
  constant ibaddr_rhrp : slv16 := slv(to_unsigned(8#176700#,16));
72
 
73
                                          --  nam  rw mb  rp     rm     storage
74
  constant ibaddr_cs1 : slv5 := "00000";  --  cs1  rw  0  rpcs1  rmcs1  m d,6+r
75
  constant ibaddr_wc  : slv5 := "00001";  --   wc  rw  -  rpwc   rmwc   m 0,7
76
  constant ibaddr_ba  : slv5 := "00010";  --   ba  rw  -  rpba   rmba   m 1,7
77
  constant ibaddr_da  : slv5 := "00011";  --   da  rw  5  rpda   rmda   m d,0
78
  constant ibaddr_cs2 : slv5 := "00100";  --  cs2  rw  -  rpcs2  rmcs2  r cs2*
79
  constant ibaddr_ds  : slv5 := "00101";  --   ds  r-  1  rpds   rmds   r ds*
80
  constant ibaddr_er1 : slv5 := "00110";  --  er1  rw  2  rper1  rmer1  r er1*
81
  constant ibaddr_as  : slv5 := "00111";  --   as  rw  4  rpas   rmas   r as*
82
  constant ibaddr_la  : slv5 := "01000";  --   la  r-  7  rpla   rmla   r sc
83
  constant ibaddr_db  : slv5 := "01001";  --   db  r?  -  rpdb   rmdb   m 2,7
84
  constant ibaddr_mr1 : slv5 := "01010";  --  mr1  rw  3  rpmr1  rmmr1  m d,3
85
  constant ibaddr_dt  : slv5 := "01011";  --   dt  r-  6  rpdt   rmdt   r dt*+map
86
  constant ibaddr_sn  : slv5 := "01100";  --   sn  r- 10  rpsn   rmsn   <map>
87
  constant ibaddr_of  : slv5 := "01101";  --   of  rw 11  rpof   rmof   m d,1
88
  constant ibaddr_dc  : slv5 := "01110";  --   dc  rw 12  rpdc   rmdc   m d,2
89
  constant ibaddr_m13 : slv5 := "01111";  --  m13  rw 13  rpcc          m =dc!
90
                                          --       rw 13         rmhr   m d,4
91
  constant ibaddr_m14 : slv5 := "10000";  --  m14  rw 14  rper2         =0
92
                                          --       rw 14         rmmr2  m d,5
93
  constant ibaddr_m15 : slv5 := "10001";  --  m15  rw 15  rper3         =0
94
                                          --       rw 15         rmer2  =0
95
  constant ibaddr_ec1 : slv5 := "10010";  --  ec1  r- 16  rpec1  rmec1  =0
96
  constant ibaddr_ec2 : slv5 := "10011";  --  ec1  r- 17  rpec2  rmec2  =0
97
  constant ibaddr_bae : slv5 := "10100";  --  bae  rw  -  rpbae  rmbae  r bae
98
  constant ibaddr_cs3 : slv5 := "10101";  --  cs3  rw  -  rpcs3  rmcs3  r cs3*
99
 
100
  constant omux_cs1  : slv4 := "0000";
101
  constant omux_cs2  : slv4 := "0001";
102
  constant omux_ds   : slv4 := "0010";
103
  constant omux_er1  : slv4 := "0011";
104
  constant omux_as   : slv4 := "0100";
105
  constant omux_la   : slv4 := "0101";
106
  constant omux_dt   : slv4 := "0110";
107
  constant omux_sn   : slv4 := "0111";
108
  constant omux_bae  : slv4 := "1000";
109
  constant omux_cs3  : slv4 := "1001";
110
  constant omux_mem  : slv4 := "1010";
111
  constant omux_zero : slv4 := "1111";
112
 
113
  constant amapc_da  : slv3 := "000";
114
  constant amapc_mr1 : slv3 := "011";
115
  constant amapc_of  : slv3 := "001";
116
  constant amapc_dc  : slv3 := "010";
117
  constant amapc_hr  : slv3 := "100";
118
  constant amapc_mr2 : slv3 := "101";
119
  constant amapc_cs1 : slv3 := "110";
120
  constant amapc_ext : slv3 := "111";
121
 
122
  constant amapr_wc  : slv2 := "00";
123
  constant amapr_ba  : slv2 := "01";
124
  constant amapr_db  : slv2 := "10";
125
 
126
  subtype  amap_f_unit     is integer range  4 downto  3;  -- unit part
127
  subtype  amap_f_reg      is integer range  2 downto  0;  -- reg  part
128
 
129
  constant clrmode_breset : slv2 := "00";
130
  constant clrmode_cs2clr : slv2 := "01";
131
  constant clrmode_fdclr  : slv2 := "10";
132
  constant clrmode_fpres  : slv2 := "11";
133
 
134
  constant cs1_ibf_sc    : integer := 15;     -- special condition
135
  constant cs1_ibf_tre   : integer := 14;     -- transfer error
136
  constant cs1_ibf_dva   : integer := 11;     -- drive available
137
  subtype  cs1_ibf_bae     is integer range  9 downto  8;  -- bus addr ext (1:0)
138
  constant cs1_ibf_rdy   : integer :=  7;     -- controller ready
139
  constant cs1_ibf_ie    : integer :=  6;     -- interrupt enable
140
  subtype  cs1_ibf_func    is integer range  5 downto  1;  -- function code
141
  constant cs1_ibf_go    : integer :=  0;     -- interrupt enable
142
 
143
  constant func_noop  : slv5 := "00000";   -- func: noop
144
  constant func_unl   : slv5 := "00001";   -- func: unload
145
  constant func_seek  : slv5 := "00010";   -- func: seek
146
  constant func_recal : slv5 := "00011";   -- func: recalibrate
147
  constant func_dclr  : slv5 := "00100";   -- func: drive clear
148
  constant func_pore  : slv5 := "00101";   -- func: port release
149
  constant func_offs  : slv5 := "00110";   -- func: offset
150
  constant func_retc  : slv5 := "00111";   -- func: return to center
151
  constant func_pres  : slv5 := "01000";   -- func: readin preset
152
  constant func_pack  : slv5 := "01001";   -- func: pack acknowledge
153
  constant func_sear  : slv5 := "01100";   -- func: search
154 32 wfjm
  constant func_xfer  : slv5 := "10100";   -- used to check for xfer type funcs
155 30 wfjm
  constant func_wcd   : slv5 := "10100";   -- func: write check data
156
  constant func_wchd  : slv5 := "10101";   -- func: write check header&data
157
  constant func_write : slv5 := "11000";   -- func: write 
158
  constant func_whd   : slv5 := "11001";   -- func: write header&data
159
  constant func_read  : slv5 := "11100";   -- func: read  
160
  constant func_rhd   : slv5 := "11101";   -- func: read header&data
161
 
162
  constant rfunc_wunit : slv5 := "00001";   -- rem func: write runit
163
  constant rfunc_cunit : slv5 := "00010";   -- rem func: copy funit->runit
164
  constant rfunc_done  : slv5 := "00011";   -- rem func: done (set rdy)
165
  constant rfunc_widly : slv5 := "00100";   -- rem func: write idly
166
 
167
  -- cs1 usage for rem functions
168
  subtype  cs1_ibf_runit   is integer range  9 downto  8;  -- new runit (_wunit)
169
  constant cs1_ibf_rata  : integer := 8;                   -- use ata   (_done)
170
  subtype  cs1_ibf_ridly   is integer range 15 downto  8;  -- new idly  (_widly)
171
 
172
  subtype  da_ibf_ta       is integer range 12 downto  8;  -- track  addr
173
  subtype  da_ibf_sa       is integer range  5 downto  0;  -- sector addr
174
 
175
  constant cs2_ibf_rwco  : integer := 15;     -- rem: write check odd word
176
  constant cs2_ibf_wce   : integer := 14;     -- write check error
177 32 wfjm
  constant cs2_ibf_ned   : integer := 12;     -- non-existent drive
178
  constant cs2_ibf_nem   : integer := 11;     -- non-existent memory
179 30 wfjm
  constant cs2_ibf_pge   : integer := 10;     -- programming error
180
  constant cs2_ibf_mxf   : integer :=  9;     -- missed transfer
181
  constant cs2_ibf_or    : integer :=  7;     -- output ready
182
  constant cs2_ibf_ir    : integer :=  6;     -- input ready
183
  constant cs2_ibf_clr   : integer :=  5;     -- clear controller
184
  constant cs2_ibf_pat   : integer :=  4;     -- parity test
185
  constant cs2_ibf_bai   : integer :=  3;     -- bus address inhibit
186
  constant cs2_ibf_unit2 : integer :=  2;     -- unit select msb
187
  subtype  cs2_ibf_unit    is integer range  1 downto  0;  -- unit select
188
 
189
  constant ds_ibf_ata    : integer := 15;     -- attention
190
  constant ds_ibf_erp    : integer := 14;     -- any errors in er1 or er2
191
  constant ds_ibf_pip    : integer := 13;     -- positioning in progress
192
  constant ds_ibf_mol    : integer := 12;     -- medium online (ATTACHED)
193
  constant ds_ibf_wrl    : integer := 11;     -- write locked
194
  constant ds_ibf_lbt    : integer := 10;     -- last block transfered
195
  constant ds_ibf_dpr    : integer :=  8;     -- drive present (ENABLED)
196
  constant ds_ibf_dry    : integer :=  7;     -- drive ready
197
  constant ds_ibf_vv     : integer :=  6;     -- volume valid
198
  constant ds_ibf_om     : integer :=  0;     -- offset mode
199
 
200
  constant er1_ibf_uns   : integer := 14;     -- drive unsafe
201
  constant er1_ibf_wle   : integer := 11;     -- write lock error
202
  constant er1_ibf_iae   : integer := 10;     -- invalid address error
203
  constant er1_ibf_aoe   : integer :=  9;     -- address overflow error
204
  constant er1_ibf_rmr   : integer :=  2;     -- register modification refused
205
  constant er1_ibf_ilf   : integer :=  0;     -- illegal function
206
 
207
  subtype  la_ibf_sc       is integer range 11 downto  6;  -- current sector
208
 
209
  constant dt_ibf_rm     : integer :=  2;     -- rm cntl
210
  constant dt_ibf_e1     : integer :=  1;     -- encoded type bit 1
211
  constant dt_ibf_e0     : integer :=  0;     -- encoded type bit 0
212
 
213
  constant dte_rp04      : slv3 :=  "000";    -- encoded dt for rp04 rm=0
214
  constant dte_rp06      : slv3 :=  "001";    -- encoded dt for rp06 rm=0
215
  constant dte_rm03      : slv3 :=  "100";    -- encoded dt for rm03 rm=1
216
  constant dte_rm80      : slv3 :=  "101";    -- encoded dt for rm80 rm=1
217
  constant dte_rm05      : slv3 :=  "110";    -- encoded dt for rm05 rm=1
218
  constant dte_rp07      : slv3 :=  "111";    -- encoded dt for rp07 rm=1
219
 
220
  subtype  dc_ibf_ca       is integer range  9 downto  0;  -- cyclinder addr
221
 
222
  subtype  bae_ibf_bae     is integer range  5 downto  0;  -- bus addr ext.
223
 
224
  constant cs3_ibf_wco       : integer := 12;     -- write check odd
225
  constant cs3_ibf_wce       : integer := 11;     -- write check even
226
  constant cs3_ibf_ie        : integer :=  6;     -- interrupt enable
227
  constant cs3_ibf_rseardone : integer :=  3;     -- rem: sear done flag
228
  constant cs3_ibf_rpackdone : integer :=  2;     -- rem: pack done flag
229
  constant cs3_ibf_rporedone : integer :=  1;     -- rem: pore done flag
230
  constant cs3_ibf_rseekdone : integer :=  0;     -- rem: seek done flag
231
 
232
  -- RP controller type disks
233
  constant rp04_dtyp   : slv6  := slv(to_unsigned(  8#20#,  6));
234
  constant rp04_camax  : slv10 := slv(to_unsigned(  411-1, 10));
235
  constant rp04_tamax  : slv5  := slv(to_unsigned(   19-1,  5));
236
  constant rp04_samax  : slv6  := slv(to_unsigned(   22-1,  6));
237
 
238
  constant rp06_dtyp   : slv6  := slv(to_unsigned(  8#22#,  6));
239
  constant rp06_camax  : slv10 := slv(to_unsigned(  815-1, 10));
240
  constant rp06_tamax  : slv5  := slv(to_unsigned(   19-1,  5));
241
  constant rp06_samax  : slv6  := slv(to_unsigned(   22-1,  6));
242
 
243
  -- RM controller type disks (Note: rp07 has a RM stype controller!)
244
  constant rm03_dtyp   : slv6  := slv(to_unsigned(  8#24#,  6));
245
  constant rm03_camax  : slv10 := slv(to_unsigned(  823-1, 10));
246
  constant rm03_tamax  : slv5  := slv(to_unsigned(    5-1,  5));
247
  constant rm03_samax  : slv6  := slv(to_unsigned(   32-1,  6));
248
 
249
  constant rm80_dtyp   : slv6  := slv(to_unsigned(  8#26#,  6));
250
  constant rm80_camax  : slv10 := slv(to_unsigned(  559-1, 10));
251
  constant rm80_tamax  : slv5  := slv(to_unsigned(   14-1,  5));
252
  constant rm80_samax  : slv6  := slv(to_unsigned(   31-1,  6));
253
 
254
  constant rm05_dtyp   : slv6  := slv(to_unsigned(  8#27#,  6));
255
  constant rm05_camax  : slv10 := slv(to_unsigned(  823-1, 10));
256
  constant rm05_tamax  : slv5  := slv(to_unsigned(   19-1,  5));
257
  constant rm05_samax  : slv6  := slv(to_unsigned(   32-1,  6));
258
 
259
  constant rp07_dtyp   : slv6  := slv(to_unsigned(  8#42#,  6));
260
  constant rp07_camax  : slv10 := slv(to_unsigned(  630-1, 10));
261
  constant rp07_tamax  : slv5  := slv(to_unsigned(   32-1,  5));
262
  constant rp07_samax  : slv6  := slv(to_unsigned(   50-1,  6));
263
 
264
  type state_type is (
265
    s_idle,                             -- idle: handle ibus
266
    s_wcs1,                             -- wcs1: write cs1
267
    s_wcs2,                             -- wcs2: write cs2
268
    s_wcs3,                             -- wcs3: write cs3
269
    s_wer1,                             -- wer1: write er1 (rem only)
270
    s_was,                              -- was:  write as
271
    s_wdt,                              -- wdt:  write dt  (rem only)
272
    s_wds,                              -- wdt:  write ds  (rem only)
273
    s_wbae,                             -- wbae: write bae
274
    s_wmem,                             -- wmem: write mem (DA,MR1,OF,DC,MR2)
275
    s_wmembe,                           -- wmem: write mem with be (WC,BA,DB)
276
    s_whr,                              -- whr:  write hr (holding reg only)
277 32 wfjm
    s_funcchk,                          -- funcchk: check function go
278 30 wfjm
    s_funcgo,                           -- funcgo: handle function go
279
    s_chkdc,                            -- chkdc: handle dc check
280
    s_chkda,                            -- chksa: handle da check
281
    s_chkdo,                            -- chkdo: execute function
282
    s_read,                             -- read: all register reads
283
    s_setrmr,                           -- set rmr flag
284
    s_oot_clr0,                         -- OOT clr0: state 0
285
    s_oot_clr1,                         -- OOT clr1: state 1
286
    s_oot_clr2                          -- OOT clr2: state 2
287
  );
288
 
289
  type regs_type is record              -- state registers
290
    ibsel   : slbit;                    -- ibus select
291
    state   : state_type;               -- state
292
    amap    : slv5;                     -- mem mapped address
293
    omux    : slv4;                     -- omux select
294
    dinmsk  : slv16;                    -- mbreq.din masked
295
    dtrm    : slv4;                     -- dt: drive rm controller
296
    dte1    : slv4;                     -- dt: drive type bit 1
297
    dte0    : slv4;                     -- dt: drive type bit 0
298
    bae     : slv6;                     -- bae: bus addr extension (in cs1&bae)
299
    cs1sc   : slbit;                    -- cs1: special condition
300
    cs1tre  : slbit;                    -- cs1: transfer error
301
    cs1rdy  : slbit;                    -- cs1: controller ready
302
    cs1ie   : slbit;                    -- cs1: interrupt enable
303
    ffunc   : slv5;                     -- func code (frozen on ext func go)
304
    fxfer   : slbit;                    -- func is xfer
305
    cs2wce  : slbit;                    -- cs2: write check error
306 32 wfjm
    cs2ned  : slbit;                    -- cs2: non-existent drive
307
    cs2nem  : slbit;                    -- cs2: non-existent memory
308 30 wfjm
    cs2pge  : slbit;                    -- cs2: programming error
309
    cs2mxf  : slbit;                    -- cs2: missed transfer
310
    cs2pat  : slbit;                    -- cs2: parity test
311
    cs2bai  : slbit;                    -- cs2: bus address inhibit
312
    cs2unit2: slbit;                    -- cs2: unit lsb
313
    cs2unit : slv2;                     -- unit (ibus view)
314
    funit   : slv2;                     -- unit (frozen on ext func go)
315
    runit   : slv2;                     -- unit (remote view)
316
    eunit   : slv2;                     -- unit (effective)
317
    dsata   : slv4;                     -- ds: attention
318
    dserp   : slv4;                     -- ds: error summary (or of er1+er2)
319
    dspip   : slv4;                     -- ds: positioning in progress
320
    dsmol   : slv4;                     -- ds: medium online (ATTACHED)
321
    dswrl   : slv4;                     -- ds: write locked
322
    dslbt   : slv4;                     -- ds: last block transfered
323
    dsdpr   : slv4;                     -- ds: drive present (ENABLED)
324
    dsvv    : slv4;                     -- ds: volume valid
325
    dsom    : slv4;                     -- ds: offset mode
326
    er1uns  : slv4;                     -- er1: dive unsafe
327
    er1wle  : slv4;                     -- er1: write lock error
328
    er1iae  : slv4;                     -- er1: invalid address error
329
    er1aoe  : slv4;                     -- er1: address overflow error
330
    er1rmr  : slv4;                     -- er1: register modificaton refused
331
    er1ilf  : slv4;                     -- er1: illegal function
332
    cs3wco  : slbit;                    -- cs3: write check  odd word
333
    idlyval : slv8;                     -- int delay value
334
    idlycnt : slv8;                     -- int delay counter
335
    seekdone: slbit;                    -- cs3 rem: seek     done
336
    poredone: slbit;                    -- cs3 rem: port rel done
337
    packdone: slbit;                    -- cs3 rem: pack ack done
338
    seardone: slbit;                    -- cs3 rem: search   done
339 32 wfjm
    ned     : slbit;                    -- current drive non-existent
340 30 wfjm
    cerm    : slbit;                    -- current eff. drive rm controller
341
    dtyp    : slv6;                     -- current drive type (5:0)
342
    camax   : slv10;                    -- current max cylinder address
343
    tamax   : slv5;                     -- current max track  address
344
    samax   : slv6;                     -- current max sector address
345
    uscnt   : slv7;                     -- usec counter
346
    sc      : slv6;                     -- current sector counter
347
    clrmode : slv2;                     -- clear: mode
348
    clrreg  : slv3;                     -- clear: register counter
349
    ireq    : slbit;                    -- interrupt request flag
350
  end record regs_type;
351
 
352
  constant regs_init : regs_type := (
353
    '0',                                -- ibsel
354
    s_idle,                             -- state
355
    (others=>'0'),                      -- amap,
356
    (others=>'0'),                      -- omux,
357
    (others=>'0'),                      -- dinmsk,
358
    (others=>'0'),                      -- dtrm
359
    (others=>'0'),                      -- dte1
360
    (others=>'0'),                      -- dte0
361
    (others=>'0'),                      -- bae,
362
    '0','0','1','0',                    -- cs1sc,cs1tre,cs1rdy,cs1ie
363
    (others=>'0'),                      -- ffunc
364
    '0',                                -- fxfer
365
    '0','0','0','0',                    -- cs2wce,cs2ned,cs2nem,cs2pge
366
    '0','0','0',                        -- cs2mxf,cs2pat,cs2bai
367
    '0',                                -- cs2unit2
368
    (others=>'0'),                      -- cs2unit
369
    (others=>'0'),                      -- funit
370
    (others=>'0'),                      -- runit
371
    (others=>'0'),                      -- eunit
372
    (others=>'0'),                      -- dsata
373
    (others=>'0'),                      -- dserp
374
    (others=>'0'),                      -- dspip
375
    (others=>'0'),                      -- dsmol
376
    (others=>'0'),                      -- dswrl
377
    (others=>'0'),                      -- dslbt
378
    (others=>'0'),                      -- dsdpr
379
    (others=>'0'),                      -- dsvv
380
    (others=>'0'),                      -- dsom
381
    (others=>'0'),                      -- er1uns
382
    (others=>'0'),                      -- er1wle
383
    (others=>'0'),                      -- er1iae
384
    (others=>'0'),                      -- er1aoe
385
    (others=>'0'),                      -- er1rmr
386
    (others=>'0'),                      -- er1ilf
387
    '0',                                -- cs3wco
388
    x"0a",                              -- idlyval  (default delay=10)
389
    (others=>'0'),                      -- idlycnt
390
    '0','0','0','0',                    -- seekdone,poredone,packdone,seardone
391
    '0','0',                            -- ned,cerm
392
    (others=>'0'),                      -- dtyp
393
    (others=>'0'),                      -- camax
394
    (others=>'0'),                      -- tamax
395
    (others=>'0'),                      -- samax
396
    (others=>'0'),                      -- uscnt
397
    (others=>'0'),                      -- sc
398
    (others=>'0'),                      -- clrmode
399
    (others=>'0'),                      -- clrreg
400
    '0'                                 -- ireq
401
  );
402
 
403
  signal R_REGS : regs_type := regs_init;
404
  signal N_REGS : regs_type := regs_init;
405
 
406
  signal MEM_1_WE : slbit := '0';
407
  signal MEM_0_WE : slbit := '0';
408
  signal MEM_ADDR : slv5  := (others=>'0');
409
  signal MEM_DIN  : slv16 := (others=>'0');
410
  signal MEM_DOUT : slv16 := (others=>'0');
411
 
412
  -- the following is unfortunately not accepted by xst:
413
  -- attribute fsm_encoding : string;
414
  -- attribute fsm_encoding of R_REGS.state : signal is "one-hot";
415
 
416
begin
417
 
418
  MEM_1 : ram_1swar_gen
419
    generic map (
420
      AWIDTH =>  5,
421
      DWIDTH =>  8)
422
    port map (
423
      CLK  => CLK,
424
      WE   => MEM_1_WE,
425
      ADDR => MEM_ADDR,
426
      DI   => MEM_DIN(ibf_byte1),
427
      DO   => MEM_DOUT(ibf_byte1));
428
 
429
  MEM_0 : ram_1swar_gen
430
    generic map (
431
      AWIDTH =>  5,
432
      DWIDTH =>  8)
433
    port map (
434
      CLK  => CLK,
435
      WE   => MEM_0_WE,
436
      ADDR => MEM_ADDR,
437
      DI   => MEM_DIN(ibf_byte0),
438
      DO   => MEM_DOUT(ibf_byte0));
439
 
440
  proc_regs: process (CLK)
441
  begin
442
    -- BRESET handled in main fsm, not here !!
443
    if rising_edge(CLK) then
444
      R_REGS <= N_REGS;
445
    end if;
446
  end process proc_regs;
447
 
448
  proc_next : process (R_REGS, CE_USEC, BRESET, ITIMER, IB_MREQ, MEM_DOUT,
449
                       EI_ACK)
450
    variable r : regs_type := regs_init;
451
    variable n : regs_type := regs_init;
452
    variable ibhold : slbit := '0';
453
    variable idout  : slv16 := (others=>'0');
454
    variable ibrem  : slbit := '0';
455
    variable ibreq  : slbit := '0';
456
    variable ibrd   : slbit := '0';
457
    variable ibw0   : slbit := '0';
458
    variable ibw1   : slbit := '0';
459
    variable ibwrem : slbit := '0';
460
    variable ilam   : slbit := '0';
461
    variable iei_req : slbit := '0';
462
 
463
    variable imem_we0 : slbit := '0';
464
    variable imem_we1 : slbit := '0';
465
    variable imem_addr : slv5 := (others=>'0');
466
    variable imem_din : slv16 := (others=>'0');
467
 
468
    variable ieunit  : slv2 := (others=>'0');
469
 
470
    variable iomux  : slv4  := (others=>'0');   -- omux select
471
    variable iamap  : slv5  := (others=>'0');   -- mem mapped address
472
    variable imask  : slv16 := (others=>'0');   -- implemented bits mask
473
    variable imbreg : slbit := '0';             -- massbus register
474
    variable inormr : slbit := '0';             -- inhibit rmr protect
475
 
476
    variable idte   : slv3  := (others=>'0');   -- encoded drive type
477
    variable idtyp  : slv6  := (others=>'0');   -- drive type (5:0)
478
    variable icamax : slv10 := (others=>'0');   -- max cylinder address
479
    variable itamax : slv5  := (others=>'0');   -- max track    address
480
    variable isamax : slv6  := (others=>'0');   -- max sector   address
481
 
482 32 wfjm
    variable ined   : slbit := '0';     -- non-existent drive
483 30 wfjm
    variable icerm  : slbit := '0';     -- effectiv drive is rm
484
 
485
    variable iclrreg : slbit := '0';    -- clr enable
486
 
487
    variable iscinc  : slbit := '0';    -- increment r.sc enable
488
 
489
  begin
490
 
491
    r := R_REGS;
492
    n := R_REGS;
493
 
494
    ibhold := '0';
495
    idout  := (others=>'0');
496
    ibrem  := IB_MREQ.racc;
497
    ibreq  := IB_MREQ.re or IB_MREQ.we;
498
    ibrd   := IB_MREQ.re;
499
    ibw0   := IB_MREQ.we and IB_MREQ.be0;
500
    ibw1   := IB_MREQ.we and IB_MREQ.be1;
501
    ibwrem := IB_MREQ.we and ibrem;
502
    ilam   := '0';
503
    iei_req  := '0';
504
 
505
    imem_we0  := '0';
506
    imem_we1  := '0';
507
    imem_addr := r.amap;                -- default address (from mapper)
508
    imem_din  := r.dinmsk;              -- default input   (from masker)
509
 
510
    ieunit := (others=>'0');
511
 
512
    iomux  := (others=>'0');
513
    iamap  := (others=>'0');
514
    imask  := (others=>'1');            -- default: all bits ok
515
    imbreg := '0';
516
    inormr := '0';
517
 
518
    idte   := (others=>'0');
519
    idtyp  := (others=>'0');
520
    icamax := (others=>'0');
521
    itamax := (others=>'0');
522
    isamax := (others=>'0');
523
 
524
    ined   := '0';
525
    icerm  := '0';
526
 
527
    iclrreg := '0';
528
 
529
    iscinc  := '0';
530
 
531
    -- ibus address decoder, accept only offsets 0 to ibaddr_cs3
532
    n.ibsel := '0';
533
    if IB_MREQ.aval = '1' and
534
       IB_MREQ.addr(12 downto 6) = ibaddr_rhrp(12 downto 6) and
535 31 wfjm
       unsigned(IB_MREQ.addr(5 downto 1)) <= unsigned(ibaddr_cs3) then
536 30 wfjm
      n.ibsel := '1';
537
    end if;
538
 
539
    -- internal state machine
540
    case r.state is
541
      when s_idle =>                    -- idle: handle ibus -----------------
542
 
543
        if r.ibsel='1' then               -- selected
544
 
545
          -- determine effective unit number
546
          if ibrem = '1' then
547
            ieunit := r.runit;
548
          else
549
            ieunit := r.cs2unit;
550
          end if;
551
          n.eunit := ieunit;
552
 
553
          -- determine drive properties (always via iunit) FIXME: correct ??
554
          idte(2) := r.dtrm(to_integer(unsigned(r.cs2unit)));
555
          idte(1) := r.dte1(to_integer(unsigned(r.cs2unit)));
556
          idte(0) := r.dte0(to_integer(unsigned(r.cs2unit)));
557
          case idte is
558
            when dte_rp04 =>            -- RP04
559
              idtyp  := rp04_dtyp;
560
              icamax := rp04_camax;
561
              itamax := rp04_tamax;
562
              isamax := rp04_samax;
563
            when dte_rp06 =>            -- RP06
564
              idtyp  := rp06_dtyp;
565
              icamax := rp06_camax;
566
              itamax := rp06_tamax;
567
              isamax := rp06_samax;
568
            when dte_rm03 =>            -- RM03
569
              idtyp  := rm03_dtyp;
570
              icamax := rm03_camax;
571
              itamax := rm03_tamax;
572
              isamax := rm03_samax;
573
            when dte_rm80 =>            -- RM80
574
              idtyp  := rm80_dtyp;
575
              icamax := rm80_camax;
576
              itamax := rm80_tamax;
577
              isamax := rm80_samax;
578
            when dte_rm05 =>            -- RM05
579
              idtyp  := rm05_dtyp;
580
              icamax := rm05_camax;
581
              itamax := rm05_tamax;
582
              isamax := rm05_samax;
583
            when dte_rp07 =>            -- RP07
584
              idtyp  := rp07_dtyp;
585
              icamax := rp07_camax;
586
              itamax := rp07_tamax;
587
              isamax := rp07_samax;
588
            when others =>
589
              idtyp  := (others=>'0');
590
              icamax := (others=>'0');
591
              itamax := (others=>'0');
592
              isamax := (others=>'0');
593
          end case; -- case idte
594
          n.dtyp  := idtyp;
595
          n.camax := icamax;
596
          n.tamax := itamax;
597
          n.samax := isamax;
598
 
599 32 wfjm
          -- consider drive non-existent if not 'DPR' or unit>=4 selected
600 30 wfjm
          if r.dsdpr(to_integer(unsigned(r.cs2unit))) = '0' or
601
             r.cs2unit2 = '1' then
602
            ined := '1';
603
          end if;
604
          n.ned := ined;
605
 
606
          icerm   := r.dtrm(to_integer(unsigned(ieunit)));
607
          n.cerm  := icerm;
608
 
609
          -- setup mapper 
610
          case IB_MREQ.addr(5 downto 1) is
611
 
612
            when ibaddr_cs1  =>             -- RxCS1 control reg 1 
613
              -- cs1 not flagged mbreg !! ned handling done explicitely
614
              iamap  := ieunit & amapc_cs1;
615
              iomux  := omux_cs1;
616
 
617
            when ibaddr_wc   =>             -- RxWC  word count 
618
              iamap  := amapr_wc & amapc_ext;
619
              iomux  := omux_mem;
620
 
621
            when ibaddr_ba   =>             -- RxBA  bus address 
622
              imask  := "1111111111111110";     -- lsb ignored
623
              iamap  := amapr_ba & amapc_ext;
624
              iomux  := omux_mem;
625
 
626
            when ibaddr_da   =>             -- RxDA  disk address 
627
              imask  := "0001111100111111";    -- 000t tttt 00ss ssss
628
              iamap  := ieunit & amapc_da;
629
              iomux  := omux_mem;
630
              imbreg := '1';                   -- mb 5
631
 
632
            when ibaddr_cs2  =>             -- RxCS2 control reg 2
633
              iomux  := omux_cs2;
634
 
635
            when ibaddr_ds   =>             -- RxDS  drive status 
636
              iomux  := omux_ds;
637
              imbreg := '1';                   -- mb 1
638
 
639
            when ibaddr_er1  =>             -- RxER1 error status 1 
640
              iomux  := omux_er1;
641
              imbreg := '1';                  -- mb 2
642
 
643
            when ibaddr_as   =>             -- RxAS  attention summary 
644
              iomux  := omux_as;
645
              imbreg := '1';                  -- mb 4
646
              inormr := '1';                  -- AS writes allowed when RDY=0
647
 
648
            when ibaddr_la   =>             -- RxLA  look ahead 
649
              iomux  := omux_la;
650
              imbreg := '1';                  -- mb 7
651
 
652
            when ibaddr_db   =>             -- RxDB  data buffer 
653
              iamap  := amapr_db & amapc_ext;
654
              iomux  := omux_mem;
655
 
656
            when ibaddr_mr1  =>             -- RxMR1 maintenance reg 1 
657
              iamap  := ieunit & amapc_mr1;
658
              iomux  := omux_mem;
659
              imbreg := '1';                  -- mb 3
660
              inormr := '1';                  -- MR1 writes allowed when RDY=0
661
 
662
            when ibaddr_dt   =>             -- RxDT  drive type 
663
              iomux  := omux_dt;
664
              imbreg := '1';                  -- mb 6
665
 
666
            when ibaddr_sn   =>             -- RxSN  serial number 
667
              iomux  := omux_sn;
668
              imbreg := '1';                  -- mb 10
669
 
670
            when ibaddr_of   =>             -- RxOF  offset reg 
671
              imask  := "0001110011111111";   -- 000f eh00 d??? ????
672
              iamap  := ieunit & amapc_of;
673
              iomux  := omux_mem;
674
              imbreg := '1';                  -- mb 11
675
 
676
            when ibaddr_dc   =>             -- RxDC  desired cylinder 
677
              imask  := "0000001111111111";   -- 0000 00cc cccc cccc
678
              iamap  := ieunit & amapc_dc;
679
              iomux  := omux_mem;
680
              imbreg := '1';                  -- mb 12
681
 
682
            when ibaddr_m13  =>
683
              if icerm = '1' then
684
                iamap := ieunit & amapc_hr;  -- RMHR  holding reg
685
              else
686
                iamap := ieunit & amapc_dc;  -- RPDC  current cylinder
687
              end if;
688
              iomux  := omux_mem;
689
              imbreg := '1';                   -- mb 13
690
 
691
            when ibaddr_m14  =>
692
              if icerm = '1' then
693
                iamap := ieunit & amapc_mr2; -- RMMR2 maintenance reg 2
694
                iomux := omux_mem;
695
              else
696
                iomux := omux_zero;            -- RPER2 error status 2
697
              end if;
698
              imbreg := '1';                  -- mb 14
699
 
700
            when ibaddr_m15  =>             -- RxER3 error status 3/2
701
              iomux  := omux_zero;
702
              imbreg := '1';                  -- mb 15
703
 
704
            when ibaddr_ec1  =>             -- RxEC1 ecc status 1 
705
              iomux  := omux_zero;
706
              imbreg := '1';                  -- mb 16
707
 
708
            when ibaddr_ec2  =>             -- RxEC2 ecc status 2 
709
              iomux  := omux_zero;
710
              imbreg := '1';                  -- mb 17
711
 
712
            when ibaddr_bae  =>             -- RxBAE bus addr extension
713
              iomux  := omux_bae;
714
 
715
            when ibaddr_cs3  =>             -- RxCS3 control reg 3 
716
              iomux  := omux_cs3;
717
 
718 31 wfjm
            when others => null;            -- doesn't happen, ibsel only for
719
                                            -- subrange up to cs3, and all
720
                                            -- 22 regs are decoded above
721 30 wfjm
 
722
          end case; -- case IB_MREQ.addr
723
          n.amap   := iamap;
724
          n.omux   := iomux;
725
          n.dinmsk := imask and IB_MREQ.din;
726
 
727
          if IB_MREQ.we = '1' then          -- write request
728
            ibhold := '1';                    -- assume follow-up state taken
729
            case IB_MREQ.addr(5 downto 1) is
730
 
731
              when ibaddr_cs1  => n.state := s_wcs1;   -- RxCS1
732
              when ibaddr_wc   => n.state := s_wmembe; -- RxWC
733
              when ibaddr_ba   => n.state := s_wmembe; -- RxBA
734
              when ibaddr_da   => n.state := s_wmem;   -- RxDA
735
              when ibaddr_cs2  => n.state := s_wcs2;   -- RxCS2
736
              when ibaddr_ds   => n.state := s_wds;    -- RxDS  (read-only)
737
              when ibaddr_er1  => n.state := s_wer1;   -- RxER1 (read-only)
738
              when ibaddr_as   => n.state := s_was;    -- RxAS
739
              when ibaddr_la   => n.state := s_whr;    -- RxLA  (read-only)
740
              when ibaddr_db   => n.state := s_wmembe; -- RxDB
741
              when ibaddr_mr1  => n.state := s_wmem;   -- RxMR1
742
              when ibaddr_dt   => n.state := s_wdt;    -- RxDT  (read-only)
743
              when ibaddr_sn   => n.state := s_whr;    -- RxSN  (read-only)
744
              when ibaddr_of   => n.state := s_wmem;   -- RxOF
745
              when ibaddr_dc   => n.state := s_wmem;   -- RxDC
746
              when ibaddr_m13  => n.state := s_whr;    -- RPCC|RMHR (fits both)
747
              when ibaddr_m14  =>
748
                if icerm = '1' then
749
                  n.state := s_wmem;                   -- RMMR2
750
                else
751
                  n.state := s_whr;                    -- RPER2
752
                end if;
753
              when ibaddr_m15  => n.state := s_whr;    -- RPER3|RMER2 (fits both)
754
              when ibaddr_ec1  => n.state := s_whr;    -- RxEC1
755
              when ibaddr_ec2  => n.state := s_whr;    -- RxEC2
756
              when ibaddr_bae  => n.state := s_wbae;   -- RxBAE
757
              when ibaddr_cs3  => n.state := s_wcs3;   -- RxCS3
758
 
759
              when others => null;           -- doesn't happen, ibsel only for
760
                                             -- subrange up to cs3, and all
761
                                             -- 22 regs are decoded above
762
 
763
            end case; -- case IB_MREQ.addr
764
 
765
            -- some general error catchers
766
            if ibrem = '0' and imbreg='1' then     -- local massbus write
767
                                                   --   for cs1: imbreg=0 !!
768 32 wfjm
              -- write to non-existent drives
769 30 wfjm
              if ined = '1' then
770
                n.cs2ned := '1';
771 32 wfjm
              -- write to a busy unit, can be a search/seek or a transfer
772
              elsif inormr='0' and                   -- rmr protected reg
773
                (r.dspip(to_integer(unsigned(r.cs2unit)))='1' or -- busy pip
774
                 (r.cs1rdy='0' and (r.funit = r.cs2unit))        -- busy xfer
775
                ) then
776 30 wfjm
                n.state := s_setrmr;
777
              end if;
778
            end if;
779
 
780
          elsif IB_MREQ.re = '1' then   -- read request
781 31 wfjm
            if ibrem='0' and imbreg='1' and ined='1' then
782
              n.cs2ned := '1';            -- signal error
783 30 wfjm
            else
784 31 wfjm
              ibhold  := '1';
785
              n.state := s_read;
786 30 wfjm
            end if;
787
 
788
          end if; --  if IB_MREQ.we .. elsif IB_MREQ.re 
789
 
790
        -- BRESET and ITIMER can be handled in the 'else' because both can
791
        -- never come during an ibus transaction. Done here to keep logic
792
        -- path in the 'if' short.
793
        else -- if r.ibsel='1'
794
          if BRESET = '1' then
795
            n.eunit   := "00";
796
            n.clrmode := clrmode_breset;
797
            n.state   := s_oot_clr0;             -- OOT state, no hold!
798
          end if;
799
 
800
          if unsigned(r.idlycnt) = 0 then     -- interrupt delay expired
801
            n.dsata := r.dsata or r.dspip;      -- convert pip's to ata's
802
            n.dspip := (others=>'0');           -- and mark them done
803
          else
804
            if ITIMER = '1' then             -- not expired and ITIMER
805
              n.idlycnt := slv(unsigned(r.idlycnt) - 1); -- count down
806
            end if;
807
          end if;
808
 
809
        end if; -- if r.ibsel='1'
810
 
811
        -- s_idle goes up to here !!
812
 
813
      when s_wcs1 =>                    -- wcs1: write cs1 -------------------
814
        n.state := s_idle;                -- in general return to s_idle
815
        imem_addr := r.amap;              -- use mapped address
816
        imem_din  := r.dinmsk;            -- use masked input
817
 
818
        if ibrem = '0' then               -- loc write access
819
 
820
          if IB_MREQ.be1 = '1' then
821
            if IB_MREQ.din(cs1_ibf_tre) = '1' then  -- TRE=1 -> clear errors
822
              n.cs2wce := '0';
823
              n.cs2ned := '0';
824
              n.cs2nem := '0';
825
              n.cs2pge := '0';
826
              n.cs2mxf := '0';
827
            end if;
828
            if r.cs1rdy = '1' then              -- only if RDY
829
              n.bae(1 downto 0) := IB_MREQ.din(cs1_ibf_bae);  -- update bae
830
            end if;
831
          end if; -- IB_MREQ.be1 = '1'
832
 
833
          if IB_MREQ.be0 = '1' then
834
            n.cs1ie   := IB_MREQ.din(cs1_ibf_ie);
835
            if IB_MREQ.din(cs1_ibf_ie) = '1' and   -- if IE and RDY both 1
836
               IB_MREQ.din(cs1_ibf_rdy) = '1'then
837
              n.ireq := '1';                         -- issue software interrupt
838
            end if;
839
 
840 32 wfjm
            if r.ned = '0' and                     -- drive on
841
               IB_MREQ.din(cs1_ibf_go) = '1' then  -- GO bit set
842
              ibhold  :=    '1';
843
              n.state := s_funcchk;
844
            end if;
845 30 wfjm
 
846 32 wfjm
            -- FIXME_code: that's likely not fully correct, cs1 func bits are
847
            --   stored before all error checks are done...
848 30 wfjm
            imem_we0 := IB_MREQ.be0;            -- remember func field per unit
849 32 wfjm
 
850 30 wfjm
            if r.ned = '1' then                 -- loc access and drive off
851
              n.cs2ned := '1';                    -- signal error
852
            end if;
853
 
854
          end if; -- IB_MREQ.be0 = '1'
855
 
856
        else                              -- rem write access. GO not checked
857
                                          --   always treated as remote function
858
          case IB_MREQ.din(cs1_ibf_func) is
859
 
860
            when rfunc_wunit =>             -- rfunc: wunit ---------------
861
              n.runit := IB_MREQ.din(cs1_ibf_runit);
862
 
863
            when rfunc_cunit =>             -- rfunc: cunit ---------------
864
              n.runit := r.funit;             -- use unit from last ext func go
865
 
866
            when rfunc_done  =>             -- rfunc: done ----------------
867
              n.cs1rdy := '1';
868
              if IB_MREQ.din(cs1_ibf_rata) = '0' then
869
                n.ireq   := r.cs1ie;          -- yes, ireq is set from ie !!
870
              else
871
                n.dsata(to_integer(unsigned(r.funit))) := '1';
872
              end if;
873
 
874
            when rfunc_widly =>             -- rfunc: widly ---------------
875
              n.idlyval := IB_MREQ.din(cs1_ibf_ridly);
876
 
877
            when others => null;
878
 
879
          end case;
880
        end if;
881
 
882
      when s_wcs2 =>                    -- wcs2: write cs2 -------------------
883
        n.state := s_idle;                -- in general return to s_idle
884
        if ibrem = '1' then                 -- rem access
885
          n.cs3wco := IB_MREQ.din(cs2_ibf_rwco);  -- cs3.wco rem set via cs2 !!
886
          n.cs2wce := IB_MREQ.din(cs2_ibf_wce);
887
          n.cs2nem := IB_MREQ.din(cs2_ibf_nem);
888
          n.cs2mxf := IB_MREQ.din(cs2_ibf_mxf);  -- FIXME: really used ???
889
        else
890
          if IB_MREQ.be0 = '1' then
891
            n.cs2pat   := IB_MREQ.din(cs2_ibf_pat);
892
            n.cs2bai   := IB_MREQ.din(cs2_ibf_bai);
893
            n.cs2unit2 := IB_MREQ.din(cs2_ibf_unit2);
894
            n.cs2unit  := IB_MREQ.din(cs2_ibf_unit);
895
            if IB_MREQ.din(cs2_ibf_clr) = '1' then
896
              n.eunit   := "00";
897
              n.clrmode := clrmode_cs2clr;
898
              n.state   := s_oot_clr0;             -- OOT state, no hold!
899
            end if;
900
          end if;
901
        end if;
902
 
903
      when s_wcs3 =>                    -- wcs3: write cs3 -------------------
904
        n.state := s_idle;                -- in general return to s_idle
905
        if ibrem = '0' then                 -- loc access
906
          if IB_MREQ.be0 = '1' then
907
            n.cs1ie  := IB_MREQ.din(cs3_ibf_ie);
908
          end if;
909
        end if;
910
 
911
      when s_wer1 =>                    -- wer1: write er1 (rem only) --------
912
        n.state := s_idle;                -- in general return to s_idle
913
        if ibrem = '1' then               -- rem access
914
          if IB_MREQ.din(er1_ibf_uns) = '1' then
915
            n.er1uns(to_integer(unsigned(r.eunit))) := '1';
916
          end if;
917
          if IB_MREQ.din(er1_ibf_wle) = '1' then
918
            n.er1wle(to_integer(unsigned(r.eunit))) := '1';
919
          end if;
920
          if IB_MREQ.din(er1_ibf_iae) = '1' then
921
            n.er1iae(to_integer(unsigned(r.eunit))) := '1';
922
          end if;
923
          if IB_MREQ.din(er1_ibf_aoe) = '1' then
924
            n.er1aoe(to_integer(unsigned(r.eunit))) := '1';
925
          end if;
926
          if IB_MREQ.din(er1_ibf_ilf) = '1' then
927
            n.er1ilf(to_integer(unsigned(r.eunit))) := '1';
928
          end if;
929
        else                              -- loc access
930
          ibhold  := '1';
931
          n.state := s_whr;
932
        end if;
933
 
934
      when s_was =>                     -- was: write as ---------------------
935
        n.state := s_idle;                -- in general return to s_idle
936
        -- clear the attention bits marked as '1' in data word (loc and rem !!)
937
        n.dsata := r.dsata and not IB_MREQ.din(r.dsata'range);
938
        if ibrem = '0' then               -- loc access
939
          ibhold  := '1';
940
          n.state := s_whr;
941
        end if;
942
 
943
      when s_wdt =>                     -- wdt: write dt ---------------------
944
        n.state := s_idle;                -- in general return to s_idle
945
        if ibrem = '1' then               -- rem access
946
          n.dtrm(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_rm);
947
          n.dte1(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e1);
948
          n.dte0(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e0);
949
          n.state := s_idle;
950
        else                              -- loc access
951
          ibhold  := '1';
952
          n.state := s_whr;
953
        end if;
954
 
955
      when s_wds =>                     -- wdt: write ds ---------------------
956
        n.state := s_idle;                -- in general return to s_idle
957
        if ibrem = '1' then               -- rem access
958
          n.dsmol(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_mol);
959
          n.dswrl(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_wrl);
960
          n.dslbt(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_lbt);
961
          n.dsdpr(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_dpr);
962
          if IB_MREQ.din(ds_ibf_ata) = '1' then -- set ata on demand
963
            n.dsata(to_integer(unsigned(r.runit))) := '1';
964
          end if;
965
          if IB_MREQ.din(ds_ibf_vv) = '1' then  -- clr vv on demand
966
            n.dsvv(to_integer(unsigned(r.runit))) := '0';
967
          end if;
968
          if IB_MREQ.din(ds_ibf_erp) = '1'  then -- clr er1 on demand
969
            n.er1uns(to_integer(unsigned(r.eunit))) := '0';  -- clr all er1
970
            n.er1wle(to_integer(unsigned(r.eunit))) := '0';  -- "
971
            n.er1iae(to_integer(unsigned(r.eunit))) := '0';  -- "
972
            n.er1aoe(to_integer(unsigned(r.eunit))) := '0';  -- "
973
            n.er1rmr(to_integer(unsigned(r.eunit))) := '0';  -- "
974
            n.er1ilf(to_integer(unsigned(r.eunit))) := '0';  -- "
975
          end if;
976
          n.state := s_idle;
977
        else                              -- loc access
978
          ibhold  := '1';                   -- read-only reg, thus noop
979
          n.state := s_whr;
980
        end if;
981
 
982
      when s_wbae =>                    -- wbae: write bae -------------------
983
        n.state := s_idle;                -- in general return to s_idle
984
        if IB_MREQ.be0 = '1' then
985
          n.bae := IB_MREQ.din(bae_ibf_bae);
986
        end if;
987
 
988
      when s_wmem =>                    -- wmem: write mem (DA,MR1,OF,DC,MR2)-
989
        --  this state only handles massbus registers
990
        n.state := s_idle;                -- in general return to s_idle
991
        imem_addr := r.amap;              -- use mapped address
992
        imem_din  := r.dinmsk;            -- use masked input
993
 
994
        if ibrem = '0' then               -- loc access
995
          imem_we0 := '1';                  -- write memory
996
          imem_we1 := '1';
997
          ibhold  := '1';
998
          n.state := s_whr;
999
        else                              -- rem access
1000
          imem_we0 := '1';                  -- write memory
1001
          imem_we1 := '1';
1002
        end if;
1003
 
1004
      when s_wmembe =>                  -- wmem: write mem with be (WC,BA,DB)-
1005
        -- this state only handles controller registers --> no ned checking
1006
        n.state := s_idle;                -- in general return to s_idle
1007
        imem_we0 := IB_MREQ.be0;
1008
        imem_we1 := IB_MREQ.be1;
1009
        imem_addr := r.amap;
1010
        imem_din  := r.dinmsk;
1011
 
1012
      when s_whr =>                     -- whr: write hr ---------------------
1013
        n.state := s_idle;                -- in general return to s_idle
1014
        imem_addr := r.cs2unit & amapc_hr;  -- mem address of holding reg
1015
        imem_din  := not IB_MREQ.din;
1016
        if ibrem = '0' then               -- loc access
1017
          imem_we0 := '1';                  -- keep state
1018
          imem_we1 := '1';
1019
        end if;
1020
 
1021 32 wfjm
      when s_funcchk =>                 -- funcchk: check function go --------
1022
        n.state := s_idle;                -- in general return to s_idle
1023
        if r.cs1rdy = '0' and
1024
           unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_xfer) then
1025
          n.cs2pge := '1';                    --  issue program error
1026
        elsif IB_MREQ.din(cs1_ibf_func) = func_dclr then
1027
          n.eunit   := r.cs2unit;              -- for follow-up states
1028
          n.clrmode := clrmode_fdclr;
1029
          n.state   := s_oot_clr0;             -- OOT state, no hold!
1030
        elsif r.dserp(to_integer(unsigned(r.cs2unit))) = '1' then
1031
          n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
1032
        else
1033
          ibhold  := '1';
1034
          n.state := s_funcgo;
1035
        end if;
1036
 
1037 30 wfjm
      when s_funcgo =>                  -- funcgo: handle function go --------
1038
        n.state := s_idle;                -- in general return to s_idle
1039
        n.dsata(to_integer(unsigned(r.cs2unit))) := '0';
1040
 
1041
        case IB_MREQ.din(cs1_ibf_func) is
1042
          when func_noop =>                    -- func: noop --------------
1043
            null;                                -- nothing done...
1044
 
1045
          when func_pore  =>                   -- func: port release-------
1046
            n.poredone := '1';                   -- take note in done flag
1047
 
1048
          when func_unl   =>                   -- func: unload ------------
1049
                                               -- only for RP, simply clears MOL
1050
            if r.dtrm(to_integer(unsigned(r.cs2unit))) = '0' then
1051
              n.dsmol(to_integer(unsigned(r.cs2unit))) := '0';
1052
              n.dswrl(to_integer(unsigned(r.cs2unit))) := '0';
1053
              n.dsvv(to_integer(unsigned(r.cs2unit)))  := '0';
1054
              n.dsom(to_integer(unsigned(r.cs2unit)))  := '0';
1055
            else
1056
              n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
1057
            end if;
1058
            n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
1059
 
1060 32 wfjm
       -- when func_dclr  =>  now handled in funcchk !!
1061 30 wfjm
 
1062
          when func_offs  |                    -- func: offset ------------
1063
               func_retc  =>                   -- func: return to center --
1064
 
1065
            -- currently always immediate completion, so ata set here
1066
            n.dsata(to_integer(unsigned(r.cs2unit)))  := '1';
1067
 
1068
            if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
1069
              n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
1070
            else
1071
              if IB_MREQ.din(cs1_ibf_func) = func_offs then
1072
                n.dsom(to_integer(unsigned(r.cs2unit))) := '1';
1073
              else
1074
                n.dsom(to_integer(unsigned(r.cs2unit))) := '0';
1075
              end if;
1076
            end if;
1077
 
1078
          when func_pres  =>                   -- func: readin preset -----
1079
            n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
1080
            n.eunit   := r.cs2unit;              -- for follow-up states
1081
            n.clrmode := clrmode_fpres;
1082
            n.state   := s_oot_clr0;             -- OOT state, no hold!
1083
 
1084
          when func_pack  =>                   -- func: pack acknowledge --
1085
            n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
1086
            n.packdone := '1';                   -- take note in done flag
1087
 
1088
          -- seek like and data transfer functions
1089
          when func_seek  |                    -- func: seek --------------
1090
               func_recal |                    -- func: recalibrate -------
1091
               func_sear  |                    -- func: search ------------
1092
               func_wcd   |                    -- func: write check data --
1093
               func_wchd  |                    -- func: write check h&d ---
1094
               func_write |                    -- func: write  ------------
1095
               func_whd   |                    -- func: write header&data -
1096
               func_read  |                    -- func: read --------------
1097
               func_rhd   =>                   -- func: read header&data --
1098
 
1099
            if  IB_MREQ.din(cs1_ibf_func) = func_seek then
1100
              n.seekdone := '1';                 -- take note in done flag
1101
            end if;
1102
            if  IB_MREQ.din(cs1_ibf_func) = func_sear then
1103
              n.seardone := '1';                 -- take note in done flag
1104
            end if;
1105
 
1106
            -- check for transfer functions
1107
            n.fxfer := '0';
1108
            if unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_wcd)  then
1109
              n.fxfer := '1';
1110
              -- in case of write, check for write lock
1111
              if IB_MREQ.din(cs1_ibf_func) = func_write or
1112
                 IB_MREQ.din(cs1_ibf_func) = func_whd   then
1113
                if r.dswrl(to_integer(unsigned(r.cs2unit))) = '1' then
1114
                  n.er1wle(to_integer(unsigned(r.cs2unit))) := '1';
1115
                end if;
1116
              end if;
1117
            end if;
1118
 
1119
            if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
1120
              n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
1121
              n.dsata(to_integer(unsigned(r.cs2unit)))  := '1';
1122
            else
1123
              ibhold  := '1';
1124
              n.state := s_chkdc;
1125
            end if;
1126
 
1127
          -- illegal function codes
1128
          when others =>
1129
            n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
1130
            n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
1131
 
1132
        end case; -- IB_MREQ.din(cs1_ibf_func)
1133
 
1134
      when s_chkdc =>                   -- chkdc: handle dc check ------------
1135
        imem_addr := r.cs2unit & amapc_dc; -- mem address of dc reg
1136
        if unsigned(MEM_DOUT(dc_ibf_ca)) > unsigned(r.camax) then
1137
          n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
1138
        end if;
1139
        ibhold  := '1';
1140
        n.state := s_chkda;
1141
 
1142
      when s_chkda =>                   -- chkda: handle da check ------------
1143
        imem_addr := r.cs2unit & amapc_da; -- mem address of da reg
1144
        if unsigned(MEM_DOUT(da_ibf_sa)) > unsigned(r.samax) or
1145
           unsigned(MEM_DOUT(da_ibf_ta)) > unsigned(r.tamax) then
1146
          n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
1147
        end if;
1148
        ibhold  := '1';
1149
        n.state := s_chkdo;
1150
 
1151
      when s_chkdo =>                   -- chkdo: execute function -----------
1152
        if r.er1iae(to_integer(unsigned(r.cs2unit))) = '1' or
1153
           r.er1wle(to_integer(unsigned(r.cs2unit))) = '1' then
1154
          n.dsata(to_integer(unsigned(r.cs2unit))) := '1'; -- ata and done
1155
        else
1156
          if r.fxfer = '0'  then            -- must be seek like function
1157
            n.dspip(to_integer(unsigned(r.cs2unit))) := '1'; -- pip
1158
            n.idlycnt := r.idlyval;                          -- start delay
1159
          else                              -- must be transfer function
1160
            n.ffunc  := IB_MREQ.din(cs1_ibf_func);  -- latch func
1161
            n.funit  := r.cs2unit;                  -- latch unit
1162
            n.cs1rdy := '0';                  -- controller busy
1163
            n.cs2wce := '0';                  -- clear errors
1164
            n.cs2ned := '0';
1165
            n.cs2nem := '0';
1166
            n.cs2pge := '0';
1167
            n.cs2mxf := '0';
1168
            ilam := '1';                      -- issue lam
1169
          end if;
1170
        end if;
1171
        n.state := s_idle;
1172
 
1173
      when s_read =>                    -- read: all register reads ----------
1174
        n.state := s_idle;                -- in general return to s_idle
1175
        imem_addr := r.amap;
1176
 
1177
        case r.omux is
1178
 
1179
          when omux_cs1 =>                -- omux: cs1 reg ---------------
1180
            idout(cs1_ibf_sc)   := r.cs1sc;
1181
            idout(cs1_ibf_tre)  := r.cs1tre;
1182
            idout(cs1_ibf_dva)  := '1';
1183
            idout(cs1_ibf_bae)  := r.bae(1 downto 0);
1184
            idout(cs1_ibf_rdy)  := r.cs1rdy;
1185
            idout(cs1_ibf_ie)   := r.cs1ie;
1186
            if ibrem = '0' then             -- loc access
1187
              idout(cs1_ibf_func) := MEM_DOUT(cs1_ibf_func); --func per unit
1188
              if r.ned = '1' then             -- drive off
1189
                n.cs2ned := '1';                -- signal error
1190
              end if;
1191
            else                            -- rem access
1192
              idout(cs1_ibf_func) := r.ffunc;
1193
            end if;
1194
 
1195
          when omux_cs2 =>                -- omux: cs2 reg ---------------
1196
            idout(cs2_ibf_wce)   := r.cs2wce;
1197
            idout(cs2_ibf_ned)   := r.cs2ned;
1198
            idout(cs2_ibf_nem)   := r.cs2nem;
1199
            idout(cs2_ibf_pge)   := r.cs2pge;
1200
            idout(cs2_ibf_mxf)   := r.cs2mxf;
1201
            idout(cs2_ibf_or)    := '1';
1202
            idout(cs2_ibf_ir)    := '1';
1203
            idout(cs2_ibf_pat)   := r.cs2pat;
1204
            idout(cs2_ibf_bai)   := r.cs2bai;
1205
            idout(cs2_ibf_unit2) := r.cs2unit2;
1206
            if ibrem = '0' then           -- loc access
1207
              idout(cs2_ibf_unit)  := r.cs2unit;
1208
            else                          -- rem access
1209
              idout(cs2_ibf_unit)  := r.funit;
1210
            end if;
1211
 
1212
          when omux_ds =>                 -- omux: ds  reg ---------------
1213
            idout(ds_ibf_ata)  := r.dsata(to_integer(unsigned(r.eunit)));
1214
            idout(ds_ibf_erp)  := r.dserp(to_integer(unsigned(r.eunit)));
1215
            idout(ds_ibf_pip)  := r.dspip(to_integer(unsigned(r.eunit)));
1216
            idout(ds_ibf_mol)  := r.dsmol(to_integer(unsigned(r.eunit)));
1217
            idout(ds_ibf_wrl)  := r.dswrl(to_integer(unsigned(r.eunit)));
1218
            idout(ds_ibf_lbt)  := r.dslbt(to_integer(unsigned(r.eunit)));
1219
            idout(ds_ibf_dpr)  := r.dsdpr(to_integer(unsigned(r.eunit)));
1220
 
1221
            -- ds.dry is 0 if mol=0 or if transfer or seek is active on unit
1222
            -- the logic below checks for the complement ...
1223
            if r.dsmol(to_integer(unsigned(r.eunit))) = '1' then
1224
              if (r.cs1rdy = '1' or r.funit /= r.eunit) and
1225
                 r.dspip(to_integer(unsigned(r.eunit))) = '0' then
1226
                idout(ds_ibf_dry)  := '1';
1227
              end if;
1228
            end if;
1229
 
1230
            idout(ds_ibf_vv)   := r.dsvv (to_integer(unsigned(r.eunit)));
1231
            idout(ds_ibf_om)   := r.dsom (to_integer(unsigned(r.eunit)));
1232
 
1233
          when omux_er1 =>                -- omux: er1 reg ---------------
1234
            idout(er1_ibf_uns)  := r.er1uns(to_integer(unsigned(r.eunit)));
1235
            idout(er1_ibf_wle)  := r.er1wle(to_integer(unsigned(r.eunit)));
1236
            idout(er1_ibf_iae)  := r.er1iae(to_integer(unsigned(r.eunit)));
1237
            idout(er1_ibf_aoe)  := r.er1aoe(to_integer(unsigned(r.eunit)));
1238
            idout(er1_ibf_rmr)  := r.er1rmr(to_integer(unsigned(r.eunit)));
1239
            idout(er1_ibf_ilf)  := r.er1ilf(to_integer(unsigned(r.eunit)));
1240
 
1241
          when omux_as =>                 -- omux: as  reg ---------------
1242
            idout(r.dsata'range) := r.dsata;
1243
 
1244
          when omux_la =>                 -- omux: la  reg ---------------
1245
            idout(la_ibf_sc)    := r.sc;
1246
 
1247
          when omux_dt =>                 -- omux: dt  reg ---------------
1248
            if ibrem = '0' then             -- loc access
1249
              idout(13) := '1';               -- set bit 020000 (movable head)
1250
              idout(r.dtyp'range) := r.dtyp;
1251
            else                            -- rem access (read back rem side)
1252
              idout(dt_ibf_rm) := r.dtrm(to_integer(unsigned(r.runit)));
1253
              idout(dt_ibf_e1) := r.dte1(to_integer(unsigned(r.runit)));
1254
              idout(dt_ibf_e0) := r.dte0(to_integer(unsigned(r.runit)));
1255
            end if;
1256
 
1257
          when omux_sn =>                 -- omux: sn  reg ---------------
1258
            -- the serial number is encoded as 4 digit BCD
1259
            --   digit 3: always 1
1260
            --   digit 2: 1 if RM type; 0 if RP type
1261
            --   digit 1: 0-3 based on encoded drive type
1262 32 wfjm
            --   digit 0: 0-3 taken as complement of unit
1263
            -- Note: the 3lsb are the *complement* of the unit number because
1264
            --       211bsd driver code contains a hack to detect SI and CDC
1265
            --       drives. For those drives the drive type is encode in the
1266
            --       sn register, and one convention is that the 3 lsb of sn
1267
            --       equal the unit numnber. To prevent that the SI/CDC hacks
1268
            --       are actived the 3lsb are set as complement of the unit !
1269 30 wfjm
            idout(12) := '1';
1270
            idout(8)  := r.dtrm(to_integer(unsigned(r.eunit)));
1271
            idout(5)  := r.dte1(to_integer(unsigned(r.eunit)));
1272
            idout(4)  := r.dte0(to_integer(unsigned(r.eunit)));
1273 32 wfjm
            idout(2)  := '1';
1274
            idout(1)  := not r.eunit(1);
1275
            idout(0)  := not r.eunit(0);
1276 30 wfjm
 
1277
          when omux_bae =>                -- omux: bae reg ---------------
1278
            idout(bae_ibf_bae) := r.bae;
1279
 
1280
          when omux_cs3 =>                -- omux: cs3 reg ---------------
1281
            idout(cs3_ibf_wco) := r.cs2wce and     r.cs3wco;
1282
            idout(cs3_ibf_wce) := r.cs2wce and not r.cs3wco;
1283
            idout(cs3_ibf_ie)  := r.cs1ie;
1284
            if ibrem = '1' then             -- rem access
1285
              idout(cs3_ibf_rseardone) := r.seardone;
1286
              idout(cs3_ibf_rpackdone) := r.packdone;
1287
              idout(cs3_ibf_rporedone) := r.poredone;
1288
              idout(cs3_ibf_rseekdone) := r.seekdone;
1289
              if IB_MREQ.re = '1' then        -- if read, do read & clear
1290
                n.seardone := '0';
1291
                n.packdone := '0';
1292
                n.poredone := '0';
1293
                n.seekdone := '0';
1294
              end if;
1295
            end if;
1296
 
1297
          when omux_mem =>                -- omux: mem output ------------
1298
            idout := MEM_DOUT;
1299
 
1300
          when omux_zero =>               -- omux: zero ------------------
1301
            idout := (others=>'0');
1302
 
1303
          when others => null;            -- nxr caught before in mapper !
1304
        end case;  -- case r.omux
1305
 
1306
      when s_setrmr =>                    -- set rmr flag ----------------------
1307
        n.er1rmr(to_integer(unsigned(r.cs2unit))) := '1';
1308
        n.state := s_idle;
1309
 
1310
      when s_oot_clr0 =>                  -- OOT clr0: state 0 -----------------
1311
        if r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr then
1312
          n.cs1rdy   := '1';                 -- clear cs1
1313
          n.cs1ie    := '0';
1314
          n.cs2wce   := '0';                 -- clear cs2
1315
          n.cs2ned   := '0';
1316
          n.cs2nem   := '0';
1317
          n.cs2pge   := '0';
1318
          n.cs2mxf   := '0';
1319
          n.cs2pat   := '0';
1320
          n.cs2bai   := '0';
1321
          n.cs2unit2 := '0';
1322
          n.cs2unit  := (others=>'0');
1323
          n.bae      := (others=>'0');       -- clear bae
1324
          n.ireq     := '0';                 -- clear iff
1325
        end if;
1326
 
1327
        if r.clrmode=clrmode_breset or r.clrmode=clrmode_fdclr then
1328
          n.er1uns(to_integer(unsigned(r.eunit))) := '0';  -- clr all er1
1329
          n.er1wle(to_integer(unsigned(r.eunit))) := '0';  -- "
1330
          n.er1iae(to_integer(unsigned(r.eunit))) := '0';  -- "
1331
          n.er1aoe(to_integer(unsigned(r.eunit))) := '0';  -- "
1332
          n.er1rmr(to_integer(unsigned(r.eunit))) := '0';  -- "
1333
          n.er1ilf(to_integer(unsigned(r.eunit))) := '0';  -- "
1334
        end if;
1335
 
1336
        n.cerm  := r.dtrm(to_integer(unsigned(ieunit)));
1337
 
1338
        n.clrreg := "000";
1339
        ibhold  := r.ibsel;                -- delay pending request
1340
        n.state := s_oot_clr1;
1341
 
1342
      when s_oot_clr1 =>                  -- OOT clr1: state 1 ----------------
1343
        imem_addr := r.eunit & r.clrreg;
1344
        imem_din  := (others=>'0');
1345
 
1346
        iclrreg := '0';
1347
        case r.clrmode is
1348
 
1349
          when clrmode_breset =>        -- BRESET -------------------------
1350
            iclrreg := '1';               -- simply clear all (cntl+drives)
1351
 
1352
          when clrmode_cs2clr =>        -- CS2.CLR (controller clr) -------
1353
            case r.clrreg is
1354
              when amapc_ext => iclrreg := '1';
1355
              when amapc_mr1 => iclrreg := r.cerm;
1356
              when others => null;
1357
            end case;
1358
 
1359
          when clrmode_fdclr =>         -- func=DCLR (drive clr) ----------
1360
            case r.clrreg is
1361
              when amapc_mr1 => iclrreg := r.cerm;
1362
              when others => null;
1363
            end case;
1364
 
1365
          when clrmode_fpres =>         -- func=PRESET --------------------
1366
            case r.clrreg is
1367
              when amapc_da  => iclrreg := '1';
1368
              when amapc_of  => iclrreg := '1';
1369
              when amapc_dc  => iclrreg := '1';
1370
              when others => null;
1371
            end case;
1372
 
1373
          when others => null;
1374
        end case;
1375
        if iclrreg = '1' then
1376
          imem_we0 := IB_MREQ.be0;
1377
          imem_we1 := IB_MREQ.be1;
1378
        end if;
1379
        n.clrreg := slv(unsigned(r.clrreg) + 1);
1380
 
1381
        ibhold := r.ibsel;                   -- delay pending request
1382
        if r.clrreg = "111" then             -- if last register done
1383
          n.state := s_oot_clr2;               -- proceed with clr2
1384
        end if;
1385
 
1386
      when s_oot_clr2 =>                  -- OOT clr2: state 2 ----------------
1387
        n.eunit := slv(unsigned(r.eunit) + 1);
1388
 
1389
        ibhold := r.ibsel;                   -- delay pending request, so that
1390
                                             -- s_idle can finally process it
1391
        if (r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr) and
1392
           r.eunit /= "11" then
1393
          n.state := s_oot_clr0;
1394
        else
1395
          n.state := s_idle;
1396
        end if;
1397
 
1398
      when others => null;                -- <> ------------------------------
1399
    end case;  -- case r.state
1400
 
1401
    -- update cs1tre and cs1sc
1402
    n.cs1tre := r.cs2wce or r.cs2ned or r.cs2nem or r.cs2pge or r.cs2mxf;
1403
    n.cs1sc  := n.cs1tre or r.dsata(0) or r.dsata(1) or r.dsata(2) or r.dsata(3);
1404
    -- update dserp
1405
    n.dserp  := r.er1uns or -- or all er1
1406
                r.er1wle or -- "
1407
                r.er1iae or -- "
1408
                r.er1aoe or -- "
1409
                r.er1rmr or -- "
1410
                r.er1ilf;   -- "
1411
 
1412
    -- handle current sector counter (for RxLA emulation)
1413
    -- advance every 128 usec, so generate a pulse every 128 usec
1414
    if CE_USEC = '1' then
1415
      n.uscnt := slv(unsigned(r.uscnt) + 1);
1416
      if unsigned(r.uscnt) = 0 then
1417
        iscinc := '1';
1418
      end if;
1419
    end if;
1420
 
1421
    -- if current sector larger or equal highest sector wrap to zero
1422
    -- note: iscinc is also '1' when unit changes, this ensures that
1423
    --       the sector counter is always in range when read to ibus.
1424
    if iscinc = '1' then
1425
      if unsigned(r.sc) >= unsigned(r.samax) then
1426
        n.sc := (others=>'0');
1427
      else
1428
        n.sc := slv(unsigned(r.sc) + 1);
1429
      end if;
1430
    end if;
1431
 
1432
    -- the RH70 interrupt logic is very unusual
1433
    --  1. done interrupts (rdy 0->1) are edge sensitive (via r.ireq)
1434
    --  2. done interrupts are not canceled when IE is cleared
1435
    --  3. attention interrupts are level sensitive      (via r.cs1sc)
1436
    --  4. IE is disabled on interrupt acknowledge
1437
 
1438
    iei_req := r.ireq or (r.cs1sc and r.cs1ie and r.cs1rdy);
1439
 
1440
    if EI_ACK = '1'  then               -- interrupt executed
1441
      n.ireq  := '0';                      -- cancel request
1442
      n.cs1ie := '0';                      -- disable interrupts
1443
    end if;
1444
 
1445
    N_REGS <= n;
1446
 
1447
    MEM_0_WE <= imem_we0;
1448
    MEM_1_WE <= imem_we1;
1449
    MEM_ADDR <= imem_addr;
1450
    MEM_DIN  <= imem_din;
1451
 
1452
    IB_SRES.dout <= idout;
1453
    IB_SRES.ack  <= r.ibsel and ibreq;
1454
    IB_SRES.busy <= ibhold  and ibreq;
1455
 
1456
    RB_LAM <= ilam;
1457
    EI_REQ <= iei_req;
1458
 
1459
  end process proc_next;
1460
 
1461
 
1462
end syn;

powered by: WebSVN 2.1.0

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