1 /* 2 * vim: filetype=c:tabstop=4:ai:expandtab 3 * SPDX-License-Identifier: ICU 4 * scspell-id: dab0da0d-f62e-11ec-8f5d-80ee73e9b8e7 5 * 6 * --------------------------------------------------------------------------- 7 * 8 * Copyright (c) 2007-2013 Michael Mondy 9 * Copyright (c) 2012-2016 Harry Reed 10 * Copyright (c) 2013-2022 Charles Anthony 11 * Copyright (c) 2021-2022 The DPS8M Development Team 12 * 13 * All rights reserved. 14 * 15 * This software is made available under the terms of the ICU 16 * License, version 1.8.1 or later. For more details, see the 17 * LICENSE.md file at the top-level directory of this distribution. 18 * 19 * --------------------------------------------------------------------------- 20 */ 21 22 // Devices connected to a SCU 23 enum active_dev { ADEV_NONE, ADEV_CPU, ADEV_IOM }; 24 25 typedef struct 26 { 27 vol uint port_enable [N_SCU_PORTS]; // enable/disable 28 29 // Mask registers A and B, each with 32 interrupt bits. 30 vol word32 exec_intr_mask [N_ASSIGNMENTS]; 31 32 // Mask assignment. 33 // 2 mask registers, A and B, each 32 bits wide. 34 // A CPU will be attached to port N. 35 // Mask assignment assigns a mask register (A or B) to a CPU 36 // on port N. 37 // That is, when interrupt I is set: 38 // For reg = A, B 39 // 40 // Mask A, B is set to Off or 0-7. 41 // mask_enable [A|B] says that mask A or B is not off 42 // if (mask_enable) then mask_assignment is a port number 43 vol uint mask_enable [N_ASSIGNMENTS]; // enable/disable 44 vol uint mask_assignment [N_ASSIGNMENTS]; // assigned port number 45 46 vol uint cells [N_CELL_INTERRUPTS]; 47 48 uint lower_store_size; // In K words, power of 2; 32 - 4096 49 uint cyclic; // 7 bits 50 uint nea; // 8 bits 51 uint onl; // 4 bits 52 uint interlace; // 1 bit 53 uint lwr; // 1 bit 54 55 // Note that SCUs had no switches to designate SCU 'A' or 'B', etc. 56 // Instead, SCU "A" is the one with base address switches set for 01400, 57 // SCU "B" is the SCU with base address switches set to 02000, etc. 58 // uint mem_base; // zero on boot scu 59 // mode reg: mostly not stored here; returned by scu_get_mode_register() 60 // int mode; // program/manual; if 1, sscr instruction can set some fields 61 62 // CPU/IOM connectivity; designated 0..7 63 // [CAC] really CPU/SCU and SCU/IOM connectivity 64 struct ports 65 { 66 //bool is_enabled; 67 enum active_dev type; // type of connected device 68 int dev_idx; // index of connected dev (cpu_unit_udx, iom_unit_idx 69 bool is_exp; 70 // which port on the connected device? 71 // if is_exp is false, then only [0] is used. 72 // if true, one connection for each sub-port; -1 if not connected 73 vol int dev_port [N_SCU_SUBPORTS]; 74 vol bool subport_enables [N_SCU_SUBPORTS]; 75 vol bool xipmask [N_SCU_SUBPORTS]; 76 vol int xipmaskval; 77 } ports [N_SCU_PORTS]; 78 79 // system controller mode register 80 word4 id; 81 word18 mode_reg; 82 83 uint elapsed_days; 84 uint steady_clock; // If non-zero the clock is tied to the cycle counter 85 uint bullet_time; 86 uint y2k; 87 int64 user_correction; 88 uint64 last_time; 89 } scu_t; 90 91 extern scu_t scu [N_SCU_UNITS_MAX]; 92 93 extern DEVICE scu_dev; 94 95 int scu_set_interrupt(uint scu_unit_idx, uint inum); 96 void scu_init (void); 97 t_stat scu_sscr (uint scu_unit_idx, UNUSED uint cpu_unit_idx, uint cpu_port_num, word18 addr, 98 word36 rega, word36 regq); 99 t_stat scu_smic (uint scu_unit_idx, uint UNUSED cpu_unit_idx, uint cpu_port_num, word36 rega); 100 t_stat scu_rscr (uint scu_unit_idx, uint cpu_unit_idx, word18 addr, word36 * rega, word36 * regq); 101 int scu_cioc (uint cpu_unit_idx, uint scu_unit_idx, uint scu_port_num, uint expander_command, uint sub_mask); 102 t_stat scu_rmcm (uint scu_unit_idx, uint cpu_unit_idx, word36 * rega, word36 * regq); 103 t_stat scu_smcm (uint scu_unit_idx, uint cpu_unit_idx, word36 rega, word36 regq); 104 void scu_clear_interrupt (uint scu_unit_idx, uint inum); 105 uint scu_get_highest_intr (uint scu_unit_idx); 106 t_stat scu_reset (DEVICE *dptr); 107 t_stat scu_reset_unit (UNIT * uptr, int32 value, const char * cptr, 108 void * desc); 109 void scu_unit_reset (int scu_unit_idx);