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

Subversion Repositories pdp8

[/] [pdp8/] [trunk/] [pdp8/] [rk8e.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 trurl
--------------------------------------------------------------------
2
--!
3
--! PDP-8 Processor
4
--!
5
--! \brief
6
--!      RK8E Disk Controller
7
--!
8
--! \file
9
--!      rk8e.vhd
10
--!
11
--! \details
12
--!      The RK8E Disk Controller is designed to be register
13
--!      compatible with real RK8E controller.  Instead of
14
--!      interfacing to 4 RK05 disk drives, this controller
15
--!      interfaces to a single Secure Digital memory chip
16
--!      which contains the storage equivalent of 4 RK05
17
--!      disk drives.
18
--!
19
--!      In this case, the term 'compatible' is a matter of
20
--!      opinion.  The Secure Digital chip does not have the
21
--!      delays associated with the rotational latency of a
22
--!      disk drive and does not have delays associated with
23
--!      head motion.  The Secure Digital chip also transfers
24
--!      data (read and write) faster than a RK05 disk.
25
--!
26
--!      The disk drive can be configured to emulated these
27
--!      latencies.  It is not well tested and fortunately it
28
--!      appears that most applications do not require this
29
--!      level of timing fidelity.  Alternately small delays
30
--!      can be used which seem to work.
31
--!
32
--!      The Cylinder, Head, and Sector (CHS) addressing of
33
--!      the Secure Digital chip  has been borrowed from the
34
--!      SIMH simulator.  This allows SIMH RK05 disk images
35
--!      which are readily available on the internet to be
36
--!      used without modification.
37
--!
38
--!      The details of this mapping is described in the RK05
39
--!      device where the RK05 CHS addressing is manipulated to
40
--!      form the 32-bit linear sector address used by the
41
--!      Secure Digial Chip.
42
--!
43
--!      Since an RK05 image is somewhat less than 4 MB, the four
44
--!      RK05 images are aligned on 4 MB addresses.  Therefore
45
--!      a 16 MB Secure Digital chip is suffient storage for four
46
--!      RK05 disk drives.  I used a 4 GB Secure Digital chip
47
--!      because it was the smallest I could find.
48
--!
49
--!      The Secure Digital disk image for four RK05 disks is
50
--!      built as follows:
51
--!
52
--! \code
53
--! dd if=advent.rk05            of=/dev/sdc seek=0     count=6496
54
--! dd if=diagpack2.rk05         of=/dev/sdc seek=8192  count=6496
55
--! dd if=diag-games-kermit.rk05 of=/dev/sdc seek=16384 count=6496
56
--! dd if=multos8.rk05           of=/dev/sdc seek=24576 count=6496
57
--! \endcode
58
--!
59
--!      Your choice of disk images may vary.
60
--!
61
--!      The VHDL Code below is organized as follows:
62
--!      -# Bus Interface
63
--!      -# RK8E Registers
64
--!      -# 4x RK05 Timing Simulators
65
--!      -# Secure Digital Interface.
66
--!
67
--!      The Bus Interface operates asynchronously as requried for
68
--!      the the bus operation.   The Bus Interface decodes the
69
--!      various IOTs and creates "rk8eOPs" that are passed to the
70
--!      "RK8E Registers" process for action.
71
--!
72
--!      The "RK8E Registers" process maintains the controller state.
73
--!      When a disk command is received, it dispatches the command
74
--!      to one of the four RK05 where the delays associated with
75
--!      the disk drive are simulated.  (Each RK05 maintains a
76
--!      a notion of head, cyclinder, and sector so rotational
77
--!      and head motion delays can be accurate simulated).  Once
78
--!      The RK05 has completed it's operation, the command is
79
--!      forwarded to the Secure Digial disk device where the
80
--!      read or write is actually performed.
81
--!
82
--!      How this all works:
83
--!
84
--!      When the unit is powered-up, it runs through the SD Card
85
--!      initialization sequence.   This takes 3 or 4 milliseconds.
86
--!
87
--!      When the SD interface is initializing, the SD device
88
--!      asserts the sdINIT output which holds the processor in
89
--!      RESET.  That prevents the processor from giving the Disk
90
--!      Controller a command before it is finished initializing
91
--!      the SD Interface and the SD Card.
92
--!
93
--!      Once the SD Card is initialized, the SD interface waits
94
--!      in the stateIDLE state for a read command or a write
95
--!      command.
96
--!
97
--! \todo
98
--!      -# Most the of RK8E diagnostics are not implemented.
99
--!      -# The DMAN register and most of it's functionality is
100
--!         not implemented.
101
--!
102
--! \author
103
--!      Rob Doyle - doyle (at) cox (dot) net
104
--!
105
--------------------------------------------------------------------
106
--
107
--  Copyright (C) 2009, 2010, 2011, 2012 Rob Doyle
108
--
109
-- This source file may be used and distributed without
110
-- restriction provided that this copyright statement is not
111
-- removed from the file and that any derivative work contains
112
-- the original copyright notice and the associated disclaimer.
113
--
114
-- This source file is free software; you can redistribute it
115
-- and/or modify it under the terms of the GNU Lesser General
116
-- Public License as published by the Free Software Foundation;
117
-- version 2.1 of the License.
118
--
119
-- This source is distributed in the hope that it will be
120
-- useful, but WITHOUT ANY WARRANTY; without even the implied
121
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
122
-- PURPOSE. See the GNU Lesser General Public License for more
123
-- details.
124
--
125
-- You should have received a copy of the GNU Lesser General
126
-- Public License along with this source; if not, download it
127
-- from http://www.gnu.org/licenses/lgpl.txt
128
--
129
--------------------------------------------------------------------
130
--
131
-- Comments are formatted for doxygen
132
--
133
 
134
library ieee;                                           --! IEEE Library
135
use ieee.std_logic_1164.all;                            --! IEEE 1164
136
use ieee.numeric_std.all;                               --! IEEE Numeric Standard
137
use work.sd_types.all;                                  --! SD Types
138
use work.sdspi_types.all;                               --! SPI Types
139
use work.rk8e_types.all;                                --! RK8E types
140
use work.rk05_types.all;                                --! RK05 types
141
use work.cpu_types.all;                                 --! CPU types
142
 
143
--
144
--! RK8E Disk Controller Entity
145
--
146
 
147
entity eRK8E is port (
148
    sys       : in  sys_t;                              --! Clock/Reset
149
    -- Config
150
    devNUM    : in  devNUM_t;                           --! Device Number
151
    rk05INH   : in  std_logic_vector(0 to 3);           --! Write Inhibit
152
    rk05MNT   : in  std_logic_vector(0 to 3);           --! Device is Mounted
153
    -- DMA
154
    cpu       : in  cpu_t;                              --! CPU Output
155
    dev       : out dev_t;                              --! Device Output
156
    -- SD Interface
157
    sdCD      : in  std_logic;                          --! CD
158
    sdWP      : in  std_logic;                          --! WP
159
    sdMISO    : in  std_logic;                          --! Data In
160
    sdMOSI    : out std_logic;                          --! Data Out
161
    sdSCLK    : out std_logic;                          --! Clock
162
    sdCS      : out std_logic;                          --! Chip Select
163
    -- RK8E Status
164
    rk8eINIT  : out std_logic;                          --! RK8E is initializing
165
    rk8eSTAT  : out rk8eSTAT_t                          --! RK8E Status
166
);
167
end eRK8E;
168
 
169
--
170
--! RK8E Disk Controller RTL
171
--
172
 
173
architecture rtl of eRK8E is
174
 
175
    --
176
    -- Command Register
177
    --
178
 
179
    signal   rkcm        : data_t;                      --! Command Register
180
    subtype  rkcmFUN_t   is std_logic_vector(0 to 2);   --! FUN field type
181
    subtype  rkcmDRV_t   is std_logic_vector(0 to 1);   --! DRV Field type
182
    alias    rkcmFUN     : rkcmFUN_t is rkcm(0 to 2);   --! Function
183
    alias    rkcmIOD     : std_logic is rkcm(3);        --! Interrupt On Done
184
    alias    rkcmDOSD    : std_logic is rkcm(4);        --! Assert Done on Seek Done
185
    alias    rkcmLEN     : std_logic is rkcm(5);        --! Block Length
186
    alias    rkcmEMA     : field_t   is rkcm(6 to 8);   --! Extended Memory Address
187
    alias    rkcmDRV     : rkcmDRV_t is rkcm(9 to 10);  --! Drive Select
188
    alias    rkcmCYL0    : std_logic is rkcm(11);       --! Cylinder MSB
189
    constant funREAD     : rkcmFUN_t := "000";          --! Read Data Command
190
    constant funREADALL  : rkcmFUN_t := "001";          --! Read All Command
191
    constant funWRPROT   : rkcmFUN_t := "010";          --! Set write protect Command
192
    constant funSEEK     : rkcmFUN_t := "011";          --! Seek Command
193
    constant funWRITE    : rkcmFUN_t := "100";          --! Write Data Command
194
    constant funWRITEALL : rkcmFUN_t := "101";          --! Write All Command
195
 
196
    --
197
    -- Status Register bits that are implemented
198
    --
199
 
200
    signal   rkst        : data_t;                      --! Status register
201
    signal   rkstDONE    : std_logic;                   --! Device is done
202
    signal   rkstMOT     : std_logic;                   --! Head in Motion (seeking)
203
    signal   rkstFNR     : std_logic;                   --! File not ready
204
    signal   rkstBUSY    : std_logic;                   --! Controller is busy
205
    signal   rkstTME     : std_logic;                   --! Timing Error
206
    signal   rkstWLE     : std_logic;                   --! Write Lock Error
207
    signal   rkstSTE     : std_logic;                   --! Status Error
208
 
209
    --
210
    -- Memory Address Register
211
    --
212
 
213
    signal   rkma        : addr_t;                      --! Memory Address Register
214
 
215
    --
216
    -- Disk Address Register
217
    --
218
 
219
    subtype  rkdaCYL_t   is std_logic_vector(0 to 6);   --! RKDA Cylinder type
220
    subtype  rkdaSECT_t  is std_logic_vector(0 to 3);   --! RKDA Sector type
221
    subtype  rkdaHEAD_t  is std_logic;                  --! RKDA Head type
222
    signal   rkda        : data_t;                      --! Disk Address Register
223
    alias    rkdaCYL     : rkdaCYL_t  is rkda(0 to 6);  --! Cylinder
224
    alias    rkdaHEAD    : rkdaHEAD_t is rkda(7);       --! Head
225
    alias    rkdaSECT    : rkdaSECT_t is rkda(8 to 11); --! Sector
226
 
227
    --
228
    -- Maintenance Mode Registers
229
    --
230
 
231
    signal  maintMODE    : std_logic;                   --! Maintenance Mode
232
    signal  shiftEN      : std_logic;                   --! Shifter Enable
233
    signal  shiftCNT     : unsigned(0 to 3);            --! Shift Count
234
 
235
    --
236
    -- Disk Operations
237
    --
238
 
239
    type     rk8eOP_t    is (rk8eopNOP,                 --! Nothing to do
240
                             rk8eopDCLS,                --! Disk Clear Status
241
                             rk8eopDCLC,                --! Disk Clear Control
242
                             rk8eopDCLD,                --! Disk Clear Drive
243
                             rk8eopDLAG,                --! Disk Load and Go
244
                             rk8eopDLCA,                --! Disk Load Current Address
245
                             rk8eopDLDC,                --! Disk Load Command
246
                             rk8eopDMAN);               --! Disk Maintenace Mode
247
    signal   rk8eOP      : rk8eOP_t;                    --! Disk Operation
248
 
249
    --
250
    -- Device OP Codes
251
    -- Normally Device is 7x
252
    --
253
 
254
    constant opDSKP      : devOP_t    := o"1";          --! 6xx1 : Disk Skip on Flag
255
    constant opDCLR      : devOP_t    := o"2";          --! 6xx2 : Disk Clear
256
    constant opDLAG      : devOP_t    := o"3";          --! 6xx3 : Disk Load Address and Go
257
    constant opDLCA      : devOP_t    := o"4";          --! 6xx4 : Disk Load Current Address
258
    constant opDRST      : devOP_t    := o"5";          --! 6xx5 : Disk Read Status
259
    constant opDLDC      : devOP_t    := o"6";          --! 6xx6 : Disk Load Command
260
    constant opDMAN      : devOP_t    := o"7";          --! 6xx6 : Disk Maintenance
261
 
262
    --
263
    -- Clear Commands
264
    --
265
 
266
    subtype  clrOP_t     is std_logic_vector(0 to 1);
267
    constant clropCLS    : clrOP_t    := "00";          --! Clear Status
268
    constant clropCLC    : clrOP_t    := "01";          --! Clear Control
269
    constant clropCLD    : clrOP_t    := "10";          --! Clear Drive
270
    constant clropCLSA   : clrOP_t    := "11";          --! Clear Status Alt
271
 
272
    --
273
    -- RK05 Interfaces
274
    --
275
 
276
    signal   rk05OP      : rk05OP_tt;                   --! Array of RK05 OPs
277
    signal   rk05STAT    : rk05STAT_tt;                 --! Array of RK05 Status
278
    signal   rk05CYL     : rk05CYL_t;                   --! Cylinder
279
 
280
    --
281
    -- Interface to SD Controller
282
    --
283
 
284
    signal   sdOP        : sdOP_t;                      --! SD Device Command
285
    signal   sdLEN       : sdLEN_t;                     --! 128/256 Word access
286
    signal   sdMEMaddr   : addr_t;                      --! Memory Address
287
    signal   sdDISKaddr  : sdDISKaddr_t;                --! Linear Disk Address
288
    signal   sdFAIL      : std_logic;                   --! SD Failed
289
    signal   sdSTAT      : sdSTAT_t;                    --! SD Device Status
290
 
291
    --
292
    -- DMA Interface
293
    --
294
 
295
    signal   dmaDOUT     : data_t;                      --! DMA Data Out
296
    signal   dmaADDR     : addr_t;                      --! DMA Address
297
    signal   dmaRD       : std_logic;                   --! DMA Read
298
    signal   dmaWR       : std_logic;                   --! DMA Write
299
    signal   dmaREQ      : std_logic;                   --! DMA Request
300
 
301
    --
302
    -- Misc
303
    --
304
 
305
    signal   skipFLAG    : std_logic;                   --! Skip Flag
306
 
307
    --
308
    -- Drives
309
    --
310
 
311
    signal   driveSelect : rk05drvNUM_t;
312
    signal   rk05BUSY    : rk05drvNUM_t;
313
 
314
    --
315
    -- Bit OPs
316
    --
317
 
318
    type     bitOP_t     is (bitopNOP,
319
                             bitopSET,
320
                             bitopCLR);
321
    signal   bitopDONE   : bitOP_t;
322
    signal   bitopMOT    : bitOP_t;
323
    signal   bitopFNR    : bitOP_t;
324
    signal   bitopBUSY   : bitOP_t;
325
    signal   bitopTME    : bitOP_t;
326
    signal   bitopWLE    : bitOP_t;
327
    signal   bitopSTE    : bitOP_t;
328
 
329
    --
330
    -- Configuration
331
    --
332
 
333
    constant simh        : std_logic := '1';
334
    constant test        : std_logic := '0';
335
    constant simtime     : std_logic := '0';            --! Simulate disk timing
336
 
337
    --
338
    --! isBUSY:
339
    --!  Returns true if the controller is busy, false otherwise.
340
    --
341
 
342
    function isBUSY(rk05BUSY : rk05drvNUM_t) return boolean is
343
    begin
344
        if ((rk05BUSY = DRIVE0) or (rk05BUSY = DRIVE1) or
345
            (rk05BUSY = DRIVE2) or (rk05BUSY = DRIVE3)) then
346
            return true;
347
        else
348
            return false;
349
        end if;
350
    end isBUSY;
351
 
352
begin
353
 
354
    --
355
    -- RK05 Drive Select
356
    --
357
 
358
    driveSelect <= to_integer(unsigned(rkcmDRV));
359
 
360
    --
361
    -- RK05 Cylinder
362
    --
363
 
364
    rk05CYL <= rkcmCYL0 & rkdaCYL;
365
 
366
    --
367
    -- SD Failure
368
    --
369
 
370
    sdFAIL    <= '1' when ((sdSTAT.state = sdstateINFAIL) or
371
                           (sdSTAT.state = sdstateRWFAIL)) else '0';
372
 
373
    --
374
    -- SD Initializing
375
    --
376
 
377
    rk8eINIT  <= '1' when sdSTAT.state = sdstateINIT else '0';
378
 
379
    --
380
    --! RK8E Bus Interface
381
    --!
382
    --! \details
383
    --!     The Bus Interface decodes the individual RK8E IOT instructions.
384
    --!     The various disk operations are encoded into the rk8eOP command
385
    --!     which is applied to the RK8E state machine.
386
    --!
387
    --! \note
388
    --!     The Bus Interface is totally asynchronous.  The dev.ack,
389
    --!     dev.skip, and dev.devc signals are combinationally derived from
390
    --!     CPU output bus signals.  These signals will be sampled by the
391
    --!     CPU on the device bus input on the next clock cycle.
392
    --
393
 
394
    RK8E_BUSINTF : process(cpu.buss, devNUM, rkst, rkcm, dmaRD, dmaWR, dmaREQ,
395
                           skipFLAG, dmaDOUT, dmaADDR, sdDISKaddr)
396
    begin
397
 
398
        dev.ack   <= '0';
399
        dev.data  <= (others => '0');
400
        dev.devc  <= devWR;
401
        dev.skip  <= '0';
402
        dev.cpreq <= '0';
403
        dev.intr  <= rkcmIOD and skipFLAG;
404
        rk8eOP    <= rk8eopNOP;
405
 
406
        if cpu.buss.addr(0 to 2) = opIOT and cpu.buss.addr(3 to 8) = devNUM and cpu.buss.lxdar = '1' then
407
 
408
            case cpu.buss.addr(9 to 11) is
409
 
410
                --
411
                -- IOT 6xx1: DSKP - Disk Skip on Flag
412
                --
413
 
414
                when opDSKP =>
415
                    dev.ack  <= '1';
416
                    dev.devc <= devWR;
417
                    dev.skip <= skipFLAG;
418
                    rk8eOP   <= rk8eopNOP;
419
 
420
                --
421
                -- IOT 6xx2: DCLR - Disk Clear
422
                --
423
 
424
                when opDCLR =>
425
                    dev.ack   <= '1';
426
                    dev.devc  <= devWRCLR;
427
                    dev.skip  <= '0';
428
 
429
                    case cpu.buss.data(10 to 11) is
430
 
431
                        --
432
                        -- DCLS: Clear AC and Status Register
433
                        --
434
 
435
                        when clropCLS =>
436
                            rk8eOP <= rk8eopDCLS;
437
 
438
                        --
439
                        -- DCLC: Clear AC, Control, everything.
440
                        --
441
 
442
                        when clropCLC =>
443
                            rk8eOP <= rk8eopDCLC;
444
 
445
                        --
446
                        -- DCLD: Clear AC, recalibrate to track 0,
447
                        -- and clear Status Register
448
                        --
449
 
450
                        when clropCLD =>
451
                            rk8eOP <= rk8eopDCLD;
452
 
453
                        --
454
                        -- DCLSA: Clear Status (Alt Decode of DCLS)
455
                        --
456
 
457
                        when clropCLSA =>
458
                            rk8eOP <= rk8eopDCLS;
459
 
460
                        --
461
                        -- Everything else
462
                        --
463
 
464
                        when others =>
465
                            rk8eOP <= rk8eopNOP;
466
 
467
                    end case;
468
 
469
                --
470
                -- IOT 6xx3: DLAG - Disk Load Address and Go
471
                --
472
 
473
                when opDLAG =>
474
                    dev.ack  <= '1';
475
                    dev.devc <= devWRCLR;
476
                    rk8eOP   <= rk8eopDLAG;
477
 
478
                --
479
                -- IOT 6xx4: DLCA - Disk Load Current Address
480
                --
481
 
482
                when opDLCA =>
483
                    dev.ack  <= '1';
484
                    dev.devc <= devWRCLR;
485
                    rk8eOP   <= rk8eopDLCA;
486
 
487
                --
488
                -- IOT 6xx5: DRST - Disk Read STatus
489
                --
490
 
491
                when opDRST =>
492
                    dev.ack  <= '1';
493
                    dev.devc <= devRDCLR;
494
                    dev.data <= rkst;
495
                    rk8eOP   <= rk8eopNOP;
496
 
497
                --
498
                -- IOT 6xx6: DLDC - Disk Load Disk Command
499
                --
500
 
501
                when opDLDC =>
502
                    dev.ack  <= '1';
503
                    dev.devc <= devWRCLR;
504
                    rk8eOP   <= rk8eopDLDC;
505
 
506
                --
507
                -- IOT 6xx7: DMAN - Maintenance Instruction
508
                --
509
 
510
                when opDMAN =>
511
                    dev.ack <= '1';
512
                    rk8eOP  <= rk8eopDMAN;
513
                    if cpu.buss.data(7) = '1' then
514
                        dev.devc <= devRDCLR;
515
                        dev.data <= o"5555";
516
                    else
517
                        dev.devc <= devWRCLR;
518
                    end if;
519
 
520
                --
521
                -- Everthing else
522
                --
523
 
524
                when others =>
525
                    rk8eOP <= rk8eopNOP;
526
 
527
            end case;
528
 
529
        --
530
        -- DMA Operation
531
        --
532
 
533
        else
534
 
535
            if dmaWR = '1' then
536
                dev.data(0 to 11) <= dmaDOUT;
537
            end if;
538
 
539
        end if;
540
 
541
        dev.dma.rd     <= dmaRD;
542
        dev.dma.wr     <= dmaWR;
543
        dev.dma.req    <= dmaREQ;
544
        dev.dma.memsel <= dmaRD or dmaWR;
545
        dev.dma.lxmar  <= dmaRD or dmaWR;
546
        dev.dma.lxpar  <= '0';
547
        dev.dma.addr   <= dmaADDR;
548
        dev.dma.eaddr  <= rkcmEMA;
549
 
550
    end process RK8E_BUSINTF;
551
 
552
    --
553
    --! RK8E Register Set and State Machine
554
    --!
555
    --! \details
556
    --!     The various rk8eOPs that were decoded by the Bus Interface
557
    --!     are dispatched and handled by this state machine.
558
 
559
    RK8E_REGS : process(sys)
560
 
561
    begin
562
 
563
        if sys.rst = '1' then
564
            rkcm           <= (others => '0');
565
            rkma           <= (others => '0');
566
            rkda           <= (others => '0');
567
            shiftCNT       <= (others => '0');
568
            maintMODE      <= '0';
569
            shiftEN        <= '0';
570
            skipFLAG       <= '0';
571
            bitopDONE      <= bitopCLR;
572
            bitopMOT       <= bitopCLR;
573
            bitopFNR       <= bitopCLR;
574
            bitopBUSY      <= bitopCLR;
575
            bitopTME       <= bitopCLR;
576
            bitopWLE       <= bitopCLR;
577
            bitopSTE       <= bitopCLR;
578
            rk05OP(DRIVE0) <= rk05opCLR;
579
            rk05OP(DRIVE1) <= rk05opCLR;
580
            rk05OP(DRIVE2) <= rk05opCLR;
581
            rk05OP(DRIVE3) <= rk05opCLR;
582
            rk05BUSY       <= DRIVENULL;
583
 
584
        elsif rising_edge(sys.clk) then
585
 
586
            bitopDONE      <= bitopNOP;
587
            bitopMOT       <= bitopNOP;
588
            bitopFNR       <= bitopNOP;
589
            bitopBUSY      <= bitopNOP;
590
            bitopTME       <= bitopNOP;
591
            bitopWLE       <= bitopNOP;
592
            bitopSTE       <= bitopNOP;
593
            rk05OP(DRIVE0) <= rk05opNOP;
594
            rk05OP(DRIVE1) <= rk05opNOP;
595
            rk05OP(DRIVE2) <= rk05opNOP;
596
            rk05OP(DRIVE3) <= rk05opNOP;
597
 
598
            if cpu.buss.ioclr = '1' then
599
 
600
                rkcm           <= (others => '0');
601
                rkma           <= (others => '0');
602
                rkda           <= (others => '0');
603
                shiftCNT       <= (others => '0');
604
                maintMODE      <= '0';
605
                shiftEN        <= '0';
606
                skipFLAG       <= '0';
607
                bitopDONE      <= bitopCLR;
608
                bitopMOT       <= bitopCLR;
609
                bitopFNR       <= bitopCLR;
610
                bitopBUSY      <= bitopCLR;
611
                bitopTME       <= bitopCLR;
612
                bitopWLE       <= bitopCLR;
613
                bitopSTE       <= bitopCLR;
614
                rk05OP(DRIVE0) <= rk05opCLR;
615
                rk05OP(DRIVE1) <= rk05opCLR;
616
                rk05OP(DRIVE2) <= rk05opCLR;
617
                rk05OP(DRIVE3) <= rk05opCLR;
618
                rk05BUSY       <= DRIVENULL;
619
 
620
            else
621
 
622
                case rk8eOP is
623
 
624
                    --
625
                    -- Nothing to do
626
                    --
627
 
628
                    when rk8eopNOP =>
629
                        null;
630
 
631
                    --
632
                    -- DCLS: Disk Clear Status - Clear AC and Status Register
633
                    --
634
 
635
                    when rk8eopDCLS =>
636
                        skipFLAG  <= '0';
637
                        bitopDONE <= bitopCLR;
638
                        bitopMOT  <= bitopCLR;
639
                        bitopFNR  <= bitopCLR;
640
                        bitopBUSY <= bitopCLR;
641
                        bitopTME  <= bitopCLR;
642
                        bitopWLE  <= bitopCLR;
643
                        bitopSTE  <= bitopCLR;
644
 
645
                        if simh = '1' then
646
                            if isBUSY(rk05BUSY) then
647
                                bitopBUSY <= bitopSET;
648
                            end if;
649
                        else
650
                            if rk05STAT(driveSelect).mounted = '0' then
651
                                bitopMOT <= bitopSET;
652
                                bitopFNR <= bitopSET;
653
                            end if;
654
                            if rk05STAT(driveSelect).recal = '1' then
655
                                bitopBUSY <= bitopSET;
656
                                bitopSTE  <= bitopSET;
657
                                skipFLAG  <= '1';
658
                            end if;
659
                        end if;
660
 
661
                    --
662
                    -- DCLC: Disk Clear Control - Clear AC, Control, and Major Registers
663
                    --
664
 
665
                    when rk8eopDCLC =>
666
                        skipFLAG       <= '0';
667
                        rkcm           <= (others => '0');
668
                        rkma           <= (others => '0');
669
                        rkda           <= (others => '0');
670
                        shiftCNT       <= (others => '0');
671
                        maintMODE      <= '0';
672
                        shiftEN        <= '0';
673
                        bitopDONE      <= bitopCLR;
674
                        bitopMOT       <= bitopCLR;
675
                        bitopFNR       <= bitopCLR;
676
                        bitopBUSY      <= bitopCLR;
677
                        bitopTME       <= bitopCLR;
678
                        bitopWLE       <= bitopCLR;
679
                        bitopSTE       <= bitopCLR;
680
                        rk05OP(DRIVE0) <= rk05opCLR;
681
                        rk05OP(DRIVE1) <= rk05opCLR;
682
                        rk05OP(DRIVE2) <= rk05opCLR;
683
                        rk05OP(DRIVE3) <= rk05opCLR;
684
                        rk05BUSY       <= DRIVENULL;
685
 
686
                        if simh = '0' then
687
                            if rk05STAT(DRIVE0).mounted = '0' then
688
                                bitopMOT <= bitopSET;
689
                                bitopFNR <= bitopSET;
690
                            end if;
691
                        end if;
692
 
693
                    --
694
                    -- DCLD: Disk Clear Drive - Clear AC, recalibrate selected
695
                    -- drive to track 0, and clear Status Register.
696
                    --
697
 
698
                    when rk8eopDCLD =>
699
                        bitopDONE <= bitopCLR;
700
                        bitopMOT  <= bitopCLR;
701
                        bitopFNR  <= bitopCLR;
702
                        bitopBUSY <= bitopCLR;
703
                        bitopTME  <= bitopCLR;
704
                        bitopWLE  <= bitopCLR;
705
                        bitopSTE  <= bitopCLR;
706
 
707
                        if simh = '1' then
708
                            if isBUSY(rk05BUSY) then
709
                                bitopBUSY <= bitopSET;
710
                            else
711
                                if rk05STAT(driveSelect).mounted = '0' then
712
                                    bitopDONE <= bitopSET;
713
                                    bitopFNR  <= bitopSET;
714
                                    bitopSTE  <= bitopSET;
715
                                    skipFLAG  <= '1';
716
                                elsif isBUSY(rk05BUSY) then
717
                                    bitopDONE <= bitopSET;
718
                                    bitopSTE  <= bitopSET;
719
                                    skipFLAG  <= '1';
720
                                else
721
                                    bitopDONE <= bitopSET;
722
                                    skipFLAG  <= '1';
723
                                    rk05OP(driveSelect) <= rk05opRECAL;
724
                                 end if;
725
                            end if;
726
                        else
727
                            if rk05STAT(driveSelect).mounted = '0' then
728
                                bitopMOT <= bitopSET;
729
                                bitopFNR <= bitopSET;
730
                                bitopSTE <= bitopSET;
731
                                if rk05STAT(driveSelect).recal = '1' then
732
                                    bitopBUSY <= bitopSET;
733
                                end if;
734
                                if maintMODE = '0' then
735
                                    skipFLAG  <= '1';
736
                                end if;
737
                            else
738
                                rk05OP(driveSelect) <= rk05opRECAL;
739
                                bitopDONE <= bitopSET;
740
                                skipFLAG  <= '1';
741
                            end if;
742
 
743
                        end if;
744
 
745
                    --
746
                    -- DLAG: Disk Load and Go.  If the disk is not already busy,
747
                    -- the contents of AC are loaded into the Disk Address
748
                    -- Register.  Run the command from the command register.
749
                    --
750
 
751
                    when rk8eopDLAG =>
752
 
753
                        if simh = '1' then
754
                            if isBUSY(rk05BUSY) then
755
                                bitopBUSY <= bitopSET;
756
                            else
757
                                rkda <= cpu.buss.data;
758
                                if rk05STAT(driveSelect).mounted = '0' then
759
                                    bitopDONE <= bitopSET;
760
                                    bitopFNR  <= bitopSET;
761
                                    bitopSTE  <= bitopSET;
762
                                    skipFLAG  <= '1';
763
                                elsif rk05STAT(driveSelect).state = rk05stBUSY then
764
                                    bitopDONE <= bitopSET;
765
                                    bitopSTE  <= bitopSET;
766
                                    skipFLAG  <= '1';
767
                                elsif unsigned(rkcmCYL0 & cpu.buss.data(0 to 6)) > 202 then
768
                                    bitopDONE <= bitopSET;
769
                                    bitopSTE  <= bitopSET;
770
                                    skipFLAG  <= '1';
771
                                else
772
                                    case rkcmFUN is
773
 
774
                                        --
775
                                        -- Write Protect Command
776
                                        --
777
 
778
                                        when funWRPROT =>
779
                                            bitopDONE <= bitopSET;
780
                                            skipFLAG  <= '1';
781
                                            rk05OP(driveSelect) <= rk05opWRPROT;
782
 
783
                                        --
784
                                        -- Seek Command
785
                                        --
786
 
787
                                        when funSEEK =>
788
                                            bitopDONE <= bitopSET;
789
                                            bitopMOT  <= bitopSET;
790
                                            skipFLAG  <= '1';
791
                                            rk05OP(driveSelect) <= rk05opSEEK;
792
 
793
                                        --
794
                                        -- Read Command
795
                                        --
796
 
797
                                        when funREAD | funREADALL =>
798
                                            bitopBUSY <= bitopSET;
799
                                            bitopMOT  <= bitopSET;
800
                                            rk05BUSY  <= driveSelect;
801
                                            rk05OP(driveSelect) <= rk05opREAD;
802
 
803
                                        --
804
                                        -- Write Command
805
                                        --
806
 
807
                                        when funWRITE | funWRITEALL =>
808
                                            if rk05STAT(driveSelect).WRINH = '1' then
809
                                                bitopDONE <= bitopSET;
810
                                                bitopMOT  <= bitopSET;
811
                                                bitopWLE  <= bitopSET;
812
                                                skipFLAG  <= '1';
813
                                            else
814
                                                bitopBUSY <= bitopSET;
815
                                                bitopMOT  <= bitopSET;
816
                                                rk05BUSY  <= driveSelect;
817
                                                rk05OP(driveSelect) <= rk05opWRITE;
818
                                            end if;
819
 
820
                                        --
821
                                        -- Functions 6 and 7 are unused.
822
                                        --
823
 
824
                                        when others =>
825
                                            bitopDONE <= bitopSET;
826
                                            bitopTME  <= bitopSET;
827
                                            skipFLAG  <= '1';
828
 
829
                                    end case;
830
                                end if;
831
                            end if; --! BUSY
832
                        else -- !SIMH
833
                            if ((rk05STAT(driveSelect).recal = '0' and rk05STAT(driveSelect).WRINH = '0') or
834
                                (rk05STAT(driveSelect).recal = '0' and maintMODE = '1')) then
835
                                rkda <= cpu.buss.data;
836
                            end if;
837
                            if rk05STAT(driveSelect).mounted = '0' then
838
                                bitopMOT <= bitopSET;
839
                                bitopFNR <= bitopSET;
840
                                bitopSTE <= bitopSET;
841
                                skipFLAG <= '1';
842
                            else
843
                                null;
844
                            end if;
845
                        end if;
846
 
847
                    --
848
                    -- DLCA: Disk Load Current Address.  If the disk is not already
849
                    -- busy, the contents of AC are loaded into the Current Address
850
                    -- Register.
851
                    --
852
 
853
                    when rk8eopDLCA =>
854
 
855
                        if simh = '1' then
856
                            if isBUSY(rk05BUSY) then
857
                                bitopBUSY <= bitopSET;
858
                            else
859
                                rkma <= cpu.buss.data;
860
                            end if;
861
                        else
862
                            rkma <= cpu.buss.data;
863
                            if rk05STAT(driveSelect).recal = '1' then
864
                                bitopBUSY <= bitopSET;
865
                                skipFLAG <= '1';
866
                            end if;
867
                        end if;
868
 
869
                    --
870
                    -- DLDC: Load Command - The content of the AC is loaded
871
                    -- into the disk command register.  The AC and the Status
872
                    -- Register are cleared.
873
                    --
874
 
875
                    when rk8eopDLDC =>
876
                        bitopDONE <= bitopCLR;
877
                        bitopMOT  <= bitopCLR;
878
                        bitopFNR  <= bitopCLR;
879
                        bitopBUSY <= bitopCLR;
880
                        bitopTME  <= bitopCLR;
881
                        bitopWLE  <= bitopCLR;
882
                        bitopSTE  <= bitopCLR;
883
                        skipFLAG  <= '0';
884
 
885
                        if simh = '1' then
886
                            if isBUSY(rk05BUSY) then
887
                               bitopBUSY <= bitopSET;
888
                             else
889
                                rkcm <= cpu.buss.data;
890
                            end if;
891
                        else
892
                            if maintMODE = '0' or rk05STAT(driveSelect).recal = '0' then
893
                                rkcm <= cpu.buss.data;
894
                            end if;
895
                            if rk05STAT(driveSelect).mounted = '1' then
896
                                if isBUSY(rk05BUSY) then
897
                                    bitopMOT <= bitopSET;
898
                                end if;
899
                            else
900
                                bitopMOT <= bitopSET;
901
                                bitopFNR <= bitopSET;
902
                                if rk05STAT(driveSelect).recal = '1' then
903
                                    bitopBUSY <= bitopSET;
904
                                    bitopSTE  <= bitopSET;
905
                                    skipFLAG  <= '1';
906
                                end if;
907
                            end if;
908
                        end if;
909
 
910
                    --
911
                    -- DMAN: Disk Maintenance Mode - AC(0) Enables maintence mode.
912
                    --
913
 
914
                    when rk8eopDMAN =>
915
                        maintMODE <= cpu.buss.data(0);
916
                        shiftEN   <= '0';
917
                        shiftCNT  <= "0000";
918
                        if maintMODE = '1' then
919
 
920
                            --
921
                            -- Enable shift to data buffer (DB4)
922
                            --
923
 
924
                            if cpu.buss.data(1) = '1' then
925
 
926
                            --
927
                            --
928
                            --
929
 
930
                            elsif cpu.buss.data(2) = '1' then
931
 
932
                            elsif cpu.buss.data(3) = '1' then
933
 
934
 
935
 
936
                            end if;
937
                        end if;
938
 
939
                    --
940
                    -- Everthing else
941
                    --
942
 
943
                    when others =>
944
                        null;
945
 
946
                end case;
947
 
948
                --
949
                -- Handle RK05 completion events
950
                --
951
 
952
                sdOP <= sdopNOP;
953
                if isBUSY(rk05BUSY) then
954
 
955
                    if rk05STAT(rk05BUSY).state = rk05stDONE then
956
                        bitopMOT <= bitopCLR;
957
                        case rk05STAT(rk05BUSY).sdOP is
958
 
959
                            --
960
                            -- sdopNOP
961
                            --  This is asserted on a SEEK or RECALIBRATE completion.
962
                            --
963
 
964
                            when sdopNOP =>
965
                                if rkcmDOSD = '1' then
966
                                    bitopDONE <= bitopSET;
967
                                end if;
968
 
969
                            --
970
                            -- sdopABORT
971
                            --  This is asserted on a DCLC command
972
                            --
973
 
974
                            when sdopABORT =>
975
                                sdOP <= sdopABORT;
976
 
977
                            --
978
                            -- sdopRD
979
                            --
980
 
981
                            when sdopRD =>
982
                                if rk05STAT(rk05BUSY).mounted = '0' then
983
                                    bitopDONE <= bitopSET;
984
                                    bitopSTE  <= bitopSET;
985
                                    rk05BUSY  <= DRIVENULL;
986
                                else
987
                                    sdOP       <= rk05STAT(rk05BUSY).sdOP;
988
                                    sdLEN      <= rk05STAT(rk05BUSY).sdLEN;
989
                                    sdMEMaddr  <= rk05STAT(rk05BUSY).sdMEMaddr;
990
                                    sdDISKaddr <= rk05STAT(rk05BUSY).sdDISKaddr;
991
                                end if;
992
 
993
                            --
994
                            -- sdopWR
995
                            --
996
 
997
                            when sdopWR =>
998
                                if rk05STAT(rk05BUSY).mounted = '0' then
999
                                    bitopDONE <= bitopSET;
1000
                                    bitopSTE  <= bitopSET;
1001
                                    rk05BUSY  <= DRIVENULL;
1002
                                elsif rk05STAT(driveSelect).WRINH = '1' then
1003
                                    bitopWLE  <= bitopSET;
1004
                                    bitopDONE <= bitopSET;
1005
                                    rk05BUSY  <= DRIVENULL;
1006
                                else
1007
                                    sdOP       <= rk05STAT(rk05BUSY).sdOP;
1008
                                    sdLEN      <= rk05STAT(rk05BUSY).sdLEN;
1009
                                    sdMEMaddr  <= rk05STAT(rk05BUSY).sdMEMaddr;
1010
                                    sdDISKaddr <= rk05STAT(rk05BUSY).sdDISKaddr;
1011
                                end if;
1012
 
1013
                            --
1014
                            -- Anything else
1015
                            --
1016
 
1017
                            when others =>
1018
                                null;
1019
                        end case;
1020
                    end if;
1021
                end if;
1022
 
1023
                --
1024
                -- Handle SD completion events
1025
                --
1026
 
1027
                if sdSTAT.state = sdstateDONE then
1028
                    bitopDONE <= bitopSET;
1029
                    bitopBUSY <= bitopCLR;
1030
                    skipFLAG  <= '1';
1031
                    rk05BUSY  <= DRIVENULL;
1032
                    rkma      <= dmaADDR;
1033
                end if;
1034
 
1035
            end if;
1036
        end if;
1037
 
1038
    end process RK8E_REGS;
1039
 
1040
    --
1041
    --! RK8E Status Register
1042
    --
1043
 
1044
    RK8E_STATUS : process(sys)
1045
    begin
1046
        if sys.rst = '1' then
1047
 
1048
            rkstDONE <= '0';
1049
            rkstMOT  <= '0';
1050
            rkstFNR  <= '0';
1051
            rkstBUSY <= '0';
1052
            rkstTME  <= '0';
1053
            rkstWLE  <= '0';
1054
            rkstSTE  <= '0';
1055
 
1056
        elsif rising_edge(sys.clk) then
1057
 
1058
            if cpu.buss.ioclr = '1' then
1059
 
1060
                rkstDONE <= '0';
1061
                rkstMOT  <= '0';
1062
                rkstFNR  <= '0';
1063
                rkstBUSY <= '0';
1064
                rkstTME  <= '0';
1065
                rkstWLE  <= '0';
1066
                rkstSTE  <= '0';
1067
 
1068
            else
1069
 
1070
                case bitopDONE is
1071
                    when bitopSET => rkstDONE <= '1';
1072
                    when bitopCLR => rkstDONE <= '0';
1073
                    when others   => null;
1074
                end case;
1075
                case bitopMOT is
1076
                    when bitopSET => rkstMOT <= '1';
1077
                    when bitopCLR => rkstMOT <= '0';
1078
                    when others   => null;
1079
                end case;
1080
                case bitopFNR is
1081
                    when bitopSET => rkstFNR <= '1';
1082
                    when bitopCLR => rkstFNR <= '0';
1083
                    when others   => null;
1084
                end case;
1085
                case bitopBUSY is
1086
                    when bitopSET => rkstBUSY <= '1';
1087
                    when bitopCLR => rkstBUSY <= '0';
1088
                    when others   => null;
1089
                end case;
1090
                case bitopTME  is
1091
                    when bitopSET => rkstTME <= '1';
1092
                    when bitopCLR => rkstTME <= '0';
1093
                    when others   => null;
1094
                end case;
1095
                case bitopWLE  is
1096
                    when bitopSET => rkstWLE <= '1';
1097
                    when bitopCLR => rkstWLE <= '0';
1098
                    when others   => null;
1099
                end case;
1100
                case bitopSTE is
1101
                    when bitopSET => rkstSTE <= '1';
1102
                    when bitopCLR => rkstSTE <= '0';
1103
                    when others   => null;
1104
                end case;
1105
            end if;
1106
        end if;
1107
    end process RK8E_STATUS;
1108
 
1109
    --
1110
    -- Status Register
1111
    --
1112
 
1113
    rkst <= rkstDONE & rkstMOT & '0' & '0' & rkstFNR  & rkstBUSY &
1114
            rkstTME  & rkstWLE & '0' & '0' & rkstSTE  & '0';
1115
 
1116
    --
1117
    --! RK05 Device #0
1118
    --
1119
 
1120
    iRK05_0 : entity work.eRK05 (rtl) port map (
1121
        sys         => sys,
1122
        ioclr       => cpu.buss.ioclr,
1123
        simtime     => simtime,
1124
        sdWP        => sdWP,
1125
        sdCD        => sdCD,
1126
        sdFAIL      => sdFAIL,
1127
        rk05INH     => rk05INH(DRIVE0),
1128
        rk05MNT     => rk05MNT(DRIVE0),
1129
        rk05OP      => rk05OP(DRIVE0),
1130
        rk05CYL     => rk05CYL,
1131
        rk05HEAD    => rkdaHEAD,
1132
        rk05SECT    => rkdaSECT,
1133
        rk05DRIVE   => "00",
1134
        rk05LEN     => rkcmLEN,
1135
        rk05MEMaddr => rkma,
1136
        rk05STAT    => rk05STAT(DRIVE0)
1137
    );
1138
 
1139
    --
1140
    --! RK05 Device #1
1141
    --
1142
 
1143
    iRK05_1 : entity work.eRK05 (rtl) port map (
1144
        sys         => sys,
1145
        ioclr       => cpu.buss.ioclr,
1146
        simtime     => simtime,
1147
        sdWP        => sdWP,
1148
        sdCD        => sdCD,
1149
        sdFAIL      => sdFAIL,
1150
        rk05INH     => rk05INH(DRIVE1),
1151
        rk05MNT     => rk05MNT(DRIVE1),
1152
        rk05OP      => rk05OP(DRIVE1),
1153
        rk05CYL     => rk05CYL,
1154
        rk05HEAD    => rkdaHEAD,
1155
        rk05SECT    => rkdaSECT,
1156
        rk05DRIVE   => "01",
1157
        rk05LEN     => rkcmLEN,
1158
        rk05MEMaddr => rkma,
1159
        rk05STAT    => rk05STAT(DRIVE1)
1160
    );
1161
 
1162
    --
1163
    --! RK05 Device #2
1164
    --
1165
 
1166
    iRK05_2 : entity work.eRK05 (rtl) port map (
1167
        sys         => sys,
1168
        ioclr       => cpu.buss.ioclr,
1169
        simtime     => simtime,
1170
        sdWP        => sdWP,
1171
        sdCD        => sdCD,
1172
        sdFAIL      => sdFAIL,
1173
        rk05INH     => rk05INH(DRIVE2),
1174
        rk05MNT     => rk05MNT(DRIVE2),
1175
        rk05OP      => rk05OP(DRIVE2),
1176
        rk05CYL     => rk05CYL,
1177
        rk05HEAD    => rkdaHEAD,
1178
        rk05SECT    => rkdaSECT,
1179
        rk05DRIVE   => "10",
1180
        rk05LEN     => rkcmLEN,
1181
        rk05MEMaddr => rkma,
1182
        rk05STAT    => rk05STAT(DRIVE2)
1183
    );
1184
 
1185
    --
1186
    --! RK05 Device #3
1187
    --
1188
 
1189
    iRK05_3 : entity work.eRK05 (rtl) port map (
1190
        sys         => sys,
1191
        ioclr       => cpu.buss.ioclr,
1192
        simtime     => simtime,
1193
        sdWP        => sdWP,
1194
        sdCD        => sdCD,
1195
        sdFAIL      => sdFAIL,
1196
        rk05INH     => rk05INH(DRIVE3),
1197
        rk05MNT     => rk05MNT(DRIVE3),
1198
        rk05OP      => rk05OP(DRIVE3),
1199
        rk05CYL     => rk05CYL,
1200
        rk05HEAD    => rkdaHEAD,
1201
        rk05SECT    => rkdaSECT,
1202
        rk05DRIVE   => "11",
1203
        rk05LEN     => rkcmLEN,
1204
        rk05MEMaddr => rkma,
1205
        rk05STAT    => rk05STAT(DRIVE3)
1206
    );
1207
 
1208
    --
1209
    --! Secure Digital Interface
1210
    --
1211
 
1212
    iSD : entity work.eSD (rtl) port map (
1213
        sys        => sys,
1214
        ioclr      => cpu.buss.ioclr,
1215
        -- PDP8 Interface
1216
        dmaDIN     => cpu.buss.data,
1217
        dmaDOUT    => dmaDOUT,
1218
        dmaADDR    => dmaADDR,
1219
        dmaRD      => dmaRD,
1220
        dmaWR      => dmaWR,
1221
        dmaREQ     => dmaREQ,
1222
        dmaGNT     => cpu.buss.dmagnt,
1223
        -- Interface to SD Hardware
1224
        sdMISO     => sdMISO,
1225
        sdMOSI     => sdMOSI,
1226
        sdSCLK     => sdSCLK,
1227
        sdCS       => sdCS,
1228
        -- Interface to SD Controller
1229
        sdOP       => sdOP,
1230
        sdDISKaddr => sdDISKaddr,
1231
        sdMEMaddr  => sdMEMaddr,
1232
        sdLEN      => sdLEN,
1233
        sdSTAT     => sdSTAT
1234
    );
1235
 
1236
    rk8eSTAT.sdCD     <= sdCD;
1237
    rk8eSTAT.sdWP     <= sdWP;
1238
    rk8eSTAT.sdSTAT   <= sdSTAT;
1239
    rk8eSTAT.rk05STAT <= rk05STAT;
1240
 
1241
end rtl;

powered by: WebSVN 2.1.0

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