1 /* hp_disclib.h: HP MAC/ICD disc controller simulator library declarations 2 3 Copyright (c) 2011-2021, J. David Bryan 4 Copyright (c) 2004-2011, Robert M. Supnik 5 6 Permission is hereby granted, free of charge, to any person obtaining a 7 copy of this software and associated documentation files (the "Software"), 8 to deal in the Software without restriction, including without limitation 9 the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 and/or sell copies of the Software, and to permit persons to whom the 11 Software is furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in 14 all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23 Except as contained in this notice, the names of the authors shall not be 24 used in advertising or otherwise to promote the sale, use or other dealings 25 in this Software without prior written authorization from the authors. 26 27 02-Apr-21 JDB Changed u3-u6 synonyms to title case to avoid conflicts 28 17-Jan-17 JDB Moved "hp2100_defs.h" inclusion to "hp2100_disclib.c" 29 13-May-16 JDB Modified for revised SCP API function parameter types 30 24-Oct-12 JDB Changed CNTLR_OPCODE to title case to avoid name clash 31 07-May-12 JDB Added end-of-track delay time as a controller variable 32 02-May-12 JDB First release 33 09-Nov-11 JDB Created disc controller common library from DS simulator 34 35 36 This file defines the interface between interface simulators and the 37 simulation library for the HP 13037 and 13365 disc controllers. It must be 38 included by the interface-specific modules (DA, DS, etc.). 39 */ 40 41 42 43 /* Program limits */ 44 45 #define DL_MAXDRIVE 7 /* last valid drive number */ 46 #define DL_MAXUNIT 10 /* last legal unit number */ 47 48 #define DL_AUXUNITS 2 /* number of MAC auxiliary units required */ 49 50 #define DL_WPSEC 128 /* words per normal sector */ 51 #define DL_WPFSEC 138 /* words per full sector */ 52 #define DL_BUFSIZE DL_WPFSEC /* required buffer size in words */ 53 54 55 /* Default controller times */ 56 57 #define DL_EOT_TIME 160 /* end-of-track delay time */ 58 #define DL_SEEK_TIME 100 /* seek delay time (per cylinder) */ 59 #define DL_SECTOR_TIME 27 /* intersector delay time */ 60 #define DL_CMD_TIME 3 /* command start delay time */ 61 #define DL_DATA_TIME 1 /* data transfer delay time */ 62 63 #define DL_WAIT_TIME 2749200 /* command wait timeout (1.74 seconds) */ 64 65 66 /* Common per-unit disc drive state variables */ 67 68 #define Cyl u3 /* current drive cylinder */ 69 #define Stat u4 /* current drive status (Status 2) */ 70 #define Op u5 /* current drive operation in process */ 71 #define Phase u6 /* current drive operation phase */ 72 73 74 /* Unit flags and accessors */ 75 76 #define UNIT_V_MODEL (UNIT_V_UF + 0) /* bits 1-0: model ID */ 77 #define UNIT_V_WLK (UNIT_V_UF + 2) /* bits 2-2: write locked (protect switch) */ 78 #define UNIT_V_UNLOAD (UNIT_V_UF + 3) /* bits 3-3: heads unloaded */ 79 #define UNIT_V_FMT (UNIT_V_UF + 4) /* bits 4-4: format enabled */ 80 #define UNIT_V_AUTO (UNIT_V_UF + 5) /* bits 5-5: autosize */ 81 #define DL_V_UF (UNIT_V_UF + 6) /* first free unit flag bit */ 82 83 #define UNIT_M_MODEL 03 /* model ID mask */ 84 85 #define UNIT_MODEL (UNIT_M_MODEL << UNIT_V_MODEL) 86 #define UNIT_WLK (1 << UNIT_V_WLK) 87 #define UNIT_UNLOAD (1 << UNIT_V_UNLOAD) 88 #define UNIT_FMT (1 << UNIT_V_FMT) 89 #define UNIT_AUTO (1 << UNIT_V_AUTO) 90 91 #define UNIT_WPROT (UNIT_WLK | UNIT_RO) /* write protected if locked or read-only */ 92 93 #define GET_MODEL(t) (((t) >> UNIT_V_MODEL) & UNIT_M_MODEL) 94 #define SET_MODEL(t) (((t) & UNIT_M_MODEL) << UNIT_V_MODEL) 95 96 97 /* Status-1 accessors */ 98 99 #define DL_V_S1SPD 13 /* bits 15-13: S/P/D flags */ 100 #define DL_V_S1STAT 8 /* bits 12- 8: controller status */ 101 #define DL_V_S1UNIT 0 /* bits 3- 0: last unit number */ 102 103 #define DL_M_S1UNIT 017 /* unit number mask */ 104 105 #define GET_S1UNIT(v) (((v) >> DL_V_S1UNIT) & DL_M_S1UNIT) 106 107 #define SET_S1SPD(v) ((v) << DL_V_S1SPD) 108 #define SET_S1STAT(v) ((v) << DL_V_S1STAT) 109 #define SET_S1UNIT(v) ((v) << DL_V_S1UNIT) 110 111 112 /* Status-2 accessors (+ = kept in unit status, - = determined dynamically) */ 113 114 #define DL_V_S2ERR 15 /* bits 15-15: (-) any error flag */ 115 #define DL_V_S2DTYP 9 /* bits 12- 9: (-) drive type */ 116 #define DL_V_S2ATN 7 /* bits 7- 7: (+) attention flag */ 117 #define DL_V_S2RO 6 /* bits 6- 6: (-) read only flag */ 118 #define DL_V_S2FMT 5 /* bits 5- 5: (-) format enabled flag */ 119 #define DL_V_S2FAULT 4 /* bits 4- 4: (+) drive fault flag */ 120 #define DL_V_S2FS 3 /* bits 3- 3: (+) first status flag */ 121 #define DL_V_S2SC 2 /* bits 2- 2: (+) seek check flag */ 122 #define DL_V_S2NR 1 /* bits 1- 1: (-) not ready flag */ 123 #define DL_V_S2BUSY 0 /* bits 0- 1: (-) drive busy flag */ 124 125 #define DL_S2ERR (1 << DL_V_S2ERR) 126 #define DL_S2DTYP (1 << DL_V_S2DTYP) 127 #define DL_S2ATN (1 << DL_V_S2ATN) 128 #define DL_S2RO (1 << DL_V_S2RO) 129 #define DL_S2FMT (1 << DL_V_S2FMT) 130 #define DL_S2FAULT (1 << DL_V_S2FAULT) 131 #define DL_S2FS (1 << DL_V_S2FS) 132 #define DL_S2SC (1 << DL_V_S2SC) 133 #define DL_S2NR (1 << DL_V_S2NR) 134 #define DL_S2BUSY (1 << DL_V_S2BUSY) 135 136 #define DL_S2STOPS (DL_S2FAULT | DL_S2SC | DL_S2NR) /* bits that stop drive access */ 137 #define DL_S2ERRORS (DL_S2FAULT | DL_S2SC | DL_S2NR | DL_S2BUSY) /* bits that set S2ERR */ 138 #define DL_S2CPS (DL_S2ATN | DL_S2FAULT | DL_S2FS | DL_S2SC) /* bits cleared by Controller Preset */ 139 140 141 /* Drive properties. 142 143 The controller library supports four different disc drive models with these 144 properties: 145 146 Drive Model Drive Sectors Heads per Cylinders Megabytes 147 Model ID Type per Head Cylinder per Drive per Drive 148 ----- ----- ----- -------- --------- --------- --------- 149 7905 0 2 48 3 411 15 150 7906 1 0 48 4 411 20 151 7920 2 1 48 5 823 50 152 7925 3 3 64 9 823 120 153 154 The Drive Type is reported by the controller in the second status word 155 (Status-2) returned by the Request Status command. 156 157 Model IDs are used in the unit flags to identify the unit's model. For the 158 autosizing feature to work, models must be assigned ascending IDs in order of 159 ascending drive sizes. 160 */ 161 162 #define D7905_MODEL 0 163 #define D7905_SECTS 48 164 #define D7905_HEADS 3 165 #define D7905_CYLS 411 166 #define D7905_TYPE (2 << DL_V_S2DTYP) 167 #define D7905_WORDS (D7905_SECTS * D7905_HEADS * D7905_CYLS * DL_WPSEC) 168 169 #define D7906_MODEL 1 170 #define D7906_SECTS 48 171 #define D7906_HEADS 4 172 #define D7906_CYLS 411 173 #define D7906_TYPE (0 << DL_V_S2DTYP) 174 #define D7906_WORDS (D7906_SECTS * D7906_HEADS * D7906_CYLS * DL_WPSEC) 175 176 #define D7920_MODEL 2 177 #define D7920_SECTS 48 178 #define D7920_HEADS 5 179 #define D7920_CYLS 823 180 #define D7920_TYPE (1 << DL_V_S2DTYP) 181 #define D7920_WORDS (D7920_SECTS * D7920_HEADS * D7920_CYLS * DL_WPSEC) 182 183 #define D7925_MODEL 3 184 #define D7925_SECTS 64 185 #define D7925_HEADS 9 186 #define D7925_CYLS 823 187 #define D7925_TYPE (3 << DL_V_S2DTYP) 188 #define D7925_WORDS (D7925_SECTS * D7925_HEADS * D7925_CYLS * DL_WPSEC) 189 190 #define MODEL_7905 SET_MODEL (D7905_MODEL) 191 #define MODEL_7906 SET_MODEL (D7906_MODEL) 192 #define MODEL_7920 SET_MODEL (D7920_MODEL) 193 #define MODEL_7925 SET_MODEL (D7925_MODEL) 194 195 196 /* Controller types */ 197 198 typedef enum { 199 MAC = 0, 200 ICD, 201 last_type = ICD, /* last valid type */ 202 type_count /* count of controller types */ 203 } CNTLR_TYPE; 204 205 206 /* Controller opcodes */ 207 208 typedef enum { 209 Cold_Load_Read = 000, 210 Recalibrate = 001, 211 Seek = 002, 212 Request_Status = 003, 213 Request_Sector_Address = 004, 214 Read = 005, 215 Read_Full_Sector = 006, 216 Verify = 007, 217 Write = 010, 218 Write_Full_Sector = 011, 219 Clear = 012, 220 Initialize = 013, 221 Address_Record = 014, 222 Request_Syndrome = 015, 223 Read_With_Offset = 016, 224 Set_File_Mask = 017, 225 Invalid_Opcode = 020, 226 Read_Without_Verify = 022, 227 Load_TIO_Register = 023, 228 Request_Disc_Address = 024, 229 End = 025, 230 Wakeup = 026, 231 Last_Opcode = Wakeup /* last valid opcode */ 232 } CNTLR_OPCODE; 233 234 #define DL_OPCODE_MASK 037 235 236 237 /* Controller command phases */ 238 239 typedef enum { 240 start_phase = 0, 241 data_phase, 242 end_phase, 243 last_phase = end_phase /* last valid phase */ 244 } CNTLR_PHASE; 245 246 247 /* Controller status. 248 249 Not all status values are returned by the library. The values not currently 250 returned are: 251 252 - illegal_drive_type 253 - cylinder_miscompare 254 - head_sector_miscompare 255 - io_program_error 256 - sync_timeout 257 - correctable_data_error 258 - illegal_spare_access 259 - defective_track 260 - protected_track 261 */ 262 263 typedef enum { 264 normal_completion = 000, 265 illegal_opcode = 001, 266 unit_available = 002, 267 illegal_drive_type = 003, 268 cylinder_miscompare = 007, 269 uncorrectable_data_error = 010, 270 head_sector_miscompare = 011, 271 io_program_error = 012, 272 sync_timeout = 013, 273 end_of_cylinder = 014, 274 data_overrun = 016, 275 correctable_data_error = 017, 276 illegal_spare_access = 020, 277 defective_track = 021, 278 access_not_ready = 022, 279 status_2_error = 023, 280 protected_track = 026, 281 unit_unavailable = 027, 282 drive_attention = 037 283 } CNTLR_STATUS; 284 285 286 /* Controller execution states */ 287 288 typedef enum { 289 cntlr_idle, /* idle */ 290 cntlr_wait, /* command wait */ 291 cntlr_busy /* busy */ 292 } CNTLR_STATE; 293 294 295 /* Controller command classifications */ 296 297 typedef enum { 298 class_invalid, /* invalid classification */ 299 class_read, /* read classification */ 300 class_write, /* write classification */ 301 class_control, /* control classification */ 302 class_status /* status classification */ 303 } CNTLR_CLASS; 304 305 306 /* Controller clear types */ 307 308 typedef enum { 309 hard_clear, /* power-on/preset hard clear */ 310 soft_clear /* programmed soft clear */ 311 } CNTLR_CLEAR; 312 313 314 /* Controller state variables */ 315 316 typedef struct { 317 CNTLR_TYPE type; /* controller type */ 318 CNTLR_STATE state; /* controller state */ 319 CNTLR_OPCODE opcode; /* controller opcode */ 320 CNTLR_STATUS status; /* controller status */ 321 FLIP_FLOP eoc; /* end-of-cylinder flag */ 322 FLIP_FLOP eod; /* end-of-data flag */ 323 uint32 spd_unit; /* S/P/D flags and unit number */ 324 uint32 file_mask; /* file mask */ 325 uint32 retry; /* retry counter */ 326 uint32 cylinder; /* cylinder address */ 327 uint32 head; /* head address */ 328 uint32 sector; /* sector address */ 329 uint32 verify_count; /* count of sectors to verify */ 330 uint32 poll_unit; /* last unit polled for attention */ 331 uint16 *buffer; /* data buffer pointer */ 332 uint32 index; /* data buffer current index */ 333 uint32 length; /* data buffer valid length */ 334 UNIT *aux; /* MAC auxiliary units (controller and timer) */ 335 int32 eot_time; /* end-of-track read delay time */ 336 int32 seek_time; /* per-cylinder seek delay time */ 337 int32 sector_time; /* intersector delay time */ 338 int32 cmd_time; /* command response time */ 339 int32 data_time; /* data transfer response time */ 340 int32 wait_time; /* command wait time */ 341 } CNTLR_VARS; 342 343 344 typedef CNTLR_VARS *CVPTR; /* pointer to controller state variables */ 345 346 /* Controller state variables initialization. 347 348 The parameters are: 349 350 ctype - type of the controller (CNTLR_TYPE) 351 bufptr - pointer to the data buffer 352 auxptr - pointer to the auxiliary units (MAC only; NULL for ICD) 353 */ 354 355 #define CNTLR_INIT(ctype,bufptr,auxptr) \ 356 (ctype), cntlr_idle, End, normal_completion, \ 357 CLEAR, CLEAR, \ 358 0, 0, 0, 0, 0, 0, 0, 0, \ 359 (bufptr), 0, 0, (auxptr), \ 360 DL_EOT_TIME, DL_SEEK_TIME, DL_SECTOR_TIME, \ 361 DL_CMD_TIME, DL_DATA_TIME, DL_WAIT_TIME 362 363 364 365 /* Disc library global controller routines */ 366 367 extern t_bool dl_prepare_command (CVPTR cvptr, UNIT *units, uint32 unit_limit); 368 extern UNIT *dl_start_command (CVPTR cvptr, UNIT *units, uint32 unit_limit); 369 extern void dl_end_command (CVPTR cvptr, CNTLR_STATUS status); 370 extern t_bool dl_poll_drives (CVPTR cvptr, UNIT *units, uint32 unit_limit); 371 extern t_stat dl_service_drive (CVPTR cvptr, UNIT *uptr); 372 extern t_stat dl_service_controller (CVPTR cvptr, UNIT *uptr); 373 extern t_stat dl_service_timer (CVPTR cvptr, UNIT *uptr); 374 extern void dl_idle_controller (CVPTR cvptr); 375 extern t_stat dl_clear_controller (CVPTR cvptr, UNIT *uptr, CNTLR_CLEAR clear_type); 376 extern t_stat dl_load_unload (CVPTR cvptr, UNIT *uptr, t_bool load); 377 378 /* Disc library global utility routines */ 379 380 extern CNTLR_CLASS dl_classify (CNTLR_VARS cntlr); 381 extern const char *dl_opcode_name (CNTLR_TYPE controller, CNTLR_OPCODE opcode); 382 extern const char *dl_phase_name (CNTLR_PHASE phase); 383 384 /* Disc library global VM routines */ 385 386 extern t_stat dl_attach (CVPTR cvptr, UNIT *uptr, char *cptr); 387 extern t_stat dl_detach (CVPTR cvptr, UNIT *uptr); 388 extern t_stat dl_set_model (UNIT *uptr, int32 value, char *cptr, void *desc); 389