From a6bbfac2c118ecc5caa1ca6557844133ed2d0d3c Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Fri, 31 Dec 2021 11:23:32 -0500 Subject: [PATCH] KA10: Removed unused files. --- PDP10/ks10_rh.c | 390 --------------- PDP10/ks10_rp.c | 1266 ----------------------------------------------- PDP10/ks10_tu.c | 1113 ----------------------------------------- 3 files changed, 2769 deletions(-) delete mode 100644 PDP10/ks10_rh.c delete mode 100644 PDP10/ks10_rp.c delete mode 100644 PDP10/ks10_tu.c diff --git a/PDP10/ks10_rh.c b/PDP10/ks10_rh.c deleted file mode 100644 index 1425b8e..0000000 --- a/PDP10/ks10_rh.c +++ /dev/null @@ -1,390 +0,0 @@ -/* ks10_rh.c: RH11/RH20 interace routines. - - Copyright (c) 2019-2020, Richard Cornwell - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include "kx10_defs.h" - - - -#if (NUM_DEVS_RP > 0) -#define CS1_GO 1 /* go */ -#define CS1_V_FNC 1 /* function pos */ -#define CS1_M_FNC 037 /* function mask */ -#define CS1_FNC (CS1_M_FNC << CS1_V_FNC) -#define FNC_NOP 000 /* no operation */ -#define FNC_UNLOAD 001 /* unload */ -#define FNC_SEEK 002 /* seek */ -#define FNC_RECAL 003 /* recalibrate */ -#define FNC_DCLR 004 /* drive clear */ -#define FNC_RELEASE 005 /* port release */ -#define FNC_OFFSET 006 /* offset */ -#define FNC_RETURN 007 /* return to center */ -#define FNC_PRESET 010 /* read-in preset */ -#define FNC_PACK 011 /* pack acknowledge */ -#define FNC_SEARCH 014 /* search */ -#define FNC_XFER 024 /* >=? data xfr */ -#define FNC_WCHK 024 /* write check */ -#define FNC_WCHKH 025 /* write check headers */ -#define FNC_WRITE 030 /* write */ -#define FNC_WRITEH 031 /* write w/ headers */ -#define FNC_READ 034 /* read */ -#define FNC_READH 035 /* read w/ headers */ -#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC) -#define CS1_IE 0000100 /* Enable interrupts */ -#define CS1_RDY 0000200 /* Drive ready */ -#define CS1_UBA 0001400 /* High order UBA bits */ -#define CS1_PSEL 0002000 /* */ -#define CS1_DVA 0004000 /* drive avail */ -#define CS1_MCPE 0020000 /* */ -#define CS1_TRE 0040000 /* Set if CS2 0177400 */ -#define CS1_SC 0100000 /* Set if TRE or ATTN */ - -#define CS2_V_UNIT 0 /* unit pos */ -#define CS2_M_UNIT 07 /* unit mask */ -#define CS2_UNIT (CS2_M_UNIT << CS2_V_UNIT) -#define CS2_UAI 0000010 /* addr inhibit */ -#define CS2_PAT 0000020 /* parity test NI */ -#define CS2_CLR 0000040 /* controller clear */ -#define CS2_IR 0000100 /* input ready */ -#define CS2_OR 0000200 /* output ready */ -#define CS2_MDPE 0000400 /* Mbus par err NI */ -#define CS2_MXF 0001000 /* missed xfer NI */ -#define CS2_PGE 0002000 /* program err */ -#define CS2_NEM 0004000 /* nx mem err */ -#define CS2_NED 0010000 /* nx drive err */ -#define CS2_PE 0020000 /* parity err NI */ -#define CS2_WCE 0040000 /* write check err */ -#define CS2_DLT 0100000 /* data late NI */ - - -DIB rpa_dib = {0776700, 077, 0254, 6, 1, &rp_read, &rp_write, &rp_vect, 0}; - -int rh_map[] = { 0, -1, -1, 05, -1, 01, 02, 04, 07, -1, - 03, 06, 010, 011, 012, 013, 014, 015, 016, 017}; - - -int -rh_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) { - int i; - int r; - struct pdp_dib *dibp = (DIB *) dptr->ctxt; - struct rh_if *rhc; - int reg; - - if (dibp == NULL) - return 1; - rhc = dibp->rh11_if; - /* Check for parity error during access */ - if (rhc->cs2 & CS2_PAT) { - uba_set_parity(dibp->uba_ctl); - rhc->status |= ER1_PAR; - } - addr &= dibp->uba_mask; - reg = rh_map[addr >> 1]; - - if (access == BYTE && reg >= 0) { - rhc->dev_read(dptr, rhc, reg, &temp); - if (addr & 1) - data = data | (temp & 0377); - else - data = (temp & 0177600) | data; - } - - switch(addr) { - case 000: /* CS1 */ - if (access == BYTE && addr & 1) - break; - rhc->cs1 &= ~(CS1_IE); - rhc->cs1 |= data & (CS1_IE); - rhc->ba = ((data << 8) & 0600000) | (rhc->ba & 0177777); - /* Check if we had a go with a data transfer command */ - if (r == 0 && (data & CS1_GO) != 0 && GET_FNC(data) >= FNC_XFER) { - rhc->status |= BUSY; - } - r = rhc->dev_write(dptr, rh, 0, data); - break; - - case 002: /* RPWC - 176702 - word count */ /* 1 */ - if ((rhc->status & BUSY) != 0) { - rhc->status |= ER1_RMR; - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit, - addr & 077, data); - return 0; - } - if (access == BYTE) { - if (addr & 1) - data = data | (rhc->wc & 0377); - else - data = (rhc->wc & 0177600) | data; - } - rhc->wc = data; - break; - case 004: /* RPBA - 176704 - base address */ /* 2 */ - if ((rhc->status & BUSY) != 0) { - rhc->status |= ER1_RMR; - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit, - addr & 077, data); - return 0; - } - if (access == BYTE) { - if (addr & 1) - data = data | (rhc->ba & 0377); - else - data = (rhc->ba & 0177600) | data; - } - rhc->ba = (rhc->ba & 0600000) | (data & 0177776); - break; - - case 010: /* RPCS2 - 176710 - Control and Status register 2 */ /* 4 */ - if (access == BYTE) { - if (addr & 1) - data = data | (rhc->cs2 & 0377); - } - rhc->cs2 = ((CS2_DLT|CS2_WCE|CS2_NED|CS2_NEM|CS2_PGE|CS2_MDPE) & rp_cs2) | - ((CS2_UAI|CS2_PAT|CS2_UNIT) & data); - if (data & CS2_CLR) { - dptr->reset(dptr); - } - rhc->cs2 |= CS2_IR; - rhc->drive = data & 07; - break; - - case 014: /* RPER1 - 176714 - error status 1 */ /* 6 */ - rhc->status &= ~(07 & data); - return rh->dev_write(dptr, rh, 2, data); - - case 022: /* RPDB - 176722 - data buffer */ /* 11 */ - if ((rhc->cs2 & CS2_IR) == 0) { - rhc->cs2 |= CS2_DLT; - break; - } - rhc->dba = rhc->dbb; - rhc->dbb = data; - if (rhc->cs2 & CS2_IR) - rhc->dba = rhc->dbb; - rhc->cs2 |= CS2_OR; - rhc->cs2 &= ~CS2_IR; - break; - - default: - return rhc->dev_write(dptr, reg, 5, data); - - } - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o write %02o %06o\n", rp_unit, - addr & 076, data); - return 0; -} - -int -rh_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access) { - int i; - int r = 1; - struct pdp_dib *dibp = (DIB *) dptr->ctxt; - struct rh_if *rhc; - int reg; - - if (dibp == NULL) - return 1; - rhc = dibp->rh11_if; - addr &= dibp->uba_mask; - reg = rh_map[addr >> 1]; - - if (reg >= 0) - r = rhc->dev_read(dptr, rhc, reg, &temp); - - /* Check for parity error during access */ - if (rhc->cs2 & CS2_PAT) { - uba_set_parity(dibp->uba_ctl); - rhc->status |= ER1_PAR; - } - switch(addr) { - case 000: /* RPC - 176700 - control */ - temp |= (uint16)(rhc->cs1 & (CS1_IE)); - temp |= (rhc->ba & 0600000) >> 8; - if ((rhc->status & BUSY) == 0) - temp |= CS1_RDY; - if (rhc->cs2 & (CS2_MDPE|CS2_MXF|CS2_PGE|CS2_NEM|CS2_NED|CS2_PE|CS2_WCE|CS2_DLT)) - temp |= CS1_TRE|CS1_SC; - if (rhc->attn) - temp |= CS1_SC; - break; - case 002: /* RPWC - 176702 - word count */ - temp = rhc->wc; - r = 0; - break; - case 004: /* RPBA - 176704 - base address */ - temp = (uint16)(rhc->ba & 0177776); - r = 0; - break; - default: - break; - case 010: /* RPCS2 - 176710 - control/status 2 */ - temp = rp_cs2; - r = 0; - break; - case 014: /* RPER1 - 176714 - error status 1 */ - temp |= rhc->status & 07; - break; - case 022: /* RPDB - 176722 - data buffer */ - if ((rp_cs2 & CS2_OR) == 0) { - rp_cs2 |= CS2_DLT; - break; - } - temp = rp_dba; - rp_dba = rp_dbb; - rp_cs2 &= ~CS2_OR; - rp_cs2 |= CS2_IR; - break; - } - *data = temp; - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o read %02o %06o %06o\n", rp_unit, - addr & 076, temp, PC); - return r; -} - -uint16 -rp_vect(struct pdp_dib *dibp) -{ - return dibp->uba_vect; -} - -/* Set the attention flag for a unit */ -void rp_setattn(UNIT *uptr) -{ - uptr->STATUS |= DS_ATA; - uptr->CMD &= ~CS1_GO; - if ((rp_ie & CSX_BUSY) == 0 && (rp_ie & CS1_IE) != 0) - uba_set_irq(&rpa_dib); -} - - - - - -/* Handle KI and KL style interrupt vectors */ -t_addr -rh_devirq(uint32 dev, t_addr addr) { - struct rh_if *rhc = NULL; - int drive; - - for (drive = 0; rh[drive].dev_num != 0; drive++) { - if (rh[drive].dev_num == (dev & 0774)) { - rhc = rh[drive].rh; - break; - } - } - if (rhc != NULL) { - if (rhc->imode == 1) /* KI10 Style */ - addr = RSIGN | rhc->ivect; - else if (rhc->imode == 2) /* RH20 style */ - addr = rhc->ivect; - } else { - sim_printf("Unable to find device %03o\r\n", dev); - } - return addr; -} - -/* Set the attention flag for a unit */ -void rh_setattn(struct rh_if *rhc, int unit) -{ -#if KS - if ((rhc->status & BUSY) == 0 && (rhc->cs2 & CS1_IE) != 0) - uba_set_irq(rhc->dib); -#else - rhc->attn |= 1<status & BUSY) == 0 && (rhc->status & IADR_ATTN) != 0) - set_interrupt(rhc->devnum, rhc->status); -#endif -} - -void rh_error(struct rh_if *rhc) -{ -#if !KS - if (rhc->imode == 2) - rhc->status |= RH20_DR_EXC; -#endif -} - -/* Decrement block count for RH20, nop for RH10 */ -int rh_blkend(struct rh_if *rhc) -{ - return 0; -} - -/* Set an IRQ for a DF10 device */ -void rh_setirq(struct rh_if *rhc) { - rhc->status |= PI_ENABLE; -#if KS - uba_set_irq(rhc->dib); -#else - set_interrupt(rhc->devnum, rhc->status); -#endif -} - -/* Generate the DF10 complete word */ -void rh_writecw(struct rh_if *rhc, int nxm) { -} - -/* Finish off a DF10 transfer */ -void rh_finish_op(struct rh_if *rhc, int nxm) { - rhc->status &= ~BUSY; - rh_writecw(rhc, nxm); - rh_setirq(rhc); -} - - -/* Setup for a DF10 transfer */ -void rh_setup(struct rh_if *rhc, uint32 addr) -{ - rhc->status |= BUSY; -} - - -/* Fetch the next IO control word */ -int rh_fetch(struct rh_if *rhc) { - return 1; -} - -/* Read next word */ -int rh_read(struct rh_if *rhc) { - if (uba_read_npr(rhc->ba, rhc->ctl, &rhc->buf) == 0) - return 0; - if ((rhc->cs2 & CS2_UAI) == 0) - rhc->ba += 4; - rhc->wc (rhc->wc + 2) & 0177777; - if (rhc->wc == 0) - return 0; - return 1; -} - -/* Write next word */ -int rh_write(struct rh_if *rhc) { - if (uba_write_npr(rhc->ba, rhc->ctl, rhc->buf) == 0) - return 0; - if ((rhc->cs2 & CS2_UAI) == 0) - rhc->ba += 4; - rhc->wc (rhc->wc + 2) & 0177777; - if (rhc->wc == 0) - return 0; - return 1; -} - diff --git a/PDP10/ks10_rp.c b/PDP10/ks10_rp.c deleted file mode 100644 index f5e4f29..0000000 --- a/PDP10/ks10_rp.c +++ /dev/null @@ -1,1266 +0,0 @@ -/* ks10_rp.c: DEC Massbus RP04/5/6 - - Copyright (c) 2021, Richard Cornwell - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include "kx10_defs.h" -#include "kx10_disk.h" - -#ifndef NUM_DEVS_RP -#define NUM_DEVS_RP 0 -#endif - -#if (NUM_DEVS_RP > 0) -#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF) -#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF - -#define RP_NUMWD 128 /* 36bit words/sec */ -#define NUM_UNITS_RP 8 - -/* Flags in the unit flags word */ - -#define UNIT_V_DTYPE (UNIT_V_UF + 1) /* disk type */ -#define UNIT_M_DTYPE 7 -#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE) -#define DTYPE(x) (((x) & UNIT_M_DTYPE) << UNIT_V_DTYPE) -#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE) - -/* Parameters in the unit descriptor */ -#define CMD u3 -/* u3 low */ -/* RPC - 176700 - control */ - -#define CS1_GO 1 /* go */ -#define CS1_V_FNC 1 /* function pos */ -#define CS1_M_FNC 037 /* function mask */ -#define CS1_FNC (CS1_M_FNC << CS1_V_FNC) -#define FNC_NOP 000 /* no operation */ -#define FNC_UNLOAD 001 /* unload */ -#define FNC_SEEK 002 /* seek */ -#define FNC_RECAL 003 /* recalibrate */ -#define FNC_DCLR 004 /* drive clear */ -#define FNC_RELEASE 005 /* port release */ -#define FNC_OFFSET 006 /* offset */ -#define FNC_RETURN 007 /* return to center */ -#define FNC_PRESET 010 /* read-in preset */ -#define FNC_PACK 011 /* pack acknowledge */ -#define FNC_SEARCH 014 /* search */ -#define FNC_XFER 024 /* >=? data xfr */ -#define FNC_WCHK 024 /* write check */ -#define FNC_WCHKH 025 /* write check headers */ -#define FNC_WRITE 030 /* write */ -#define FNC_WRITEH 031 /* write w/ headers */ -#define FNC_READ 034 /* read */ -#define FNC_READH 035 /* read w/ headers */ -#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC) -#define CS1_IE 0000100 /* Enable interrupts */ -#define CS1_RDY 0000200 /* Drive ready */ -#define CS1_UBA 0001400 /* High order UBA bits */ -#define CS1_PSEL 0002000 /* */ -#define CS1_DVA 0004000 /* drive avail */ -#define CS1_MCPE 0020000 /* */ -#define CS1_TRE 0040000 /* Set if CS2 0177400 */ -#define CS1_SC 0100000 /* Set if TRE or ATTN */ - -#define CSX_BUSY 02 /* RH11 is doing a transfer */ - - -/* RPWC - 176702 - word count */ - -/* RPBA - 176704 - base address */ - -#define DA u4 -/* u4 high */ -/* RPDC - 176706 - desired sector */ - -#define DA_V_SC 16 /* sector pos */ -#define DA_M_SC 077 /* sector mask */ -#define DA_V_SF 24 /* track pos */ -#define DA_M_SF 077 /* track mask */ -#define DA_MBZ 0140300 -#define GET_SC(x) (((x) >> DA_V_SC) & DA_M_SC) -#define GET_SF(x) (((x) >> DA_V_SF) & DA_M_SF) - -/* RPCS2 - 176710 - control/status 2 */ - -#define CS2_V_UNIT 0 /* unit pos */ -#define CS2_M_UNIT 07 /* unit mask */ -#define CS2_UNIT (CS2_M_UNIT << CS2_V_UNIT) -#define CS2_UAI 0000010 /* addr inhibit */ -#define CS2_PAT 0000020 /* parity test NI */ -#define CS2_CLR 0000040 /* controller clear */ -#define CS2_IR 0000100 /* input ready */ -#define CS2_OR 0000200 /* output ready */ -#define CS2_MDPE 0000400 /* Mbus par err NI */ -#define CS2_MXF 0001000 /* missed xfer NI */ -#define CS2_PGE 0002000 /* program err */ -#define CS2_NEM 0004000 /* nx mem err */ -#define CS2_NED 0010000 /* nx drive err */ -#define CS2_PE 0020000 /* parity err NI */ -#define CS2_WCE 0040000 /* write check err */ -#define CS2_DLT 0100000 /* data late NI */ - -/* RPDS - 176712 - drive status */ -#define STATUS us10 - -#define DS_DF5 0000001 /* Drive forward 5in/sec */ -#define DS_DF20 0000002 /* Drive forward 20in/sec */ -#define DS_DIGB 0000004 /* Drive inner gaurd band */ -#define DS_GRV 0000010 /* Go reverse read */ -#define DS_DL64 0000020 /* Difference less 64 */ -#define DS_DE1 0000040 /* Difference equal 1 */ -#define DS_VV 0000100 /* volume valid */ -#define DS_DRY 0000200 /* drive ready */ -#define DS_DPR 0000400 /* drive present */ -#define DS_PGM 0001000 /* programable NI */ -#define DS_LST 0002000 /* last sector */ -#define DS_WRL 0004000 /* write locked */ -#define DS_MOL 0010000 /* medium online */ -#define DS_PIP 0020000 /* pos in progress */ -#define DS_ERR 0040000 /* error */ -#define DS_ATA 0100000 /* attention active */ - -/* u3 high */ -/* RPER1 - 176714 - error status 1 */ - -#define ER1_ILF 0000001 /* illegal func */ -#define ER1_ILR 0000002 /* illegal register */ -#define ER1_RMR 0000004 /* reg mod refused */ -#define ER1_PAR 0000010 /* parity err */ -#define ER1_FER 0000020 /* format err NI */ -#define ER1_WCF 0000040 /* write clk fail NI */ -#define ER1_ECH 0000100 /* ECC hard err NI */ -#define ER1_HCE 0000200 /* hdr comp err NI */ -#define ER1_HCR 0000400 /* hdr CRC err NI */ -#define ER1_AOE 0001000 /* addr ovflo err */ -#define ER1_IAE 0002000 /* invalid addr err */ -#define ER1_WLE 0004000 /* write lock err */ -#define ER1_DTE 0010000 /* drive time err NI */ -#define ER1_OPI 0020000 /* op incomplete */ -#define ER1_UNS 0040000 /* drive unsafe */ -#define ER1_DCK 0100000 /* data check NI */ - -/* RPAS - 176716 - attention summary */ - -#define AS_U0 0000001 /* unit 0 flag */ - -/* RPLA - 176720 - look ahead register */ -#define LA_REG u6 -#define LA_V_SC 6 /* sector pos */ - -/* RPDB - 176722 - data buffer */ - -#define OF_HCI 0002000 /* hdr cmp inh NI */ -#define OF_ECI 0004000 /* ECC inhibit NI */ -#define OF_F22 0010000 /* format NI */ -#define OF_MBZ 0161400 - -/* RPMR - 176724 - maintenace register */ -#define PMR_DMD 0000001 /* Enable Diag mode */ -#define PMR_DCLK 0000002 /* Diag Data Clock */ -#define PMR_DIND 0000004 /* Diag Index Pulse */ -#define PMR_DSCK 0000010 /* Diag Sector Clock */ -#define PMR_DRDD 0000020 /* Diag Read Data */ -#define PMR_DWRD 0000040 /* Diag Write Data */ -#define PMR_ECE 0000100 /* In ECE field */ -#define PMR_DFE 0000200 /* In Data Field */ -#define PMR_ZD 0000400 /* After ECE field */ -#define PMR_MSK 0000037 /* Mask bits in PMR */ - -/* RPDT - 176726 - drive type */ - - -/* RPSN - 176730 - serial number */ - -/* us10 */ -/* RPOF - 176732 - offset register */ -#define RPOF_OFF 0000077 /* Offset value */ -#define RPOF_OFNU 0000100 -#define RPOF_OFD 0000200 /* Offset direction */ -#define RPOF_HCI 0002000 /* Head compare inhibited */ -#define RPOF_ECI 0004000 /* Error correct inhibit */ -#define RPOF_FMT22 0010000 /* Format 22/20 sectors */ -#define RPOF_SCG 0100000 /* Sign change */ -/* u4 low */ -/* RPDC - 176734 - desired cylinder */ -#define DC_V_CY 0 /* cylinder pos */ -#define DC_M_CY 01777 /* cylinder mask */ -#define DC_MBZ 0176000 -#define GET_CY(x) (((x) >> DC_V_CY) & DC_M_CY) -#define GET_DA(c,d) ((((GET_CY (c) * rp_drv_tab[d].surf) + GET_SF (c)) \ - * rp_drv_tab[d].sect) + GET_SC (c)) -#define CCYL u5 -/* u5 low */ -/* RPCC - 176736 - current cylinder */ - -/* RPER2 - 176740 - error status 2 - drive unsafe conditions - unimplemented */ -/* RPER3 - 176742 - error status 3 - more unsafe conditions - unimplemented */ -//#define ERR2 us9 -/* us9 */ -//#define ERR3 us10 - - -#define DATAPTR us9 -/* RPEC1 - 176744 - ECC status 1 - unimplemented */ -/* RPEC2 - 176746 - ECC status 2 - unimplemented */ - - -/* This controller supports many different disk drive types. These drives - are operated in 576 bytes/sector (128 36b words/sector) mode, which gives - them somewhat different geometry from the PDP-11 variants: - - type #sectors/ #surfaces/ #cylinders/ - surface cylinder drive - - RM03 30 5 823 =67MB - RM05 30 19 823 =256MB - RP04/5 20 19 411 =88MB - RP06 20 19 815 =176MB - RP07 43 32 630 =516MB - - In theory, each drive can be a different type. The size field in - each unit selects the drive capacity for each drive and thus the - drive type. DISKS MUST BE DECLARED IN ASCENDING SIZE. - - The RP07, despite its name, uses an RM-style controller. -*/ - -#define RP04_DTYPE 0 -#define RP04_SECT 20 -#define RP04_SURF 19 -#define RP04_CYL 411 -#define RP04_DEV 020020 -#define RP04_SIZE (RP04_SECT * RP04_SURF * RP04_CYL * RP_NUMWD) - -#define RP06_DTYPE 1 -#define RP06_SECT 20 -#define RP06_SURF 19 -#define RP06_CYL 815 -#define RP06_DEV 020022 -#define RP06_SIZE (RP06_SECT * RP06_SURF * RP06_CYL * RP_NUMWD) - -#define RP07_DTYPE 2 -#define RP07_SECT 43 -#define RP07_SURF 32 -#define RP07_CYL 630 -#define RP07_DEV 020042 -#define RP07_SIZE (RP07_SECT * RP07_SURF * RP07_CYL * RP_NUMWD) - -#define RM03_DTYPE 3 -#define RM03_SECT 30 -#define RM03_SURF 5 -#define RM03_CYL 823 -#define RM03_DEV 020024 -#define RM03_SIZE (RM03_SECT * RM03_SURF * RM03_CYL * RP_NUMWD) - -#define RM05_DTYPE 4 -#define RM05_SECT 30 -#define RM05_SURF 19 -#define RM05_CYL 823 -#define RM05_DEV 020027 -#define RM05_SIZE (RM05_SECT * RM05_SURF * RM05_CYL * RP_NUMWD) - -struct drvtyp { - int32 sect; /* sectors */ - int32 surf; /* surfaces */ - int32 cyl; /* cylinders */ - int32 size; /* #blocks */ - int32 devtype; /* device type */ - }; - -struct drvtyp rp_drv_tab[] = { - { RP04_SECT, RP04_SURF, RP04_CYL, RP04_SIZE, RP04_DEV }, - { RP06_SECT, RP06_SURF, RP06_CYL, RP06_SIZE, RP06_DEV }, - { RP07_SECT, RP07_SURF, RP07_CYL, RP07_SIZE, RP07_DEV }, - { RM03_SECT, RM03_SURF, RM03_CYL, RM03_SIZE, RM03_DEV }, - { RM05_SECT, RM05_SURF, RM05_CYL, RM05_SIZE, RM05_DEV }, - { 0 } - }; - - -int rp_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access); -int rp_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access); -uint16 rp_vect(struct pdp_dib *dibp); -void rp_setattn(UNIT *uptr); - -t_stat rp_svc(UNIT *); -t_stat rp_boot(int32, DEVICE *); -void rp_ini(UNIT *, t_bool); -t_stat rp_reset(DEVICE *); -t_stat rp_attach(UNIT *, CONST char *); -t_stat rp_detach(UNIT *); -t_stat rp_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat rp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, - const char *cptr); -const char *rp_description (DEVICE *dptr); -uint64 rp_buf[RP_NUMWD]; -uint16 rp_wc; -uint16 rp_dba; -uint16 rp_dbb; -t_addr rp_ba; -uint16 rp_cs2; -uint8 rp_ie; -uint16 rp_err2; -uint16 rp_err3; -uint16 rp_rmr[NUM_UNITS_RP]; - - -UNIT rpa_unit[] = { -/* Controller 1 */ - { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) }, - { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) }, - { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) }, - { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) }, - { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) }, - { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) }, - { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) }, - { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+DTYPE(RP06_DTYPE), RP06_SIZE) }, -}; - -DIB rpa_dib = {0776700, 077, 0254, 6, 1, &rp_read, &rp_write, &rp_vect, 0}; - - -MTAB rp_mod[] = { - { MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED", - &set_writelock, &show_writelock, NULL, "Write enable drive" }, - { MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED", - &set_writelock, NULL, NULL, "Write lock drive" }, - {UNIT_DTYPE, (RP07_DTYPE << UNIT_V_DTYPE), "RP07", "RP07", &rp_set_type }, - {UNIT_DTYPE, (RP06_DTYPE << UNIT_V_DTYPE), "RP06", "RP06", &rp_set_type }, - {UNIT_DTYPE, (RP04_DTYPE << UNIT_V_DTYPE), "RP04", "RP04", &rp_set_type }, - {UNIT_DTYPE, (RM03_DTYPE << UNIT_V_DTYPE), "RM03", "RM03", &rp_set_type }, - {UNIT_DTYPE, (RM05_DTYPE << UNIT_V_DTYPE), "RM05", "RM05", &rp_set_type }, - {MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", NULL, &disk_show_fmt }, - {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "addr", "addr", &uba_set_addr, uba_show_addr, - NULL, "Sets address of RH11" }, - {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "vect", "vect", &uba_set_vect, uba_show_vect, - NULL, "Sets vect of RH11" }, - {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "br", "br", &uba_set_br, uba_show_br, - NULL, "Sets br of RH11" }, - {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "ctl", "ctl", &uba_set_ctl, uba_show_ctl, - NULL, "Sets br of RH11" }, - {0} -}; - -REG rpa_reg[] = { - {ORDATA(WC, rp_wc, 16)}, - {ORDATA(BA, rp_ba, 18)}, - {ORDATA(UNIT, rp_cs2, 16)}, - {ORDATA(IE, rp_ie, 8), REG_HRO}, - {BRDATA(BUFF, rp_buf, 16, 64, RP_NUMWD), REG_HRO}, - {0} -}; - -DEVICE rpa_dev = { - "RP", rpa_unit, rpa_reg, rp_mod, - NUM_UNITS_RP, 8, 18, 1, 8, 36, - NULL, NULL, &rp_reset, &rp_boot, &rp_attach, &rp_detach, - &rpa_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug, - NULL, NULL, &rp_help, NULL, NULL, &rp_description -}; - -int -rp_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) { - int i; - int rp_unit = rp_cs2 & 07; - UNIT *uptr = &rpa_unit[rp_unit]; - int dtype = GET_DTYPE(uptr->flags); - - switch(addr & 076) { -/* u3 low */ - case 000: /* RPC - 176700 - control */ - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o Status=%06o\n", rp_unit, uptr->CMD); - if (rp_cs2 & CS2_PAT) { - uba_set_parity(rpa_dib.uba_ctl); - uptr->CMD |= (ER1_PAR << 16); - break; - } - if (access == BYTE && addr & 1) - break; - - rp_ie &= ~(CS1_IE); - rp_ie |= data & (CS1_IE); - if ((uptr->CMD & CS1_GO) != 0) { - uptr->CMD |= (ER1_RMR << 16); - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit, - addr & 077, data); - return 0; - } - rp_ba = ((data << 8) & 0600000) | (rp_ba & 0177777); - uptr->CMD &= ~077; - uptr->CMD |= data & 076; - /* Check if GO bit set */ - if ((data & 1) == 0) { - if (data & CS1_TRE) - rp_cs2 &= (CS2_IR|CS2_OR|CS2_UAI|CS2_PAT|CS2_UNIT); - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o no go %06o\n", rp_unit, data); - return 0; /* No, nop */ - } - if ((uptr->flags & UNIT_ATT) == 0) { - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o unattached %06o\n", rp_unit, data); - return 0; /* No, nop */ - } - uba_clr_irq(&rpa_dib); - uptr->CMD &= 0777; - switch (GET_FNC(data)) { - case FNC_NOP: - break; - - case FNC_RECAL: /* recalibrate */ - uptr->DA &= ~0177777; - uptr->STATUS |= DS_PIP; - uptr->CMD |= CS1_GO; - break; - - case FNC_SEEK: /* seek */ - if (GET_FNC(data) == FNC_SEEK && - GET_CY(uptr->DA) == (uptr->CCYL & 01777)) { - uptr->STATUS |= DS_ATA; - rp_setattn(uptr); - break; - } - /* Fall through */ - - case FNC_SEARCH: /* search */ - if (rp_rmr[rp_unit] & 1) { - int sect = rp_drv_tab[dtype].sect; - if (GET_CY(uptr->DA) != (uptr->CCYL & 01777)) { - uptr->STATUS |= DS_PIP; - } - uptr->CCYL = (uptr->CCYL & (0177777 << 16)) | GET_CY(uptr->DA); - if ((uptr->CCYL & (RPOF_FMT22 << 16)) != 0) - sect += 2; - if ((GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl) || - (GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) || - (GET_SC(uptr->DA) >= sect)) { - uptr->STATUS |= DS_ATA; - uptr->CMD |= (ER1_IAE << 16); - rp_setattn(uptr); - break; - } - } else - if ((GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl) || - (GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) || - (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect)) { - uptr->STATUS |= DS_ATA; - uptr->CMD |= (ER1_IAE << 16); - rp_setattn(uptr); - break; - } - /* Fall through */ - - case FNC_RETURN: /* return to center */ - case FNC_OFFSET: /* offset */ - case FNC_UNLOAD: /* unload */ - case FNC_WCHK: /* write check */ - case FNC_WRITE: /* write */ - case FNC_WRITEH: /* write w/ headers */ - case FNC_READ: /* read */ - case FNC_READH: /* read w/ headers */ - if (GET_CY(uptr->DA) != (uptr->CCYL & 01777)) { - uptr->STATUS |= DS_PIP; - } - if (GET_FNC(data) >= FNC_XFER) - rp_ie |= CSX_BUSY; - uptr->CMD |= CS1_GO; - CLR_BUF(uptr); - uptr->DATAPTR = 0; - break; - - - case FNC_DCLR: /* drive clear */ - uptr->STATUS &= DS_VV; - uptr->DA &= 003400177777; - uptr->CCYL &= 0177777; - rp_rmr[rp_unit] = 0; - uptr->CMD &= ~CS1_GO; - break; - - case FNC_PRESET: /* read-in preset */ - uptr->DA = 0; - uptr->CCYL &= 0177777; - /* Fall through */ - case FNC_PACK: /* pack acknowledge */ - uptr->STATUS |= DS_VV; - /* Fall through */ - case FNC_RELEASE: /* port release */ - break; - - default: - uptr->STATUS |= DS_ATA; - uptr->CMD |= (ER1_ILF << 16); - } - if (GET_FNC(data) >= FNC_XFER) - uptr->STATUS &= (DS_VV|DS_PIP); - rp_cs2 &= (CS2_IR|CS2_OR|CS2_UAI|CS2_PAT|CS2_UNIT); - if ((uptr->CMD & CS1_GO) != 0 && ((rp_rmr[rp_unit] & 1) == 0)) - sim_activate(uptr, 1000); - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o AStatus=%06o %06o %06o\n", rp_unit, uptr->CMD, rp_cs2, uptr->STATUS); - break; - case 002: /* RPWC - 176702 - word count */ - if ((rp_ie & (CSX_BUSY)) != 0) { - uptr->CMD |= (ER1_RMR << 16); - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit, - addr & 077, data); - return 0; - } - if (access == BYTE) { - if (addr & 1) - data = data | (rp_wc & 0377); - else - data = (rp_wc & 0177600) | data; - } - rp_wc = data; - break; - case 004: /* RPBA - 176704 - base address */ - if ((rp_ie & (CSX_BUSY)) != 0) { - uptr->CMD |= (ER1_RMR << 16); - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit, - addr & 077, data); - return 0; - } - if (access == BYTE) { - if (addr & 1) - data = data | (rp_ba & 0377); - else - data = (rp_ba & 0177600) | data; - } - rp_ba = (rp_ba & 0600000) | (data & 0177776); - break; - case 006: /* RPDC - 176706 - desired sector */ - if (access == BYTE) { - if (addr & 1) - data = data | ((uptr->DA >> 16) & 0377); - else - data = ((uptr->DA >> 16) & 0177600) | data; - } - uptr->DA &= 0177777; - uptr->DA |= data << 16; - break; - - case 010: /* RPCS2 - 176710 - Control and Status register 2 */ - if (access == BYTE) { - if (addr & 1) - data = data | (rp_cs2 & 0377); - } - rp_cs2 = ((CS2_DLT|CS2_WCE|CS2_NED|CS2_NEM|CS2_PGE|CS2_MDPE) & rp_cs2) | - ((CS2_UAI|CS2_PAT|CS2_UNIT) & data); - if (data & CS2_CLR) { - rp_reset(&rpa_dev); - } - rp_cs2 |= CS2_IR; - rp_unit = rp_cs2 & 07; - if (rpa_unit[rp_cs2 & CS2_UNIT].flags & UNIT_DIS) - rp_cs2 |= CS2_NED; - break; - - case 012: /* RPDS - 176712 - drive status */ - break; - - case 014: /* RPER1 - 176714 - error status 1 */ - if (access == BYTE) { - if (addr & 1) - data = data | ((uptr->CMD >> 16) & 0377); - else - data = ((uptr->CMD >> 16) & 0177600) | data; - } - uptr->CMD &= 0177777; - uptr->CMD |= data << 16; - break; - - case 016: /* RPAS - 176716 - attention summary */ - if (access == BYTE && addr & 1) - break; - for (i = 0; i < 8; i++) { - if (data & (1<STATUS &= ~DS_ATA; - } - } - break; - - case 024: /* RPMR - 176724 - maintenace register */ - /* LA_REG has 10 bits for position in sector */ - if (data & 1) { - if ((data & 076) == 0) { - if (rp_rmr[rp_unit] & 010) - uptr->LA_REG ++; - if (rp_rmr[rp_unit] & 04) - uptr->LA_REG = 0; - } - rp_rmr[rp_unit] = data; - } else - rp_rmr[rp_unit] = 0; - break; - case 020: /* RPLA - 176720 - look ahead register */ - case 026: /* RPDT - 176726 - drive type */ - break; - case 022: /* RPDB - 176722 - data buffer */ - if ((rp_cs2 & CS2_IR) == 0) { - rp_cs2 |= CS2_DLT; - break; - } - rp_dba = rp_dbb; - rp_dbb = data; - if (rp_cs2 & CS2_IR) - rp_dba = rp_dbb; - rp_cs2 |= CS2_OR; - rp_cs2 &= ~CS2_IR; - break; - case 032: /* RPOF - 176732 - offset register */ - uptr->CCYL &= 0177777; - uptr->CCYL |= data << 16; - break; - case 034: /* RPDC - 176734 - desired cylinder */ - if ((uptr->CMD & CS1_GO) != 0) { - uptr->CMD |= (ER1_RMR << 16); - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit, - addr & 077, data); - break; - } - if (access == BYTE) { - if (addr & 1) - data = data | (uptr->DA & 0377); - else - data = (uptr->DA & 0177600) | data; - } - uptr->DA &= ~0177777; - uptr->DA |= data; - break; - case 040: /* RPER2 - 176740 - error status 2 - drive unsafe conditions */ - rp_err2 = data; - break; - case 042: /* RPER3 - 176742 - error status 3 - more unsafe conditions */ - rp_err3 = data; - break; - case 030: /* RPSN - 176730 - serial number */ - case 036: /* RPCC - 176736 - current cylinder */ - case 044: /* RPEC1 - 176744 - ECC status 1 - unimplemented */ - case 046: /* RPEC2 - 176746 - ECC status 2 - unimplemented */ - break; - } - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o write %02o %06o\n", rp_unit, - addr & 076, data); - return 0; -} - -int -rp_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access) { - int rp_unit = rp_cs2 & 07; - UNIT *uptr = &rpa_unit[rp_unit]; - uint16 temp = 0; - int i; - - switch(addr & 076) { - case 000: /* RPC - 176700 - control */ - temp = uptr->CMD & 077; - temp |= (uint16)(rp_ie & (CS1_IE)); - temp |= (rp_ba & 0600000) >> 8; - if ((rp_ie & CSX_BUSY) == 0) - temp |= CS1_RDY; - if (uptr->flags & UNIT_ATT) - temp |= CS1_DVA; - if (rp_cs2 & (CS2_MDPE|CS2_MXF|CS2_PGE|CS2_NEM|CS2_NED|CS2_PE|CS2_WCE|CS2_DLT)) - temp |= CS1_TRE|CS1_SC; - for (i = 0; i < 8; i++) { - UNIT *u = &rpa_unit[i]; - if (u->STATUS & DS_ATA) { - temp |= CS1_SC; - break; - } - } - break; - case 002: /* RPWC - 176702 - word count */ - temp = rp_wc; - break; - case 004: /* RPBA - 176704 - base address */ - temp = (uint16)(rp_ba & 0177776); - break; - case 006: /* RPDC - 176706 - desired sector */ - temp = (uptr->DA >> 16) & 0177777; - break; - case 010: /* RPCS2 - 176710 - control/status 2 */ - temp = rp_cs2; - break; - case 012: /* RPDS - 176712 - drive status */ - temp = uptr->STATUS; - if (((uptr->CMD >> 16) & 0177777) != 0 || rp_err2 != 0 || rp_err3 != 0) - temp |= DS_ERR; - if ((uptr->flags & UNIT_DIS) == 0) - temp |= DS_DPR; - if ((uptr->flags & UNIT_ATT) != 0) - temp |= DS_MOL; - if ((uptr->flags & UNIT_WPRT) != 0) - temp |= DS_WRL; - if ((uptr->CMD & CS1_GO) == 0) - temp |= DS_DRY; - break; - case 014: /* RPER1 - 176714 - error status 1 */ - temp = (uptr->CMD >> 16) & 0177777; - break; - case 016: /* RPAS - 176716 - attention summary */ - for (i = 0; i < 8; i++) { - UNIT *u = &rpa_unit[i]; - if (u->STATUS & DS_ATA) { - temp |= 1 << i; - } - } - break; - case 020: /* RPLA - 176720 - look ahead register */ - if ((uptr->LA_REG >> 10) >= 23) - uptr->LA_REG = 0; - temp = GET_SC(uptr->DA) << 6; - temp ^= ((uptr->LA_REG + 1) >> 4) & 07760; - if ((rp_rmr[rp_unit] & 1) == 0) - uptr->LA_REG+=1024; - break; - case 022: /* RPDB - 176722 - data buffer */ - if ((rp_cs2 & CS2_OR) == 0) { - rp_cs2 |= CS2_DLT; - break; - } - temp = rp_dba; - rp_dba = rp_dbb; - rp_cs2 &= ~CS2_OR; - rp_cs2 |= CS2_IR; - break; - case 024: /* RPMR - 176724 - maintenace register */ - if (rp_rmr[rp_unit] & 1) - temp = rp_rmr[rp_unit] & PMR_MSK; - break; - case 026: /* RPDT - 176726 - drive type */ - temp = rp_drv_tab[GET_DTYPE(uptr->flags)].devtype; - break; - case 030: /* RPSN - 176730 - serial number */ - temp = (rp_unit + 1); - break; - case 032: /* RPOF - 176732 - offset register */ - temp = (uptr->CCYL >> 16) & 0177777; - break; - case 034: /* RPDC - 176734 - desired cylinder */ - temp = GET_CY(uptr->DA); - break; - case 036: /* RPCC - 176736 - current cylinder */ - temp = uptr->CCYL & 0177777; - break; - case 040: /* RPER2 - 176740 - error status 2 - drive unsafe conditions */ - temp = rp_err2; - break; - case 042: /* RPER3 - 176742 - error status 3 - more unsafe conditions */ - temp = rp_err3; - break; - case 044: /* RPEC1 - 176744 - ECC status 1 - unimplemented */ - case 046: /* RPEC2 - 176746 - ECC status 2 - unimplemented */ - break; - } - *data = temp; - sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o read %02o %06o %06o\n", rp_unit, - addr & 076, temp, PC); - if (rp_cs2 & CS2_PAT) { - uba_set_parity(rpa_dib.uba_ctl); - uptr->CMD |= (ER1_PAR << 16); - } - return 0; -} - -uint16 -rp_vect(struct pdp_dib *dibp) -{ - return dibp->uba_vect; -} - -/* Set the attention flag for a unit */ -void rp_setattn(UNIT *uptr) -{ - uptr->STATUS |= DS_ATA; - uptr->CMD &= ~CS1_GO; - if ((rp_ie & CSX_BUSY) == 0 && (rp_ie & CS1_IE) != 0) - uba_set_irq(&rpa_dib); -} - - - -t_stat rp_svc (UNIT *uptr) -{ - int dtype = GET_DTYPE(uptr->flags); - int cyl = GET_CY(uptr->DA); - int unit; - DEVICE *dptr; - int diff, da; - int sts; - uint64 buf; - - dptr = uptr->dptr; - unit = uptr - dptr->units; - if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ - uptr->CMD |= (ER1_UNS << 16); /* set drive error */ - uptr->STATUS |= DS_ATA; - rp_ie &= ~(CSX_BUSY); - uptr->CMD &= ~CS1_GO; - if (GET_FNC(uptr->CMD) >= FNC_XFER) { /* xfr? set done */ - if ((rp_ie & CSX_BUSY) == 0 && (rp_ie & CS1_IE) != 0) - uba_set_irq(&rpa_dib); - } else { - rp_setattn(uptr); - } - return (SCPE_OK); - } - - /* Check if seeking */ - if (uptr->STATUS & DS_PIP) { - sim_debug(DEBUG_DETAIL, dptr, "%s%o seek %d %d\n", dptr->name, unit, cyl, uptr->CCYL); - if (cyl >= rp_drv_tab[dtype].cyl) { - uptr->STATUS &= ~DS_PIP; - sim_activate(uptr, 10); - return SCPE_OK; - } - diff = cyl - (uptr->CCYL & 01777); - if (diff < 0) { - if (diff < -50) { - uptr->CCYL -= 50; - sim_activate(uptr, 500); - } else if (diff < -10) { - uptr->CCYL -= 10; - sim_activate(uptr, 200); - } else { - uptr->CCYL -= 1; - sim_activate(uptr, 100); - } - return SCPE_OK; - } else if (diff > 0) { - if (diff > 50) { - uptr->CCYL += 50; - sim_activate(uptr, 500); - } else if (diff > 10) { - uptr->CCYL += 10; - sim_activate(uptr, 200); - } else { - uptr->CCYL += 1; - sim_activate(uptr, 100); - } - return SCPE_OK; - } else { - uptr->STATUS &= ~DS_PIP; - uptr->DATAPTR = 0; - } - } - - /* Bump sector counter */ - switch (GET_FNC(uptr->CMD)) { - case FNC_NOP: - case FNC_DCLR: /* drive clear */ - case FNC_RELEASE: /* port release */ - case FNC_PACK: /* pack acknowledge */ - break; - case FNC_UNLOAD: /* unload */ - rp_detach(uptr); - /* Fall through */ - case FNC_OFFSET: /* offset */ - /* Fall through */ - case FNC_RETURN: /* return to center */ - case FNC_PRESET: /* read-in preset */ - case FNC_RECAL: /* recalibrate */ - case FNC_SEEK: /* seek */ - if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect || - GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf || - GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl) - uptr->CMD |= (ER1_IAE << 16); - rp_setattn(uptr); - sim_debug(DEBUG_DETAIL, dptr, "%s%o seekdone %d %o\n", dptr->name, unit, cyl, uptr->CMD); - break; - - case FNC_SEARCH: /* search */ - if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect || - GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf || - GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl) - uptr->CMD |= (ER1_IAE << 16); - rp_setattn( uptr); - sim_debug(DEBUG_DETAIL, dptr, "%s%o searchdone %d %o\n", dptr->name, unit, cyl, uptr->CMD); - break; - - case FNC_READ: /* read */ - case FNC_READH: /* read w/ headers */ - case FNC_WCHK: /* write check */ - - if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect || - GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) { - uptr->CMD |= (ER1_IAE << 16); - uptr->STATUS |= DS_ATA; - rp_ie &= ~(CSX_BUSY); - uptr->CMD &= ~CS1_GO; - if (rp_ie & CS1_IE) - uba_set_irq(&rpa_dib); - sim_debug(DEBUG_DETAIL, dptr, "%s%o readx done\n", dptr->name, unit); - return SCPE_OK; - } - sim_debug(DEBUG_DETAIL, dptr, "%s%o read (%d,%d,%d)\n", dptr->name, unit, cyl, - GET_SF(uptr->DA), GET_SC(uptr->DA)); - da = GET_DA(uptr->DA, dtype); - (void)disk_read(uptr, &rp_buf[0], da, RP_NUMWD); - uptr->hwmark = RP_NUMWD; - uptr->DATAPTR = 0; - sts = 1; - /* On read headers, transfer 2 words to start */ - if (GET_FNC(uptr->CMD) == FNC_READH) { - buf = (((uint64)cyl) << 18) | - ((uint64)((GET_SF(uptr->DA) << 8) | GET_SF(uptr->DA))); - sim_debug(DEBUG_DATA, dptr, "%s%o read word h1 %012llo %09o %06o\n", - dptr->name, unit, buf, rp_ba, rp_wc); - if ((sts = uba_write_npr(rp_ba, rpa_dib.uba_ctl, buf)) == 0) - goto rd_end; - if ((rp_cs2 & CS2_UAI) == 0) - rp_ba += 4; - rp_wc = (rp_wc + 2) & 0177777; - if (rp_wc == 0) { - sts = 0; - goto rd_end; - } - buf = (((uint64)(unit + 1)) << 18) | (uint64)(unit); - sim_debug(DEBUG_DATA, dptr, "%s%o read word h2 %012llo %09o %06o\n", - dptr->name, unit, buf, rp_ba, rp_wc); - if ((sts = uba_write_npr(rp_ba, rpa_dib.uba_ctl, buf)) == 0) - goto rd_end; - if ((rp_cs2 & CS2_UAI) == 0) - rp_ba += 4; - rp_wc = (rp_wc + 2) & 0177777; - if (rp_wc == 0) { - sts = 0; - goto rd_end; - } - } - - while (uptr->DATAPTR < RP_NUMWD && sts != 0) { - buf = rp_buf[uptr->DATAPTR++]; - sim_debug(DEBUG_DATA, dptr, "%s%o read word %d %012llo %09o %06o\n", - dptr->name, unit, uptr->DATAPTR, buf, rp_ba, rp_wc); - sts = uba_write_npr(rp_ba, rpa_dib.uba_ctl, buf); - if ((rp_cs2 & CS2_UAI) == 0) - rp_ba += 4; - rp_wc = (rp_wc + 2) & 0177777; - if (rp_wc == 0) { - sts = 0; - goto rd_end; - } - } - - if (sts) { - /* Increment to next sector. Set Last Sector */ - uptr->DATAPTR = 0; - CLR_BUF(uptr); - uptr->DA += 1 << DA_V_SC; - if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect) { - uptr->DA &= (DA_M_SF << DA_V_SF) | (DC_M_CY << DC_V_CY); - uptr->DA += 1 << DA_V_SF; - if (GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) { - uptr->DA &= (DC_M_CY << DC_V_CY); - uptr->DA += 1 << DC_V_CY; - uptr->STATUS |= DS_PIP; - } - } - uptr->LA_REG = GET_SC(uptr->DA) << 10; - sim_activate(uptr, 300); - return SCPE_OK; - } -rd_end: - uptr->LA_REG = GET_SC(uptr->DA) << 10; - sim_debug(DEBUG_DETAIL, dptr, "%s%o read done\n", dptr->name, unit); - uptr->CMD &= ~CS1_GO; - rp_ie &= ~(CSX_BUSY); - if (rp_ie & CS1_IE) - uba_set_irq(&rpa_dib); - return SCPE_OK; - - case FNC_WRITE: /* write */ - case FNC_WRITEH: /* write w/ headers */ - if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect || - GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) { - uptr->CMD |= (ER1_IAE << 16); - uptr->STATUS |= DS_ATA; - rp_ie &= ~(CSX_BUSY); - uptr->CMD &= ~CS1_GO; - if (rp_ie & CS1_IE) - uba_set_irq(&rpa_dib); - sim_debug(DEBUG_DETAIL, dptr, "%s%o writex done\n", dptr->name, unit); - return SCPE_OK; - } - sts = 1; - /* On Write headers, transfer 2 words to start */ - if (GET_FNC(uptr->CMD) == FNC_WRITEH) { - if (uba_read_npr(rp_ba, rpa_dib.uba_ctl, &buf) == 0) - goto wr_done; - if ((rp_cs2 & CS2_UAI) == 0) - rp_ba += 4; - rp_wc = (rp_wc + 2) & 0177777; - if (rp_wc == 0) { - sts = 0; - goto wr_done; - } - sim_debug(DEBUG_DATA, dptr, "%s%o write word h1 %012llo %07o\n", - dptr->name, unit, buf, rp_wc); - if (uba_read_npr(rp_ba, rpa_dib.uba_ctl, &buf) == 0) - goto wr_done; - if ((rp_cs2 & CS2_UAI) == 0) - rp_ba += 4; - rp_wc = (rp_wc + 2) & 0177777; - if (rp_wc == 0) { - sts = 0; - goto wr_done; - } - sim_debug(DEBUG_DATA, dptr, "%s%o write word h2 %012llo %07o\n", - dptr->name, unit, buf, rp_wc); - } - uptr->DATAPTR = 0; - uptr->hwmark = 0; - buf = 0; - while (uptr->DATAPTR < RP_NUMWD) { - if ((sts = uba_read_npr(rp_ba, rpa_dib.uba_ctl, &buf)) == 0) - break; - rp_buf[uptr->DATAPTR++] = buf; - sim_debug(DEBUG_DATA, dptr, "%s%o write word %d %012llo %07o %06o\n", - dptr->name, unit, uptr->DATAPTR, buf, rp_ba, rp_wc); - if ((rp_cs2 & CS2_UAI) == 0) - rp_ba += 4; - rp_wc = (rp_wc + 2) & 0177777; - if (rp_wc == 0) { - sts = 0; - goto wr_done; - } - } -wr_done: - while (uptr->DATAPTR < RP_NUMWD) { - rp_buf[uptr->DATAPTR++] = 0; - } - sim_debug(DEBUG_DETAIL, dptr, "%s%o write (%d,%d,%d)\n", dptr->name, - unit, cyl, GET_SF(uptr->DA), GET_SC(uptr->DA)); - da = GET_DA(uptr->DA, dtype); - (void)disk_write(uptr, &rp_buf[0], da, RP_NUMWD); - uptr->DATAPTR = 0; - CLR_BUF(uptr); - uptr->DA += 1 << DA_V_SC; - if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect) { - uptr->DA &= (DA_M_SF << DA_V_SF) | (DC_M_CY << DC_V_CY); - uptr->DA += 1 << DA_V_SF; - if (GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) { - uptr->DA &= (DC_M_CY << DC_V_CY); - uptr->DA += 1 << DC_V_CY; - uptr->STATUS |= DS_PIP; - } - } - - uptr->LA_REG = GET_SC(uptr->DA) << 10; - if (sts) { - sim_activate(uptr, 300); - } else { - sim_debug(DEBUG_DETAIL, dptr, "RP%o write done\n", unit); - uptr->STATUS &= ~DS_PIP; - rp_ie &= ~(CSX_BUSY); - uptr->CMD &= ~CS1_GO; - if (rp_ie & CS1_IE) - uba_set_irq(&rpa_dib); - } - return SCPE_OK; - } - return SCPE_OK; -} - - -t_stat -rp_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ - int i; - - if (uptr == NULL) return SCPE_IERR; - uptr->flags &= ~(UNIT_DTYPE); - uptr->flags |= val; - i = GET_DTYPE(val); - uptr->capac = rp_drv_tab[i].size; - return SCPE_OK; -} - - -t_stat -rp_reset(DEVICE * dptr) -{ - int i; - rp_ba = 0; - rp_wc = 0; - rp_ie = 0; - rp_err2 = 0; - rp_err3 = 0; - rp_cs2 = CS2_IR; - for (i = 0; i < 8; i++) { - UNIT *u = &rpa_unit[i]; - u->STATUS &= DS_VV; - u->CMD &= 0177776; - u->CCYL &= ((OF_HCI|OF_ECI|OF_F22) << 16) | 0177777; - if (rp_rmr[i] & 1) { - u->CCYL = GET_CY(u->DA) | (((OF_HCI|OF_ECI|OF_F22) << 16) & u->CCYL); - } - rp_rmr[i] = 0; - } - uba_clr_irq(&rpa_dib); - sim_debug(DEBUG_DETAIL, dptr, "RP reset done\n"); - return SCPE_OK; -} - -/* Boot from given device */ -t_stat -rp_boot(int32 unit_num, DEVICE * rptr) -{ - UNIT *uptr = &rptr->units[unit_num]; - int dtype = GET_DTYPE(uptr->flags); - DEVICE *dptr = uptr->dptr; - uint32 addr; - uint32 ptr = 0; - uint64 len; - int i; - int da; - t_stat r; - - if ((r = rp_reset(dptr) )!= SCPE_OK) - return r; - /* Read in block 1 and see if it is a home block */ - disk_read(uptr, &rp_buf[0], 1, RP_NUMWD); - if (rp_buf[0] != 0505755000000LL) { - /* Try blocks 10 and 12 if fail */ - disk_read(uptr, &rp_buf[0], 010, RP_NUMWD); - if (rp_buf[0] != 0505755000000LL) { - disk_read(uptr, &rp_buf[0], 012, RP_NUMWD); - if (rp_buf[0] != 0505755000000LL) - return SCPE_IERR; - } - } - - /* Word 103 and 102 contain pointer to SMFILE block */ - uptr->DA = (int32)((rp_buf[0103] & 077) << DA_V_SC) | - (int32)(((rp_buf[0103] >> 8) & 077) << DA_V_SF) | - (int32)((rp_buf[0103] >> 24) << DC_V_CY); - len = (int)(rp_buf[0102] & RMASK); - da = GET_DA(uptr->DA, dtype); - disk_read(uptr, &rp_buf[0], da, RP_NUMWD); - /* For diagnostics use locations 6 and 7 */ - if (sim_switches & SWMASK ('D')) { - sim_messagef(SCPE_OK, "Diags boot\n"); - uptr->DA = (int32)((rp_buf[06] & 077) << DA_V_SC) | - (int32)(((rp_buf[06] >> 8) & 077) << DA_V_SF) | - (int32)((rp_buf[06] >> 24) << DC_V_CY); - len = (int)(((rp_buf[07] & 077) * 4) & RMASK); - } else { - /* Normal is at 4 and 5*/ - uptr->DA = (int32)((rp_buf[04] & 077) << DA_V_SC) | - (int32)(((rp_buf[04] >> 8) & 077) << DA_V_SF) | - (int32)((rp_buf[04] >> 24) << DC_V_CY); - len = (int)(((rp_buf[05] & 077) * 4) & RMASK); - } - - /* Read len sectors into address 1000 */ - addr = 01000; - for (; len > 0; len--) { - da = GET_DA(uptr->DA, dtype); - disk_read(uptr, &rp_buf[0], da, RP_NUMWD); - for (i = 0; i < RP_NUMWD; i++) { - M[addr++] = rp_buf[i]; - } - uptr->DA += 1 << DA_V_SC; - if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect) { - uptr->DA &= (DA_M_SF << DA_V_SF) | (DC_M_CY << DC_V_CY); - uptr->DA += 1 << DA_V_SF; - if (GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) { - uptr->DA &= (DC_M_CY << DC_V_CY); - uptr->DA += 1 << DC_V_CY; - } - } - } - /* Start location, and set up load infor */ - PC = 01000; - M[036] = rpa_dib.uba_addr | (rpa_dib.uba_ctl << 18); - M[037] = unit_num; - return cty_reset(&cty_dev); -} - -/* Device attach */ - -t_stat rp_attach (UNIT *uptr, CONST char *cptr) -{ - t_stat r; - DEVICE *rptr; - DIB *dib; - - uptr->capac = rp_drv_tab[GET_DTYPE (uptr->flags)].size; - r = disk_attach (uptr, cptr); - if (r != SCPE_OK) - return r; - rptr = find_dev_from_unit(uptr); - if (rptr == 0) - return SCPE_OK; - dib = (DIB *) rptr->ctxt; - if (sim_switches & SIM_SW_REST) - return SCPE_OK; - uptr->DA = 0; - uptr->STATUS = DS_ATA; - if ((rp_ie & CSX_BUSY) == 0 && (rp_ie & CS1_IE) != 0) - uba_set_irq(&rpa_dib); - return SCPE_OK; -} - -/* Device detach */ - -t_stat rp_detach (UNIT *uptr) -{ - if (!(uptr->flags & UNIT_ATT)) /* attached? */ - return SCPE_OK; - if (sim_is_active (uptr)) /* unit active? */ - sim_cancel (uptr); /* cancel operation */ - uptr->STATUS = 0; - return disk_detach (uptr); -} - -t_stat rp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) -{ -fprintf (st, "RP04/05/06/07 Disk Pack Drives (RP)\n\n"); -fprintf (st, "The RP controller implements the Massbus family of large disk drives. RP\n"); -fprintf (st, "options include the ability to set units write enabled or write locked, to\n"); -fprintf (st, "set the drive type to one of six disk types or autosize, and to write a DEC\n"); -fprintf (st, "standard 044 compliant bad block table on the last track.\n\n"); -disk_attach_help(st, dptr, uptr, flag, cptr); -fprint_set_help (st, dptr); -fprint_show_help (st, dptr); -fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n"); -fprintf (st, "The RP device supports the BOOT command.\n"); -fprint_reg_help (st, dptr); -return SCPE_OK; -} - -const char *rp_description (DEVICE *dptr) -{ - return "RP04/05/06/07 Massbus disk controller"; -} - - -#endif diff --git a/PDP10/ks10_tu.c b/PDP10/ks10_tu.c deleted file mode 100644 index e10bb39..0000000 --- a/PDP10/ks10_tu.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* ks10_tu.c: DEC Massbus TM03/TU10 tape controller - - Copyright (c) 2021, Richard Cornwell - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PUTUOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include "kx10_defs.h" -#include "sim_tape.h" - -#ifndef NUM_DEVS_TU -#define NUM_DEVS_TU 0 -#endif - -#if (NUM_DEVS_TU > 0) - -#define NUM_UNITS_TU 4 -#define TU_NUMFR (64*1024) - -#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF) -#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF - -/* Flags in the unit flags word */ - -#define TU_UNIT UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE - -#define CMD u3 -/* u3 low */ -/* TUC - 772440 - control */ - -#define CS1_GO 1 /* go */ -#define CS1_V_FNC 1 /* function pos */ -#define CS1_M_FNC 037 /* function mask */ -#define CS1_FNC (CS1_M_FNC << CS1_V_FNC) -#define FNC_NOP 000 /* no operation */ -#define FNC_UNLOAD 001 /* unload */ -#define FNC_REWIND 003 /* rewind */ -#define FNC_DCLR 004 /* drive clear */ -#define FNC_PRESET 010 /* read-in preset */ -#define FNC_ERASE 012 /* Erase */ -#define FNC_WTM 013 /* Write Tape Mark */ -#define FNC_SPACEF 014 /* Space record forward */ -#define FNC_SPACEB 015 /* Space record backward */ -#define FNC_XFER 024 /* >=? data xfr */ -#define FNC_WCHK 024 /* write check */ -#define FNC_WCHKREV 027 /* write check reverse */ -#define FNC_WRITE 030 /* write */ -#define FNC_READ 034 /* read */ -#define FNC_READREV 037 /* read reverse */ -#define CS1_IE 0000100 /* Enable interrupts */ -#define CS1_RDY 0000200 /* Drive ready */ -#define CS1_UBA 0001400 /* High order UBA bits */ -#define CS1_PSEL 0002000 /* */ -#define CS1_DVA 0004000 /* drive avail NI */ -#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC) -#define CS1_MCPE 0020000 /* */ -#define CS1_TRE 0040000 /* */ -#define CS1_SC 0100000 /* */ - -#define CSX_BUSY 02 /* RH11 is doing a transfer */ - -/* TUWC - 772442 - word count. */ - -/* TUBA - 772444 - bus address */ - -/* TUFC - 772446 - Frame count */ - -/* TUCS2 -772450 - Control Status 2 */ -#define CS2_V_UNIT 0 /* unit pos */ -#define CS2_M_UNIT 07 /* unit mask */ -#define CS2_UNIT (CS2_M_UNIT << CS2_V_UNIT) -#define CS2_UAI 0000010 /* addr inhibit */ -#define CS2_PAT 0000020 /* parity test NI */ -#define CS2_CLR 0000040 /* controller clear */ -#define CS2_IR 0000100 /* input ready */ -#define CS2_OR 0000200 /* output ready */ -#define CS2_MDPE 0000400 /* Mbus par err NI set TRE*/ -#define CS2_MXF 0001000 /* missed xfer NI set TRE*/ -#define CS2_PGE 0002000 /* program err set TRE*/ -#define CS2_NEM 0004000 /* nx mem err set TRE*/ -#define CS2_NED 0010000 /* nx drive err set TRE */ -#define CS2_PE 0020000 /* parity err NI set TRE */ -#define CS2_WCE 0040000 /* write check err set TRE */ -#define CS2_DLT 0100000 /* data late NI set TRE */ - -#define STATUS u5 -/* u5 low */ -/* TUDS - 772452 - drive status */ - -#define DS_SLA 0000001 /* Drive has become ready */ -#define DS_BOT 0000002 /* Beginning of tape */ -#define DS_TM 0000004 /* Tape mark */ -#define DS_IDB 0000010 /* Identification burst */ -#define DS_SDWN 0000020 /* Tape stoped */ -#define DS_PES 0000040 /* Phase Encoding */ -#define DS_SSC 0000100 /* Status change */ -#define DS_DRY 0000200 /* drive ready */ -#define DS_DPR 0000400 /* drive present */ -#define DS_PGM 0001000 /* programable NI */ -#define DS_EOT 0002000 /* end of tape */ -#define DS_WRL 0004000 /* write locked */ -#define DS_MOL 0010000 /* medium online */ -#define DS_PIP 0020000 /* pos in progress */ -#define DS_ERR 0040000 /* error */ -#define DS_ATA 0100000 /* attention active */ - -/* u5 high */ -/* TUER1 - 772454 - error status 1 */ - -#define ER1_ILF 0000001 /* illegal func */ -#define ER1_ILR 0000002 /* illegal register */ -#define ER1_RMR 0000004 /* reg mod refused */ -#define ER1_PAR 0000010 /* control parity err NI */ -#define ER1_FMT 0000020 /* format err */ -#define ER1_DPAR 0000040 /* data parity error */ -#define ER1_INC 0000100 /* Incorrectable data */ -#define ER1_PEF 0000200 /* format error */ -#define ER1_NSG 0000400 /* Nonstandard gap NI */ -#define ER1_FCE 0001000 /* Frame count error */ -#define ER1_ITM 0002000 /* Illegal tape mark */ -#define ER1_NEF 0004000 /* Non executable function */ -#define ER1_DTE 0010000 /* drive time err NI */ -#define ER1_OPI 0020000 /* op incomplete */ -#define ER1_UNS 0040000 /* drive unsafe */ -#define ER1_DCK 0100000 /* data check NI */ - -/* TULA - 772460 - Check Character */ - -/* TUDB - 772462 - Data buffer */ - -/* TUMR - 772464 - maintenace register */ - -/* TUAS - 772456 - attention summary */ - -#define AS_U0 0000001 /* unit 0 flag */ - -/* TUDT - 772466 - drive type */ - -/* TUSN - 772470 - serial number */ - -/* TUTC - 772472 - Tape control register */ -#define TC_SS 0000007 /* Slave select mask */ -#define TC_EVPAR 0000010 /* Even parity */ -#define TC_FMTSEL 0000360 /* Format select */ -#define TC_10CORE 000 /* PDP 10 Core */ - /* 4 8 bit chars + 1 4 bit char */ -#define TC_15CORE 001 /* PDP 15 core */ - /* 3 6 bit chars per word */ -#define TC_10NORM 003 /* PDP 10 Compatible */ - /* 4 8 bit chars per word */ -#define TC_11NORM 014 /* PDP 11 Normal */ - /* 2 8 bit chars per word */ -#define TC_11CORE 015 /* PDP 11 Core */ - /* 4 4 bit chars per word */ -#define TC_15NORM 016 /* PDP 15 Normal */ - /* 2 8 bit chars per word */ -#define TC_DENS 0003400 /* Density (ignored) */ -#define TC_800 0001400 /* 800 BPI */ -#define TC_1600 0002000 /* 1600 BPI */ -#define TC_EAODTE 0010000 /* Enable abort */ -#define TC_SAC 0020000 /* Slave address change */ -#define TC_FCS 0040000 /* Frame count status */ -#define TC_ACCL 0100000 /* Acceleration */ - - -/* TUER3 - 15 - error status 3 - more unsafe conditions - unimplemented */ - -#define CPOS u4 -#define DATAPTR u6 - -uint8 tu_buf[TU_NUMFR]; -uint64 tu_cbuf; -uint16 tu_frame; -uint16 tu_tcr; -uint16 tu_wc; -uint16 tu_dba; -uint16 tu_dbb; -uint16 tu_cs2; -t_addr tu_ba; -uint8 tu_attn; -uint8 tu_ie; -uint16 tu_mr; -static uint64 tu_boot_buffer; - -int tu_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access); -int tu_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access); -uint16 tu_vect(struct pdp_dib *dibp); -void tu_rst(DEVICE *dptr); -t_stat tu_srv(UNIT *); -t_stat tu_boot(int32, DEVICE *); -void tu_ini(UNIT *, t_bool); -t_stat tu_reset(DEVICE *); -t_stat tu_attach(UNIT *, CONST char *); -t_stat tu_detach(UNIT *); -t_stat tu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, - const char *cptr); -const char *tu_description (DEVICE *dptr); - - -UNIT tua_unit[] = { -/* Controller 1 */ - { UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) }, - { UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) }, - { UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) }, - { UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) }, - { UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) }, - { UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) }, - { UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) }, - { UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) }, -}; - -DIB tua_dib = {0772440, 037, 0224, 6, 3, &tu_read, &tu_write, &tu_vect, 0}; - -MTAB tu_mod[] = { - {MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL}, - {MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL}, - {MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", - &sim_tape_set_fmt, &sim_tape_show_fmt, NULL}, - {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LENGTH", "LENGTH", - &sim_tape_set_capac, &sim_tape_show_capac, NULL}, - {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "DENSITY", "DENSITY", - &sim_tape_set_dens, &sim_tape_show_dens, NULL}, - {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "addr", "addr", &uba_set_addr, uba_show_addr, - NULL, "Sets address of RH11" }, - {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "vect", "vect", &uba_set_vect, uba_show_vect, - NULL, "Sets vect of RH11" }, - {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "br", "br", &uba_set_br, uba_show_br, - NULL, "Sets br of RH11" }, - {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "ctl", "ctl", &uba_set_ctl, uba_show_ctl, - NULL, "Sets br of RH11" }, - {0} -}; - -REG tua_reg[] = { - {ORDATA(WC, tu_wc, 16)}, - {ORDATA(BA, tu_ba, 18)}, - {ORDATA(ATTN, tu_attn, 8)}, - {ORDATA(UNIT, tu_cs2, 8)}, - {ORDATA(IE, tu_ie, 8), REG_HRO}, - {ORDATA(FRAME, tu_frame, 16)}, - {ORDATA(TCR, tu_tcr, 16)}, - {BRDATA(BUFF, tu_buf, 16, 8, TU_NUMFR), REG_HRO}, - {0} -}; - -DEVICE tua_dev = { - "TU", tua_unit, tua_reg, tu_mod, - NUM_UNITS_TU, 8, 18, 1, 8, 36, - NULL, NULL, &tu_reset, &tu_boot, &tu_attach, &tu_detach, - &tua_dib, DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, - NULL, NULL, &tu_help, NULL, NULL, &tu_description -}; - -int -tu_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) { - int i; - int unit = tu_tcr & 07; - UNIT *uptr = &tua_unit[unit]; - - if (uptr->CMD & CS1_GO) { - uptr->STATUS |= (ER1_RMR << 16); - return 0; - } - - if (tu_cs2 & CS2_PAT || (tu_mr & 05) == 5) { - uba_set_parity(tua_dib.uba_ctl); - uptr->STATUS |= (ER1_PAR << 16) | DS_ATA; - tu_attn = 1; - fprintf(stderr, "Parity\r\n"); - } - switch(addr & 036) { - case 000: /* TUCS - control */ - sim_debug(DEBUG_DETAIL, &tua_dev, "TU %d Status=%06o %08o\n", unit, uptr->STATUS, - uptr->CMD); - if (access == BYTE && addr & 1) - return 0; - - tu_ie &= ~CS1_IE; - tu_ie |= data & CS1_IE; - tu_ba = ((data << 8) & 0600000) | (tu_ba & 0177777); - uptr->CMD = data & 076; - - if ((data & 1) == 0) { - sim_debug(DEBUG_DETAIL, &tua_dev, "TU%o no go %06o\n", unit, data); - return 0; /* No, nop */ - } - if ((uptr->flags & UNIT_ATT) == 0) { - if (GET_FNC(data) == FNC_DCLR) { - uptr->STATUS = 0; - tu_ie = 0; - tu_attn = 0; - for (i = 0; i < NUM_UNITS_TU; i++) { - if (tua_unit[i].STATUS & DS_ATA) - tu_attn = 1; - } - } - sim_debug(DEBUG_DETAIL, &tua_dev, "TU%o unattached %06o\n", unit, data); - return 0; /* No, nop */ - } - - uba_clr_irq(&tua_dib); - switch (GET_FNC(data)) { - case FNC_NOP: - break; - - case FNC_PRESET: /* read-in preset */ - tu_tcr = 01000; - unit = 0; - uptr = &tua_unit[0]; - /* Fall through */ - - case FNC_READ: /* read */ - case FNC_READREV: /* read w/ headers */ - tu_frame = 0; - tu_tcr |= TC_FCS; - /* Fall through */ - - case FNC_WRITE: /* write */ - case FNC_SPACEF: /* Space forward */ - case FNC_SPACEB: /* Space backward */ - if ((tu_tcr & TC_FCS) == 0) { - uptr->STATUS |= ER1_NEF << 16; - break; - } - /* Fall through */ - - case FNC_ERASE: /* Erase gap */ - case FNC_WTM: /* Write tape mark */ - case FNC_WCHK: /* write check */ - case FNC_REWIND: /* rewind */ - case FNC_UNLOAD: /* unload */ - case FNC_WCHKREV: /* write w/ headers */ - uptr->CMD |= CS1_GO; - uptr->STATUS = DS_PIP; - tu_tcr |= TC_ACCL; - tu_attn = 0; - for (i = 0; i < NUM_UNITS_TU; i++) { - if (tua_unit[i].STATUS & DS_ATA) - tu_attn = 1; - } - CLR_BUF(uptr); - uptr->DATAPTR = 0; - if (GET_FNC(data) >= FNC_XFER) - tu_ie |= CSX_BUSY; - sim_activate(uptr, 100); - break; - - case FNC_DCLR: /* drive clear */ - uptr->CMD &= ~(CS1_GO); - uptr->STATUS = 0; - tu_ie = 0; - tu_attn = 0; - for (i = 0; i < NUM_UNITS_TU; i++) { - if (tua_unit[i].STATUS & DS_ATA) - tu_attn = 1; - } - break; - default: - uptr->STATUS |= (ER1_ILF << 16) | DS_ATA; - tu_attn = 1; - } - sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o AStatus=%06o\n", unit, uptr->CMD); - if (tu_attn && tu_ie) - uba_set_irq(&tua_dib); - break; - case 002: /* TUWC - 172442 - word count */ - if ((tu_ie & (CSX_BUSY)) != 0) { - uptr->STATUS |= (ER1_RMR << 16); - sim_debug(DEBUG_DETAIL, &tua_dev, "TU%o not ready %02o %06o\n", unit, - addr & 077, data); - return 0; - } - if (access == BYTE) { - if (addr & 1) - data = data | (tu_wc & 0377); - else - data = (tu_wc & 0177600) | data; - } - tu_wc = data; - break; - case 004: /* TUBA - 172444 - base address */ - if ((tu_ie & (CSX_BUSY)) != 0) { - uptr->STATUS |= (ER1_RMR << 16); - sim_debug(DEBUG_DETAIL, &tua_dev, "TU%o not ready %02o %06o\n", unit, - addr & 077, data); - return 0; - } - if (access == BYTE) { - if (addr & 1) - data = data | (tu_ba & 0377); - else - data = (tu_ba & 0177600) | data; - } - tu_ba = (tu_ba & 0600000) | (data & 0177776); - break; - - case 006: /* 772446 frame count */ - tu_frame = data; - tu_tcr |= TC_FCS; - break; - - case 010: /* 772450 CS2 */ - if (access == BYTE) { - if (addr & 1) - data = data | tu_cs2; - } - if (data & 040) { - tu_reset(&tua_dev); - } - tu_cs2 = data & (CS2_IR|CS2_PAT|CS2_UAI|CS2_UNIT); - break; - - case 012: /* 772452 status */ - break; - - case 014: /* 772454 error register 1 */ - uptr->STATUS &= 0177777; - uptr->STATUS |= (uint32)data << 16; - break; - case 016: /* 772456 atten summary */ - tu_attn = 0; - if (data & 1) { - for (i = 0; i < 8; i++) - tua_unit[i].STATUS &= ~DS_ATA; - } - break; - - case 020: /* 772460 TCK maintenance */ - fprintf(stderr, "TCK %06o\n\r", data); - break; - case 022: /* 772462 Data buffer */ - if ((tu_cs2 & CS2_IR) == 0) { - tu_cs2 |= CS2_DLT; - break; - } - tu_dba = tu_dbb; - tu_dbb = data; - if ((tu_cs2 & CS2_OR) == 0) - tu_dba = tu_dbb; - tu_cs2 |= CS2_OR; - tu_cs2 &= ~CS2_IR; - break; - case 024: /* 772464 Maintenance register */ - tu_mr = data; - break; - case 026: /* 772466 drive type */ - break; - case 030: /* 772470 - serial no */ - break; - case 032: /* 772472 tape control register */ - if ((tu_tcr & 07) != (data & 07)) - data |= TC_SAC; - else - data &= ~TC_SAC; - tu_tcr = data; - uptr->STATUS &= ~DS_SSC; - break; - case 034: - case 036: - return 1; - default: - uptr->STATUS |= (ER1_ILR << 16) | DS_ATA; - tu_attn = 1; - } - sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o write %02o %06o %06o %06o %06o %06o\n", unit, - addr & 036, data, PC, tu_tcr, tu_mr, uptr->CMD); - return 0; -} - -int -tu_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access) -{ - int tu_drive = tu_tcr & 07; - UNIT *uptr = &tua_unit[tu_drive]; - uint16 temp = 0; - int i; - -#if 0 - if ((tu_cs2 & CS2_UNIT) != 0) { - *data = 0; - sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o read %02o %06o %06o %o\n", - tu_tcr & 7, addr & 036, *data, PC, tu_cs2); - return 0; - } -#endif - - switch(addr & 036) { - case 000: /* 772440 control */ - temp = uptr->CMD & 077; - if ((tu_cs2 & CS2_UNIT) == 0) { - temp |= CS1_DVA; - temp |= (uint16)(tu_ie & CS1_IE); - temp |= (tu_ba & 0600000) >> 8; - if ((tu_ie & CSX_BUSY) == 0 && (uptr->CMD & CS1_IE) == 0) - temp |= CS1_RDY; - if ((uptr->STATUS & (ER1_RMR << 16)) != 0) - temp |= CS1_TRE; - if (tu_cs2 & (CS2_MDPE|CS2_MXF|CS2_PGE|CS2_NEM|CS2_NED|CS2_PE|CS2_WCE|CS2_DLT)) - temp |= CS1_TRE; - if (tu_attn || temp & CS1_TRE) - temp |= CS1_SC; - } - break; - case 002: /* 772442 - word count */ - temp = tu_wc; - break; - case 004: /* 772444 - base addresss */ - temp = (uint16)(tu_ba & 0177776); - break; - case 006: /* 772446 - frame count */ - temp = tu_frame; - break; - case 010: /* 772450 - CS2 */ - temp = tu_cs2; - if ((tu_cs2 & 07) != 0) - temp |= CS2_NED; - break; - case 012: /* 772452 - status */ - if ((tu_cs2 & CS2_UNIT) != 0) - break; - temp = uptr->STATUS & 0177777; - if ((tu_tcr & TC_DENS) == TC_1600) - temp |= DS_PES; - temp |= ((tu_cs2 & CS2_UNIT) == 0) ? DS_DPR : 0; - if (((uptr->STATUS >> 16) & 0177777) != 0) - temp |= DS_ERR; - if ((uptr->flags & UNIT_ATT) != 0) { - if ((uptr->CMD & CS1_IE) == 0) - temp |= DS_MOL; - if (uptr->flags & MTUF_WLK) - temp |= DS_WRL; - if ((uptr->CMD & CS1_GO) == 0 && (uptr->STATUS & DS_PIP) == 0) - temp |= DS_DRY; - if (sim_tape_bot(uptr)) - temp |= DS_BOT; - if (sim_tape_eot(uptr)) - temp |= DS_EOT; - } - break; - case 014: /* 772454 - error register 1 */ - temp = (uptr->STATUS >> 16) & 0177777; - break; - case 016: /* 772456 - atten summary */ - for (i = 0; i < 8; i++) { - if (tua_unit[i].STATUS & DS_ATA) - temp |= 1; - } - break; - case 022: /* 772462 Data buffer */ - if ((tu_cs2 & CS2_OR) == 0) { - tu_cs2 |= CS2_DLT; - break; - } - temp = tu_dba; - tu_dba = tu_dbb; - tu_cs2 &= ~CS2_OR; - tu_cs2 |= CS2_IR; - break; - case 020: /* 772460 - character check */ - break; - case 024: /* 772464 - maintenance */ - temp = tu_mr; - break; - case 026: /* 772466 - drive type */ - if ((tu_cs2 & CS2_UNIT) == 0 && (uptr->flags & UNIT_DIS) == 0) - temp = 0142054; - break; - case 030: /* 772470 - serial no */ - if ((tu_cs2 & CS2_UNIT) == 0) - temp = 020 + (tu_drive + 1); - break; - case 032: /* 772472 - tape control register */ - if ((tu_cs2 & CS2_UNIT) == 0) - temp = tu_tcr; - break; - case 034: - case 036: - return 1; - default: - uptr->STATUS |= (ER1_ILR << 16) | DS_ATA; - tu_attn = 1; - } - *data = temp; - sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o read %02o %06o %06o %o %o\n", - tu_tcr & 7, addr & 036, *data, PC, tu_cs2, uptr->CMD); - if (tu_attn && tu_ie) - uba_set_irq(&tua_dib); - if (tu_cs2 & CS2_PAT) { - uba_set_parity(tua_dib.uba_ctl); - uptr->STATUS |= (ER1_PAR << 16) | DS_ATA; - tu_attn = 1; - } - return 0; -} - -uint16 -tu_vect(struct pdp_dib *dibp) -{ -// tu_ie = 0; - return dibp->uba_vect; -} - -/* Map simH errors into machine errors */ -void tu_error(UNIT * uptr, t_stat r) -{ - DEVICE *dptr = uptr->dptr; - - switch (r) { - case MTSE_OK: /* no error */ - break; - - case MTSE_TMK: /* tape mark */ - uptr->STATUS |= DS_TM; - break; - - case MTSE_WRP: /* write protected */ - uptr->STATUS |= (ER1_NEF << 16) | DS_ATA; - break; - - case MTSE_UNATT: /* unattached */ - case MTSE_BOT: /* beginning of tape */ - case MTSE_EOM: /* end of medium */ - break; - - case MTSE_IOERR: /* IO error */ - case MTSE_FMT: /* invalid format */ - uptr->STATUS |= (ER1_PEF << 16) | DS_ATA; - break; - - case MTSE_RECE: /* error in record */ - uptr->STATUS |= (ER1_DPAR << 16) | DS_ATA; - break; - - case MTSE_INVRL: /* invalid rec lnt */ - uptr->STATUS |= (ER1_FCE << 16) | DS_ATA; - break; - - } - if (uptr->STATUS & DS_ATA) - tu_attn = 1; - uptr->CMD &= ~(CS1_GO); - uptr->STATUS &= ~DS_PIP; - sim_debug(DEBUG_EXP, dptr, "Setting status %d\n", r); - if ((tu_ie & CSX_BUSY) == 0 && (tu_ie & CS1_IE) != 0) - uba_set_irq(&tua_dib); -} - -/* Handle processing of tape requests. */ -t_stat tu_srv(UNIT * uptr) -{ - int unit; - DEVICE *dptr; - t_stat r; - t_mtrlnt reclen; - uint8 ch; - int cc; - int cc_max; - - /* Find dptr, and df10 */ - dptr = uptr->dptr; - unit = uptr - dptr->units; - cc_max = (4 + ((tu_tcr & TC_FMTSEL) == 0)); - tu_tcr &= ~(TC_ACCL); - if ((uptr->flags & UNIT_ATT) == 0) { - tu_error(uptr, MTSE_UNATT); /* attached? */ - return SCPE_OK; - } - - /* Check if waiting for attachment */ - if ((uptr->CMD & CS1_IE) != 0) { - uptr->CMD &= ~(CS1_IE|CS1_GO); - uptr->STATUS = DS_ATA|DS_SSC; - fprintf(stderr, "Tape online\n\r"); - sim_debug(DEBUG_DETAIL, &tua_dev, "%s%o online\n", dptr->name, unit); - tu_error(uptr, MTSE_OK); - return SCPE_OK; - } - - tu_tcr &= ~TC_ACCL; - switch (GET_FNC(uptr->CMD)) { - case FNC_NOP: - case FNC_DCLR: - sim_debug(DEBUG_DETAIL, dptr, "%s%o nop\n", dptr->name, unit); - tu_error(uptr, MTSE_OK); /* Nop */ -// tu_attn = 1; - return SCPE_OK; - - case FNC_PRESET: - case FNC_REWIND: - sim_debug(DEBUG_DETAIL, dptr, "%s%o rewind\n", dptr->name, unit); - if (sim_tape_bot(uptr)) { - uptr->CMD &= ~(CS1_GO); - uptr->STATUS &= ~(DS_PIP); - uptr->STATUS |= DS_SSC|DS_ATA; - tu_error(uptr, sim_tape_rewind(uptr)); - } else { - sim_activate(uptr,4000); - uptr->CMD |= (CS1_IE); - (void)sim_tape_rewind(uptr); - } - return SCPE_OK; - - case FNC_UNLOAD: - sim_debug(DEBUG_DETAIL, dptr, "%s%o unload\n", dptr->name, unit); - uptr->CMD &= ~(CS1_GO); - uptr->STATUS &= ~(DS_PIP); - uptr->STATUS |= DS_SSC|DS_ATA; - tu_error(uptr, sim_tape_detach(uptr)); - return SCPE_OK; - - case FNC_WCHKREV: - case FNC_READREV: - if (BUF_EMPTY(uptr)) { - if ((r = sim_tape_rdrecr(uptr, &tu_buf[0], &reclen, - TU_NUMFR)) != MTSE_OK) { - sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r); - tu_ie &= ~(CSX_BUSY); - if (r == MTSE_BOT) - uptr->STATUS |= ER1_NEF << 16; - tu_error(uptr, r); - } else { - sim_debug(DEBUG_DETAIL, dptr, "%s%o read %d\n", dptr->name, unit, reclen); - uptr->hwmark = reclen; - uptr->DATAPTR = uptr->hwmark-1; - uptr->CPOS = cc_max; - tu_cbuf = 0; - sim_activate(uptr, 120); - } - return SCPE_OK; - } - if (uptr->DATAPTR >= 0) { - tu_frame++; - cc = (8 * (3 - uptr->CPOS)) + 4; - ch = tu_buf[uptr->DATAPTR]; - if (cc < 0) - tu_cbuf |= (uint64)(ch & 0x0f); - else - tu_cbuf |= (uint64)(ch & 0xff) << cc; - uptr->DATAPTR--; - uptr->CPOS--; - if (uptr->CPOS == 0) { - uptr->CPOS = cc_max; - if (GET_FNC(uptr->CMD) == FNC_READREV && - uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf) == 0) { - tu_ie &= ~(CSX_BUSY); - tu_error(uptr, MTSE_OK); - return SCPE_OK; - } - sim_debug(DEBUG_DATA, dptr, "%s%o readrev %012llo\n", - dptr->name, unit, tu_cbuf); - tu_cbuf = 0; - if ((tu_cs2 & CS2_UAI) == 0) - tu_ba -= 4; - tu_wc = (tu_wc + 2) & 0177777; - if (tu_wc == 0) { - tu_ie &= ~(CSX_BUSY); - tu_error(uptr, MTSE_OK); - return SCPE_OK; - } - } - } else { - if (uptr->CPOS != cc_max) - uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf); - tu_ie &= ~(CSX_BUSY); - tu_error(uptr, MTSE_OK); - return SCPE_OK; - } - break; - - case FNC_WCHK: - case FNC_READ: - if (BUF_EMPTY(uptr)) { - if ((r = sim_tape_rdrecf(uptr, &tu_buf[0], &reclen, - TU_NUMFR)) != MTSE_OK) { - sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r); - tu_ie &= ~(CSX_BUSY); - if (r == MTSE_TMK) - uptr->STATUS |= ER1_FCE << 16; - tu_error(uptr, r); - } else { - sim_debug(DEBUG_DETAIL, dptr, "%s%o read %d %d\n", dptr->name, unit, reclen, uptr->pos); - uptr->hwmark = reclen; - uptr->DATAPTR = 0; - uptr->CPOS = 0; - tu_cbuf = 0; - sim_activate(uptr, 120); - } - return SCPE_OK; - } - if ((uint32)uptr->DATAPTR < uptr->hwmark) { - tu_frame++; - cc = (8 * (3 - uptr->CPOS)) + 4; - ch = tu_buf[uptr->DATAPTR]; - if (cc < 0) - tu_cbuf |= (uint64)(ch & 0x0f); - else - tu_cbuf |= (uint64)(ch & 0xff) << cc; - uptr->DATAPTR++; - uptr->CPOS++; - if (uptr->CPOS == cc_max) { - uptr->CPOS = 0; - if (GET_FNC(uptr->CMD) == FNC_READ && - uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf) == 0) { -// if ((uint32)uptr->DATAPTR == uptr->hwmark) - // goto rd_end; - tu_ie &= ~(CSX_BUSY); - tu_error(uptr, MTSE_OK); - return SCPE_OK; - } - sim_debug(DEBUG_DATA, dptr, "%s%o read %012llo %d %06o\n", - dptr->name, unit, tu_cbuf, uptr->DATAPTR, tu_tcr); - tu_cbuf = 0; - if ((tu_cs2 & CS2_UAI) == 0) - tu_ba += 4; - tu_wc = (tu_wc + 2) & 0177777; - if (tu_wc == 0) - goto rd_end; - } - } else { -rd_end: - if (uptr->CPOS != 0) { - sim_debug(DEBUG_DATA, dptr, "%s%o readf %012llo %d\n", - dptr->name, unit, tu_cbuf, uptr->DATAPTR); - uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf); - } - if (tu_frame != 0) - uptr->STATUS |= ER1_FCE << 16; - tu_ie &= ~(CSX_BUSY); - tu_error(uptr, MTSE_OK); - return SCPE_OK; - } - break; - - case FNC_WRITE: - if (BUF_EMPTY(uptr)) { - if (tu_frame == 0) { - uptr->STATUS |= (ER1_NEF << 16) | DS_ATA; - tu_ie &= ~(CSX_BUSY); - tu_error(uptr, MTSE_OK); - return SCPE_OK; - } - if ((uptr->flags & MTUF_WLK) != 0) { - tu_ie &= ~(CSX_BUSY); - tu_error(uptr, MTSE_WRP); - return SCPE_OK; - } - sim_debug(DEBUG_EXP, dptr, "%s%o Init write\n", dptr->name, unit); - uptr->hwmark = 0; - uptr->CPOS = 0; - uptr->DATAPTR = 0; - tu_cbuf = 0; - } - if (tu_frame != 0 && uptr->CPOS == 0) { - if (uba_read_npr(tu_ba, tua_dib.uba_ctl, &tu_cbuf) == 0) { - uptr->CPOS = 010; - goto wr_end; - } else { - if ((tu_cs2 & CS2_UAI) == 0) - tu_ba += 4; - tu_wc = (tu_wc + 2) & 0177777; - } - } - - if (uptr->CPOS == 0) - sim_debug(DEBUG_DATA, dptr, "%s%o write %012llo\n", - dptr->name, unit, tu_cbuf); - /* Write next char out */ - cc = (8 * (3 - (uptr->CPOS & 07))) + 4; - if (cc < 0) - ch = tu_cbuf & 0x0f; - else - ch = (tu_cbuf >> cc) & 0xff; - tu_buf[uptr->DATAPTR] = ch; - uptr->DATAPTR++; - uptr->hwmark = uptr->DATAPTR; - uptr->CPOS = (uptr->CPOS & 010) | ((uptr->CPOS & 07) + 1); - if ((uptr->CPOS & 7) == cc_max) { - uptr->CPOS &= 010; - if (tu_wc == 0) - uptr->CPOS = 010; - } - tu_frame = 0177777 & (tu_frame + 1); - if (tu_frame == 0) { - uptr->CPOS = 010; - tu_tcr &= ~(TC_FCS); - } -wr_end: - if (uptr->CPOS == 010) { - /* Write out the block */ - reclen = uptr->hwmark; - r = sim_tape_wrrecf(uptr, &tu_buf[0], reclen); - sim_debug(DEBUG_DETAIL, dptr, "%s%o Write %d %d\n", - dptr->name, unit, reclen, uptr->CPOS); - uptr->DATAPTR = 0; - uptr->hwmark = 0; - tu_ie &= ~(CSX_BUSY); - tu_error(uptr, r); /* Record errors */ - return SCPE_OK; - } - break; - - case FNC_WTM: - uptr->STATUS &= ~DS_PIP; - uptr->STATUS |= DS_ATA; - if ((uptr->flags & MTUF_WLK) != 0) { - tu_error(uptr, MTSE_WRP); - } else { - tu_error(uptr, sim_tape_wrtmk(uptr)); - } - sim_debug(DEBUG_DETAIL, dptr, "%s%o WTM\n", dptr->name, unit); - return SCPE_OK; - - case FNC_ERASE: - uptr->STATUS &= ~DS_PIP; - uptr->STATUS |= DS_ATA; - if ((uptr->flags & MTUF_WLK) != 0) { - tu_error(uptr, MTSE_WRP); - } else { - tu_error(uptr, sim_tape_wrgap(uptr, 35)); - } - sim_debug(DEBUG_DETAIL, dptr, "%s%o ERG\n", dptr->name, unit); - return SCPE_OK; - - case FNC_SPACEF: - case FNC_SPACEB: - sim_debug(DEBUG_DETAIL, dptr, "%s%o space %o\n", dptr->name, unit, GET_FNC(uptr->CMD)); - /* Always skip at least one record */ - if (GET_FNC(uptr->CMD) == FNC_SPACEF) - r = sim_tape_sprecf(uptr, &reclen); - else - r = sim_tape_sprecr(uptr, &reclen); - switch (r) { - case MTSE_OK: /* no error */ - tu_frame = 0177777 & (tu_frame + 1); - break; - - case MTSE_BOT: /* beginning of tape */ - uptr->STATUS |= ER1_NEF << 16; - /* Fall Through */ - - case MTSE_TMK: /* tape mark */ - case MTSE_EOM: /* end of medium */ - if (tu_frame != 0) - uptr->STATUS |= ER1_FCE << 16; - else - tu_tcr &= ~(TC_FCS); - uptr->STATUS |= DS_ATA; - /* Stop motion if we recieve any of these */ - tu_error(uptr, r); - return SCPE_OK; - } - if (tu_frame == 0) { - uptr->STATUS |= DS_ATA; - tu_error(uptr, MTSE_OK); - return SCPE_OK; - } else { - tu_tcr &= ~(TC_FCS); - sim_activate(uptr, reclen * 100); - } - return SCPE_OK; - } - sim_activate(uptr, 50); - return SCPE_OK; -} - - - -t_stat -tu_reset(DEVICE * dptr) -{ - int i; - - tu_attn = 0; - tu_ie = 0; - tu_ba = tu_frame = 0; - tu_wc = 0; - tu_mr = 0; - tu_cs2 = CS2_IR; - for (i = 0; i < 8; i++) { - tua_unit[i].STATUS = 0; - tua_unit[i].CMD = 0; - } - uba_clr_irq(&tua_dib); - sim_debug(DEBUG_DETAIL, dptr, "%s reset\n", dptr->name); - return SCPE_OK; -} - -void tu_read_word(UNIT *uptr) { - int i, cc, ch; - - tu_cbuf = 0; - for(i = 0; i <= 4; i++) { - cc = (8 * (3 - i)) + 4; - ch = tu_buf[uptr->DATAPTR]; - if (cc < 0) - tu_cbuf |= (uint64)(ch & 0x0f); - else - tu_cbuf |= (uint64)(ch & 0xff) << cc; - uptr->DATAPTR++; - } -} - -/* Boot from given device */ -t_stat -tu_boot(int32 unit_num, DEVICE * dptr) -{ - UNIT *uptr = &dptr->units[unit_num]; - t_mtrlnt reclen; - t_stat r; - uint32 addr; - - if ((uptr->flags & UNIT_ATT) == 0) - return SCPE_UNATT; /* attached? */ - - uptr->CMD = 0; - tu_tcr = unit_num; - r = sim_tape_rewind(uptr); - if (r != MTSE_OK) - return r; - /* Skip first file, which is micro code */ - while (r == MTSE_OK) - r = sim_tape_rdrecf(uptr, &tu_buf[0], &reclen, TU_NUMFR); - - if (r != MTSE_TMK) - return r; - /* Next read in the boot block */ - r = sim_tape_rdrecf(uptr, &tu_buf[0], &reclen, TU_NUMFR); - if (r != MTSE_OK) - return r; - uptr->DATAPTR = 0; - uptr->hwmark = reclen; - - addr = 01000; - while ((uint32)uptr->DATAPTR < uptr->hwmark) { - tu_read_word(uptr); - M[addr] = tu_cbuf; - addr ++; - } - M[036] = tua_dib.uba_addr | (tua_dib.uba_ctl << 18); - M[037] = 0; - M[040] = tu_tcr; - PC = 01000; - return cty_reset(&cty_dev); -} - - -t_stat -tu_attach(UNIT * uptr, CONST char *file) -{ t_stat r; - - uptr->CMD = 0; - uptr->STATUS = 0; - r = sim_tape_attach_ex(uptr, file, 0, 0); - if (r == SCPE_OK && (sim_switches & SIM_SW_REST) == 0) { -// uptr->CMD = CS1_IE|CS1_GO; -// sim_activate_after(uptr, 500000); - uptr->STATUS = DS_ATA|DS_SSC; - tu_attn = 1; - if ((tu_ie & CSX_BUSY) == 0 && (tu_ie & CS1_IE) != 0) - uba_set_irq(&tua_dib); - } - return r; -} - -t_stat -tu_detach(UNIT * uptr) -{ - uptr->STATUS = DS_ATA|DS_SSC; - tu_attn = 1; - if ((tu_ie & CSX_BUSY) == 0 && (tu_ie & CS1_IE) != 0) - uba_set_irq(&tua_dib); - return sim_tape_detach(uptr); -} - - - -t_stat tu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) -{ -fprintf (st, "TU Tape Drives with TM03 formatter. (TU)\n\n"); -fprintf (st, "The TU controller implements the Massbus tape formatter the TM03. TU\n"); -fprintf (st, "options include the ability to set units write enabled or write locked\n\n"); -fprint_set_help (st, dptr); -fprint_show_help (st, dptr); -fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n"); -fprintf (st, "The TU device supports the BOOT command.\n"); -sim_tape_attach_help (st, dptr, uptr, flag, cptr); -fprint_reg_help (st, dptr); -return SCPE_OK; -} - -const char *tu_description (DEVICE *dptr) -{ - return "TU04/05/06/07 Massbus disk controller"; -} - - -#endif