From 4991701ee696ffec4063c9eb36e59e9a6812b6f3 Mon Sep 17 00:00:00 2001 From: AZBevier Date: Thu, 3 Mar 2022 16:25:48 -0700 Subject: [PATCH] SEL32: Add new SEL32 simulator. --- SEL32/README.md | 112 + SEL32/installs/.gitignore | 6 + SEL32/installs/README.md | 172 + SEL32/installs/loaddma1x67.ini | 142 + SEL32/installs/loaddma21b.ini | 239 + SEL32/installs/loadscsi21b.ini | 399 ++ SEL32/installs/loadscsi3x.ini | 168 + SEL32/installs/rundma1x67.ini | 215 + SEL32/installs/rundma21b.ini | 70 + SEL32/installs/runscsi21b.ini | 248 + SEL32/installs/runscsi3x.ini | 219 + SEL32/installs/sel32load1x.ini | 245 + SEL32/installs/sel32run1x.ini | 210 + SEL32/installs/user36erunp2.ini | 327 ++ SEL32/installs/user36esdtp2.ini | 364 ++ SEL32/sel32_chan.c | 2971 +++++++++++ SEL32/sel32_clk.c | 714 +++ SEL32/sel32_com.c | 1333 +++++ SEL32/sel32_con.c | 799 +++ SEL32/sel32_cpu.c | 7636 +++++++++++++++++++++++++++ SEL32/sel32_defs.h | 535 ++ SEL32/sel32_disk.c | 3482 ++++++++++++ SEL32/sel32_ec.c | 1909 +++++++ SEL32/sel32_fltpt.c | 1637 ++++++ SEL32/sel32_hsdp.c | 3790 +++++++++++++ SEL32/sel32_iop.c | 301 ++ SEL32/sel32_lpr.c | 677 +++ SEL32/sel32_mfp.c | 357 ++ SEL32/sel32_mt.c | 1645 ++++++ SEL32/sel32_scfi.c | 1997 +++++++ SEL32/sel32_scsi.c | 2068 ++++++++ SEL32/sel32_sys.c | 1722 ++++++ SEL32/tests/SetupNet | 635 +++ SEL32/tests/cpu.icl | 114 + SEL32/tests/diag.ini | 226 + SEL32/tests/diag.tap | Bin 0 -> 4144792 bytes SEL32/tests/sel32_test.ini | 226 + Visual Studio Projects/SEL32.vcproj | 565 ++ Visual Studio Projects/Simh.sln | 9 + doc/sel32_doc.doc | Bin 0 -> 96256 bytes makefile | 26 +- 41 files changed, 38508 insertions(+), 2 deletions(-) create mode 100644 SEL32/README.md create mode 100644 SEL32/installs/.gitignore create mode 100644 SEL32/installs/README.md create mode 100644 SEL32/installs/loaddma1x67.ini create mode 100644 SEL32/installs/loaddma21b.ini create mode 100644 SEL32/installs/loadscsi21b.ini create mode 100644 SEL32/installs/loadscsi3x.ini create mode 100644 SEL32/installs/rundma1x67.ini create mode 100644 SEL32/installs/rundma21b.ini create mode 100644 SEL32/installs/runscsi21b.ini create mode 100644 SEL32/installs/runscsi3x.ini create mode 100644 SEL32/installs/sel32load1x.ini create mode 100644 SEL32/installs/sel32run1x.ini create mode 100644 SEL32/installs/user36erunp2.ini create mode 100644 SEL32/installs/user36esdtp2.ini create mode 100644 SEL32/sel32_chan.c create mode 100644 SEL32/sel32_clk.c create mode 100644 SEL32/sel32_com.c create mode 100644 SEL32/sel32_con.c create mode 100644 SEL32/sel32_cpu.c create mode 100644 SEL32/sel32_defs.h create mode 100644 SEL32/sel32_disk.c create mode 100644 SEL32/sel32_ec.c create mode 100644 SEL32/sel32_fltpt.c create mode 100644 SEL32/sel32_hsdp.c create mode 100644 SEL32/sel32_iop.c create mode 100644 SEL32/sel32_lpr.c create mode 100644 SEL32/sel32_mfp.c create mode 100644 SEL32/sel32_mt.c create mode 100644 SEL32/sel32_scfi.c create mode 100644 SEL32/sel32_scsi.c create mode 100644 SEL32/sel32_sys.c create mode 100755 SEL32/tests/SetupNet create mode 100644 SEL32/tests/cpu.icl create mode 100644 SEL32/tests/diag.ini create mode 100644 SEL32/tests/diag.tap create mode 100644 SEL32/tests/sel32_test.ini create mode 100755 Visual Studio Projects/SEL32.vcproj mode change 100644 => 100755 Visual Studio Projects/Simh.sln create mode 100644 doc/sel32_doc.doc diff --git a/SEL32/README.md b/SEL32/README.md new file mode 100644 index 00000000..83d9bf0b --- /dev/null +++ b/SEL32/README.md @@ -0,0 +1,112 @@ + +# SEL32 Concept/32 Simulator + +This is a working simulator for the SEL Concept/32 computer. The current +version is for the SEL 32/27, 32/67, 32/77, 32/87, 32/97, V6, and V9 +computers. All of the processors except for the 32/77 can run the Gould +diags. Operational support for the 32/77 computers may be added in the +future. + +# SEL Concept/32 + +This simulator is capable of running UTX2.1A, UTX2.1B, MPX 1.5F, MPX 3.4, +MPX 3.5, MPX 3.6, and SEL diagnostics. Actually any software using the SEL +instruction set should work. It is capable of creating a disk image for the +O/S from a UTX or MPX SDT tape. The disk image can be booted, initialized, +and can run many of the UTX and MPX utilities and programs. Ethernet is +supported on UTX and will be added to MPX in the future. Eight terminals +can be used to access MPX or UTX via Telnet port 4747. The sumulator has +support for excess 64 floating point arithmetic and passes the 32/27 and +32/67 FP diags. UTX is the SEL version of System V Unix and BSD Unix +ported to the V6 and V9 processors. UTX utilizes the basemode instruction +set and a virtual memory system supported by the V6 & V9 CPUs. The system +needs further testing to solidify the SEL32 simulator code in all of the +supported environmenets and hardware configurations. + +# SEL32 installation configuration files in the installs directory: + +The installs directory contains the simh command files to install and run +multiple UTX, MPX1X, and MPX3X systems. The install tape images are in +the tapes directory and created disks are in the dsk directory. The dsk +and tapes directories are initially missing but will be created during +the installation. The required tape(s) are read from the repo at +https://github.com/AZBevier/SEL32-installs when the installation +simh command file is run. The tapes are tar gzipped files that are +extracted during the installation. Only the tape(s) required for the +specific UTX or MPX installation are downloaded. A bootable disk is +created in the dsk directory. This disk can then be booted and the +installed operating system executed by using a second simh command file. +See the README.md file in the install directory for a description of the +available configurations. + +# SEL32 test configuration files in the tests directory: + +The tests directory contains the SEL32 machine diagnostic command file and +bootable tape. They are used by the simh makefile to test the SEL32 +simulator after it built. All of the instruction set and operating modes +are validated by the diagnostic. There is a pass/failure indication from +the diagnostic. The command file sel32_test.ini is used by the makefile. +The command file diag.ini can be run at any time by the user to rerun the +diagnostics. There is an example of the initial configuration file (ICL) +used by the diagnostic. The machine configuration is loaded by the diag +or the UTX or MPX operating system at boot time. See the MPX manuals at +bitsavers.org/pdf/sel/sel32_mpx for using MPX 1X or 3X. + +#sel32_test.ini - diag.tap; type "../sel32_test.ini" or run from makefile. +Auto run by sel32 makefile to validate build or can be run at any time +to validate system functionality. + +#diag.ini - diag.tap; type "../sel32 diag.ini" to run. +This is the SEL32 memory diagnostic that validates the SEL32 instruction +set and memory management sumulated hardware. Any errors are reported +to the terminal. Different cpu models can be configured to test various +cpu model features. + +Available Level One Diagnostic boot tape in tests directory: +diag.ini - command file to start diags. Type "../sel32 diag.ini" +diag.tap - bootable level one diagnostic tape w/auto testing. + Set cpu type to 32/27, 32/67, 32/87, 32/97, V6 or V9. All + cpu models now run all diagnostics provided on the + diagnostic tape. Running DEXP stand alone causes input + to stop after a few characters are entered. More testing + is still required. + + CV.CSL - Firmware control diag. Disabled in auto testing. + CV.CP1 - CPU diag part 1 runs OK. + CV.CP2 - CPU diag part 2 runs OK. + CV.CP3 - CPU diag part 3 runs OK. + CV.EAD - Effective address diag runs OK. + CV.BRD - Base register instruction diag runs OK + Not supported on 32/27. + CV.INT - Interrupt diag runs OK. + CV.TRP - Traps diag runs OK. + CV.CMD - Cache/Shadow diag. Disabled in auto testing. + CN.MMM - Non virtual memory diag runs OK. + VM.MMM - Virtual memory diag for V6 & V9 runs OK. + CV.IPT - IPU trap diag. Disabled in auto testing. + CV.CSD - WCS read/write trap diag. Disabled in auto testing. + CV.CON - Operators Console runs all tests for all CPUs. + CV.DXP - Diagnostic executive for level 2 diags. OK in batch. + 67.FPT - Level two floating point diag runs under DXP OK. + CV.ITD - Level two interval timer diag runs under DXP OK. + + Set GPR[0] = 0xffffffff before booting from tape to disable the + auto test and go to the Diagnostic Overlay Loader (DOL>) prompt. + Testing is extremely difficult without any source for the + diagnostics. Updates to follow as tests are corrected. + +Other MPX versions support: + I have recently received some old MPX 3.X save tapes. Using + these I have been able to hand build a MPX3.6 SDT tape that + can be used to install MPX3.6. Once installed, the system can + be used to build a new user SDT tape and install it elsewhere. + Both based and non-based O/S images can be created. More images + for installation will be made available in the future as I work + my way through the save tapes. I still do not have a master SDT + tape for any of the MPX 1.X or MPX 3.X systems. I have a + 1600/6250 BPI tape drive that can read 9 track tapes and convert + them to .tap files. If you have a master SDT, I would be very + thankfull. Please keep looking. + +James C. Bevier +02/28/2022 diff --git a/SEL32/installs/.gitignore b/SEL32/installs/.gitignore new file mode 100644 index 00000000..7ba7fdd8 --- /dev/null +++ b/SEL32/installs/.gitignore @@ -0,0 +1,6 @@ +#tape files are dynamically downloaded from github.com/AZBevier/SEL32-installs as they are needed. +/tape +#disk files are created by the simh installation command files. These are SEL32 bootable disks. +/dsk +#ignore lp output from MPX-1X install. +lprout diff --git a/SEL32/installs/README.md b/SEL32/installs/README.md new file mode 100644 index 00000000..82df5685 --- /dev/null +++ b/SEL32/installs/README.md @@ -0,0 +1,172 @@ + +# SEL32 Concept/32 Simulator + +The installs directory contains the simh command files to install and run +multiple UTX, MPX1X, and MPX3X systems. The install tape images are in +the tapes directory and created disks are in the dsk directory. The dsk +and tapes directories are initially missing but will be created during +the installation. The required tape(s) are read from the repo at +https://github.com/AZBevier/SEL32-installs when the installation +simh command file is run. The tapes are tar gzipped files that are +extracted during the installation. Only the tape(s) required for the +specific UTX or MPX installation are downloaded. A bootable disk is +created in the dsk directory. This disk can then be booted and the +installed operating system executed by using a second simh command file. + +This method of installation replaces the prebuilt disks from previous +releases. This allows more versions to be supplied in the minimum +amount of storage space. Minimal or no user input is required to +create the bootable system. The command files are in pairs, one to do +the install and one to execute the installed system. Some MPX systems +also contain some of the NBC software environment. See the NBC project +at github.com/AZBevier/nbc for all of the NBC software. See the MPX +manuals at bitsavers.org/pdf/sel/sel32_mpx for using MPX 1X or 3X. + +# SEL32 installation configuration files in the install directory: + +-------------------- + +#sel32load1x.ini - sel32sdt.tap; type "../sel32 sel32load1x.ini +This is a minimal MPX 1.5F installation to a UDP/DPII 300 MB disk. It +will initialize the disk and install an MPX bootable system. The disk +image is in the dsk directory named sel32disk. + +#sel32run1x.ini - dsk/sel32disk; type "../sel32 sel32run1x.ini" to run. +The disk is booted up to the TSM> prompt logged in as "SYSTEM". Use +@@A to log into the system console. + +-------------------- + +#loaddma1x67.ini - mpx1xsdt.tap; type "../sel32 loaddma1x67.ini +This is an MPX 1.5F installation to a UDP/DPII 300 MB disk. It will +initialize the disk and install an MPX bootable system. The disk +image is in the dsk directory named mpx1xdma0. Once the MPX software +is loaded an MPX command file is executed that runs the SYSGEN program +to create a new MPX O/S image. That system is then restarted to +install the new image to the disk as the new bootable image. The +system reboots to the new image, logs in as SYSTEM and exits TSM. +Use @@A to relogin to the console. + +#rundma1x67.ini - dsk/mpx1xdma0; type "../sel32 rundma1x67.ini" to run. +The disk is booted up to the TSM> prompt and logged in as "SYSTEM". +MPX can be accessed from a second Linux screen by using the command +"telnet localhost 4747". This will bring up the "ENTER OWNERNAME +AND KEY:". Any name is valid, but SYSTEM should be used. At the +"TSM>" prompt, type "EXIT" to exit TSM. Use ^G to get the login +prompt when the "RING IN FOR SERVICE" message is displayed. + +-------------------- + +#loaddma21b.ini - utx21b1.tap, utx21b2.tap, utx21b3.tap; +type "../sel32 loaddma21b.ini" to install UTX 21b to UDP/DPII disk. +This is an automated installation of UTX 21b to disk. Two disks, +21bdisk0.dma and 21bdisk1.dma are initialized and then the file +systems are created and loaded. Tape 1 loads "/" and tape 2 and 3 +loads "/usr.POWERNODE" filesystems. The system boots from tape and +installs the root filesystem. The system restarts and boots from +the new root filesystem where the 2nd & 3rd tapes are then loaded to +/usr.POWERNODE. A third empty file system is created and mounted +as /usr/POWERNODE/src. The second disk is one large filesystem and is +mounted under /home. Several files are modified during installation +to allow the system to be booted into multiuser mode. Only the user +"root" is created and is the only allowable user login. + +#rundma21b.ini - dsk/21bdisk0.dma & dsk/21bdisk1.dma; +type "../sel32 rundma21b.ini" to run the installed UTX system. +The disk is booted up to the "login:" prompt for the user to login +as "root" in multi-user mode. + +-------------------- + +#loadscsi21b.ini - utx21b1.tap, utx21b2.tap, utx21b3.tap; +type "../sel32 loadscsi21b.ini" to install UTX 21b to MFP SCSI disks. +This is an automated installation of UTX 21b to disk. Two disks, +scsidiska0 and scsidiska1 are initialized and then the file systems +are created and loaded. Tape 1 loads root "/" and tapes 2 and 3 +loads "/usr.POWERNODE" filesystem. The system boots from tape and +installs the root filesystem. The system restarts and boots from +the new root filesystem where the 2nd & 3rd tapes are then loaded to +/usr.POWERNODE. A third empty file system is created and mounted +as /usr/POWERNODE/src. The second disk is one large filesystem and is +mounted under /home. Several files are modified during installation +to allow the system to be booted into multiuser mode. Only the user +"root" is created and is the only allowable user login. + +#rundscsi21b.ini - dsk/scsidiska0 & dsk/scsidiska1; +type "../sel32 rundscsi21b.ini" to run the installed UTX system. +The disk is booted up to the "login:" prompt for the user to login +as "root" in multi-user mode. + +-------------------- + +#loadscsi3x.ini - mpxsdt69.tap; +type "../sel32 loadscsi3x.ini" to install MPX 3.4 to MFP SCSI disks. +This is an automated installation of MPX 3.4 to disk. Two 300MB disks, +mpx3xsba0.dsk and mpx3xsbb0.dsk are initialized and then the file +systems are created and loaded. The user sdt tape contains system +and user files that are loaded to multiple directories. The second +disk is initialized and formatted and only a system directory defined. +The install is exited and @@A is used to login into MPX. The username +SYSTEM is used to login into TSM without a password. + +#runscsi3x.ini - dsk/mpx3xsba0.dsk & dsk/mpx3csbb0.dsk; + - dsk/scsi35m1disk0 & dsk/scsi35m2disk0; +type "../sel32 rundscsi3x.ini" to run the installed MPX system. +The disk is booted up to the MPX message "Press Attention for TSM". +Use @@A to get login prompt. Login as SYSTEM. The WORK volume will +be mounted along with the SYSTEM volume and the system is ready for +use. MPX can be accessed from a second Linux screen by using the +command "telnet locallhost 4747". This will bring up the "Connected +to the SEL-32 simulator COMC device, line 0". Use ^G as the wakeup +character to get the "ENTER YOUR OWNERNAME:" login prompt. Any name +is valid, but SYSTEM should be used. At the "TSM>" prompt, type +"EXIT" to exit TSM. Use ^G to get the login prompt when the "RING +IN FOR SERVICE" message is displayed. + +-------------------- + +#user36esdtp2.ini - user36esdtp2.tap; +type "../sel32 user36esdtp2.ini" to install MPX 3.6 to HSDP disks. +This is an automated installation of MPX 3.6 to disk. A 300MB system +disk volume (user36p2udp0) and a 600MB work disk volume (user36s1udp1) +are initialized and then the file systems are created and loaded using +the volmgr. The user sdt tape contains system and user files that +are loaded to multiple directories. The second disk is initialized +and formatted and only a system directory defined. The disk is mounted +as the volume "work" as the 2nd disk drive. The installed MPX system +also has 2 scsi disks configured into the system. Two 700MB SCSI disks +are created, but they are not initialized and no directories are +created. The usage of these disks is left as an exercise for the user. +A third HSDP 600MD disk is also configured in MPX, but not used. The +user can provide other data volumes that can be mounted for use on the +system. The install is exited and @@A can be used to login into MPX. +The username SYSTEM is used to login into TSM without a password. Any +username is valid until an m.key file is created for valid user logins. + +#user36erunp2.ini - dsk/user36p2udp0 & dsk/user36s1udp1; +type "../sel32 user36erunp2.ini" to run the installed MPX 3.6 system. +The disk is booted up to the MPX message "Press Attention for TSM". +@@A is used to get the login prompt and the user is logged in as SYSTEM. +The WORK volume will be mounted along with the SYSTEM volume and the +system is ready for use at the TSM> prompt. The install tape also has +some of the NBC development system. A complete installation tape is +available at github.com/azbevier/nbc. + +-------------------- + +Other MPX versions support: + +I have recently received some old MPX 3.X save tapes. Using these +I have been able to hand build a MPX3.6 SDT tape that can be used +to install MPX3.6. Once installed, the system can be used to build +a new user SDT tape and install it elsewhere. Both based and non- +based O/S images can be created. More images for installation will +be made available in the future as I work my way through the save +tapes. I still do not have a master SDT tape for any of the MPX 1.X +or MPX 3.X systems. I have a 1600/6250 BPI tape drive that can read +9 track tapes and convert them to .tap files. If you have a master +SDT, I would be very thankfull. Please keep looking. + +James C. Bevier +02/27/2022 + diff --git a/SEL32/installs/loaddma1x67.ini b/SEL32/installs/loaddma1x67.ini new file mode 100644 index 00000000..a0d3e343 --- /dev/null +++ b/SEL32/installs/loaddma1x67.ini @@ -0,0 +1,142 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX - Ver 1.5F hardware configuration +; CPU - 32/67 4M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; DMA - 0800 2311/2314 Disk Processor II +; dma0 MH300 Model 8127 300MB MHD +; dma0 <-> dsk/mpx1xdma0.dsk +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/mpx1xsdt.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; Set directory for disk images +mkdir dsk +mkdir tapes +; Set tape image filename +set env FILE=mpx1xsdt.tap +; Set github.com URL for downloading files +set env GITURL=https://github.com/AZBevier/SEL32-installs/raw/main/tapes/ +if exist "tapes/%FILE%" goto exists +if not exist "tapes/%FILE%" echof "file %FILE% missing, trying %FILE%.tgz" +cd tapes +if exist "%FILE%.tgz" goto nocurl +echof "fetching %FILE%.tgz file from github.com\n" +;curl -LJO https://raw.githubusercontent.com/AZBevier/sims/master/SEL32/tests/tapes/%FILE%.tgz +curl -LJO %GITURL%/%FILE%.tgz +if not exist "%FILE%.tgz" echof "FAILED - file %FILE% not available"; exit 1 +:nocurl +echof "untar %FILE%.tgz file\n" +tar -xzf %FILE%.tgz +cd .. +:exists +echof "file %FILE% present, doing install" +; +; Set debug output +; set debug -n sel.log +; +; CPU type and memory size +set CPU 32/67 4M +; +; RTC realtime clock at 7f06 +set RTC 60 +set RTC enable +; +; ITM interval timer at 7f04 +set ITM 3840 +; +; IOP at channel 7e00 +set iop enable +set iop0 dev=7e00 +; +; COM 8-Line at 7ec0 +set coml enable +set coml0 dev=7ec0 +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +; +; Enable telnet sessions on port 4747 +set comc enable +at comc 4747 +; +; LPR at 7ef8 +set lpr enable +; LPR output file +at lpr lprout +; +; EC ethernet at 0e00 +; Support not available yet +;set ec enable +;set ec mode=2 +;set ec0 dev=0e00 +;at ec tap:tap0 +; set mac address to cause ec to be attached +;set ec MAC=08:00:5D:01:01:20 +; +; CON Console at 7efc +; enable console +set con enable +set con0 dev=7efc +; +; MTA Buffered tape processor at 1000 +set mta enable +set mta0 dev=1000 +; Attach install sdt tape file +set mta0 locked +at mta0 tapes/mpx1xsdt.tap +; +; DMA disk processor II/UDP at 800 +set dma enable +set dma0 dev=800 +set dma0 type=MH300 +; Attach diskfile +at dma0 -i dsk/mpx1xdma0.dsk +; +; set console switches +deposit CSW 0 +; +; allow cpu idle +set cpu idle +; wait for expected output from simulator, then enter this text +expect "COLD OR WARM START (C OR W)?" send "C\r"; continue +; Set expect script for auto time entry on MPX at OPCOM prompt +expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r@@A"; continue +;expect "" after=800000, delay=4000, send "@@A"; continue +expect "??" send "X\r"; continue +expect "TSM>" send "A4 SLO=UT\r"; continue +expect "TSM>" send "A3 IN=M91000,TAP\r"; continue +expect "TSM>" send "PAGE 0\r"; continue +expect "TSM>" send "FILEMGR\r"; continue +; restore all files +expect "FIL>" send "RESTORE\r"; continue +expect "FIL>" send "EXIT\r"; continue +; sysgen new mpx image +expect "TSM>" send "MAKSIMH1\r"; continue +; restart to new image +expect "TSM>" send "RESTART SEL32SY1,DEFAULT\r"; continue +expect " RESTART...DO YOU WANT TO REBOOT(Y/N)?" send "Y\r"; continue +expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r@@A"; continue +expect "??" send "X\r"; continue +expect "TSM>" send "WHO\r"; continue +expect "TSM>" send "EXIT\r"; continue +expect "RING IN FOR SERVICE" send "\r^E" +; Boot from mag tape +bo mta0 +detach all +quit diff --git a/SEL32/installs/loaddma21b.ini b/SEL32/installs/loaddma21b.ini new file mode 100644 index 00000000..2decf0df --- /dev/null +++ b/SEL32/installs/loaddma21b.ini @@ -0,0 +1,239 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; UTX - Ver 2.1B hardware configuration +; CPU - V6 8M Sel32 Powernode +; MFP - 7e00 Model 8001 IOP Processor Controller +; DMA - 0800 2311/2314 Disk Processor II +; dma0 Model 8858 340MB +; dma0 <-> dsk/21bdisk0.dma +; dma1 Model 8858 340MB +; dma1 <-> dsk/21bdisk1.dma +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ee0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 50 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/utx21b1.tap +; EC - 0e00 Model 8516 Ethernet +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +set env IP=192.168.1.5 +;====================================================== +; Set directory for disk images +mkdir dsk +mkdir tapes +; Set tape image filename +set env FILE1=utx21b1.tap +; Set github.com URL for downloading files +set env GITURL=https://github.com/AZBevier/SEL32-installs/raw/main/tapes/ +if exist "tapes/%FILE1%" goto exists1 +if not exist "tapes/%FILE1%" echof "file %FILE1% missing, trying %FILE1%.tgz" +cd tapes +if exist "%FILE1%.tgz" goto nocurl1 +echof "fetching %FILE1%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE1%.tgz +if not exist "%FILE1%.tgz" echof "FAILED - file %FILE1% not available"; exit 1 +:nocurl1 +echof "untar %FILE1%.tgz file\n" +tar -xzf %FILE1%.tgz +cd .. +:exists1 +echof "file %FILE1% present, doing install" +; +; Set directory for disk images +mkdir dsk +mkdir tapes +; Set tape image filename +set env FILE2=utx21b2.tap +if exist "tapes/%FILE2%" goto exists2 +if not exist "tapes/%FILE2%" echof "file %FILE2% missing, trying %FILE2%.tgz" +cd tapes +if exist "%FILE2%.tgz" goto nocurl2 +echof "fetching %FILE2%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE2%.tgz +if not exist "%FILE2%.tgz" echof "FAILED - file %FILE2% not available"; exit 1 +:nocurl2 +echof "untar %FILE2%.tgz file\n" +tar -xzf %FILE2%.tgz +cd .. +:exists2 +echof "file %FILE2% present, doing install" +; +; Set directory for disk images +mkdir dsk +mkdir tapes +; Set tape image filename +set env FILE3=utx21b3.tap +if exist "tapes/%FILE3%" goto exists3 +if not exist "tapes/%FILE3%" echof "file %FILE% missing, trying %FILE%.tgz" +cd tapes +if exist "%FILE3%.tgz" goto nocurl3 +echof "fetching %FILE3%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE3%.tgz +if not exist "%FILE3%.tgz" echof "FAILED - file %FILE% not available"; exit 1 +:nocurl3 +echof "untar %FILE3%.tgz file\n" +tar -xzf %FILE3%.tgz +cd .. +:exists3 +echof "file %FILE3% present, doing install" +; +set RTC 50 +set CPU V6 8M +set RTC enable +set iop enable +set iop0 dev=7e00 +set dma enable +set dma0 dev=800 +set dma0 type=8858 +set dma1 type=8858 +set coml0 dev=7ee0 +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +set con enable +set con0 dev=7efc +set mta enable +set mta0 dev=1000 +set lpr enable +set comc enable +at comc 4747 +set ec enable +set ec mode=2 +set ec0 dev=0e00 +; set mac address to cause ec to be attached +set ec MAC=08:00:5D:01:01:20 +;at lpr lprout +;set cpu idle +; +deposit BOOTR[7] 42 +deposit BOOTR[6] 800 +set mta0 locked +at mta0 tapes/utx21b1.tap +at dma0 -i dsk/21bdisk0.dma +at dma1 -i dsk/21bdisk1.dma +at ec tap:tap0 +expect "#" continue +expect "#" send "prep /dev/rdk0a\r"; continue +expect "Ready to prep /dev/rdk0a" send "yes\r"; continue +expect "Which option ?" send "2\r"; continue +expect "Warning: some data may be lost on the pack, proceed ?" send "yes\r"; continue +expect "Rebuild UTX flaw map from diagnostic flaw map ?" send "yes\r"; continue +expect "Please select a drive type:" send "8\r"; continue +expect "#" continue +expect "#" continue +expect "How many spare tracks should be allocated " send "\r"; continue +expect "Do you really want to do this ?" send "yes\r"; continue +expect "Which option ?" send "3\r"; continue +expect "Which option ?" send "2\r"; continue +expect "(a) Starting Cylinder <0>?" send "0\r"; continue +expect "(a) Size In Blocks <25344> or Ending Cylinder ?" send "c65\r"; continue +expect "(a) Swap ?" send "\r"; continue +expect "(b) Starting Cylinder <66>?" send "66\r"; continue +expect "(b) Size In Blocks <20352> or Ending Cylinder ?" send "c118\r"; continue +expect "(b) Swap ?" send "\r"; continue +expect "(c) Starting Cylinder <0>?" send "\r"; continue +expect "(c) Size In Blocks <271488> or Ending Cylinder ?" send "\r"; continue +expect "(c) Swap ?" send "\r"; continue +expect "(d) Starting Cylinder <119>?" send "119\r"; continue +expect "(d) Size In Blocks <70272> or Ending Cylinder ?" send "c301\r"; continue +expect "(d) Swap ?" send "\r"; continue +expect "(e) Starting Cylinder <302>?" send "302\r"; continue +expect "(e) Size In Blocks <100224> or Ending Cylinder ?" send "C706\r"; continue +expect "(e) Swap ?" send "\r"; continue +expect "(f) Starting Cylinder <563>?" send "0\r"; continue +expect "(f) Size In Blocks <55296> or Ending Cylinder ?" send "0\r"; continue +expect "(f) Swap ?" send "\r"; continue +expect "(g) Starting Cylinder <0>?" send "\r"; continue +expect "(g) Size In Blocks <0> or Ending Cylinder ?" send "\r"; continue +expect "(g) Swap ?" send "\r"; continue +expect "(h) Starting Cylinder <0>?" send "\r"; continue +expect "(h) Size In Blocks <0> or Ending Cylinder ?" send "\r"; continue +expect "(h) Swap ?" send "\r"; continue +expect "Do you really want to do this ?" send "yes\r"; continue +expect "Which option ?" send "0\r"; continue +expect "Which option ?" send "0\r"; continue +expect "#" send "prep /dev/rdk1a\r"; continue +expect "Ready to prep /dev/rdk1a" send "yes\r"; continue +expect "Which option ?" send "2\r"; continue +expect "Warning: some data may be lost on the pack, proceed ?" send "yes\r"; continue +expect "Rebuild UTX flaw map from diagnostic flaw map ?" send "yes\r"; continue +expect "Please select a drive type:" send "8\r"; continue +expect "#" continue +expect "#" continue +expect "How many spare tracks should be allocated " send "\r"; continue +expect "Do you really want to do this ?" send "yes\r"; continue +expect "Which option ?" send "0\r"; continue +expect "#" send "newfs /dev/dk0a\r"; continue +expect "#" continue +expect "#" send "mount /dev/dk0a /mnt\r"; continue +expect "#" send "cd /mnt\r"; continue +expect "#" send "restore r\r"; continue +expect "#" send "cd /\r"; continue +expect "#" send "umount /dev/dk0a\r"; continue +expect "#" send "halt\r"; continue +bo mta0 +deposit BOOTR[7] 2 +at mta0 tapes/utx21b2.tap +; do not allow cpu to idle +; works around a reboot issue with UTX +; if allowed, installation will hang checking root file system +set cpu noidle +;at mta0 tapes/utx21b2-3.tap +expect "#" continue +expect "#" send "newfs /dev/dk0d\r"; continue +expect "#" continue +expect "#" send "newfs /dev/dk0e\r"; continue +expect "#" continue +expect "#" send "mount /dev/dk0d /usr.POWERNODE\r"; continue +expect "#" send "rm /restoresymtable\r"; continue +expect "#" send "cd /usr.POWERNODE\r"; continue +expect "#" send "restore rf /dev/rmt0\r"; continue +expect "then enter tape name (default: /dev/rmt0)" at mta0 tapes/utx21b3.tap; send "\r"; continue +expect "#" send "rm /usr.POWERNODE/restoresymtable\r"; continue +expect "#" send "cd /\r"; continue +expect "#" send "/ranlib.sh\r"; continue +expect "#" send 'echo "/dev/dk0e /usr.POWERNODE/src 4.3 rw,noquota 1 3" >>/etc/fstab\r'; continue +expect "echo" continue +;expect "#" send "mount /dev/dk0e /usr.POWERNODE/src\r"; at mta0 tapes/utx21b_src.tap; continue +;expect "#" send "cd /usr.POWERNODE/src\r"; continue +;expect "#" send "tar xf /dev/rmt0\r"; continue +expect "#" send "ed /etc/rc.boot\r"; continue +expect "1522" send "/preen/\r"; continue +expect "#" send "s/#/ /\r.+1\r"; continue +expect "#" continue +expect "echo" send "d\r"; 'expect "\r\n" send "/noname/\r"; continue' ; continue +expect "/bin/hostname noname" send "s/noname/%HOST%/\rw\rq\r"; continue +expect "#" send "ed /etc/hosts\r"; continue +expect "128" send "/sysname/\r"; continue +expect "sysname" continue +expect "sysname" send "d\r"; 'expect "\r\n" send "i\r%IP% %HOST%\r.\rw\rq\r"; continue'; continue +expect "#" send "ed /etc/rc.local\r" ; continue +expect "3849" send "/echo 'Setup/\r"; continue +expect "#" send "s/# //\r"; 'expect "\r\n" send "/en0 inet/\r"; continue' ; continue +expect "#" continue +expect "#" send "s/# //\r"; 'expect "\r\n" send "w\rq\r"; continue'; continue +expect "#" continue +expect "#" send "newfs /dev/dk1c\r"; continue +expect "#" continue +expect "#" send "mkdir /home\r"; continue +expect "#" send 'echo "/dev/dk1c /home 4.3 rw,noquota 2 1" >>/etc/fstab\r'; continue +expect "echo" continue +expect "#" send 'bin/echo "stty intr \003" >>/.profile\r'; continue +expect "#" send "mount /dev/dk1c /home\r"; continue +expect "#" send "df\r"; continue +;expect "#" send "reboot\r"; continue +expect "#" send "halt\r"; continue +expect "sim>" send "q\r"; continue +;Boot from disk dma0 +bo dma0 +;stop simh execution +quit diff --git a/SEL32/installs/loadscsi21b.ini b/SEL32/installs/loadscsi21b.ini new file mode 100644 index 00000000..4ea00ac4 --- /dev/null +++ b/SEL32/installs/loadscsi21b.ini @@ -0,0 +1,399 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; UTX - Ver 2.1B hardware configuration +; CPU - V6 8M Sel32 Powernode +; MFP - 7e00 Model 8002 Multi-Function Processor +; SBA - 7e00/7e08 MFP SCSI Disk controller +; sba0 Model 8821 300MB +; sba0 <-> dsk/scsidiska0 +; sba1 Model 8821 300MB +; sba1 <-> dsk/scsidiska1 +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ee0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 50 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/utx21b1.tap +; EC - 0e00 Model 8516 Ethernet +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +;set env IP=192.168.0.20 +set env IP=192.168.1.5 +;====================================================== +; Set debug output +;set debug -n sel.log +;set debug stderr +; +; Set directory for disk images +mkdir dsk +mkdir tapes +; Set tape image filename +set env FILE1=utx21b1.tap +if exist "tapes/%FILE1%" goto exists1 +; Set github.com URL for downloading files +set env GITURL=https://github.com/AZBevier/SEL32-installs/raw/main/tapes/ +if not exist "tapes/%FILE1%" echof "file %FILE1% missing, trying %FILE1%.tgz" +cd tapes +if exist "%FILE1%.tgz" goto nocurl1 +echof "fetching %FILE1%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE1%.tgz +if not exist "%FILE1%.tgz" echof "FAILED - file %FILE1% not available"; exit 1 +:nocurl1 +echof "untar %FILE1%.tgz file\n" +tar -xzf %FILE1%.tgz +cd .. +:exists1 +echof "file %FILE1% present, doing install" +; +; Set tape image filename +set env FILE2=utx21b2.tap +if exist "tapes/%FILE2%" goto exists2 +if not exist "tapes/%FILE2%" echof "file %FILE2% missing, trying %FILE2%.tgz" +cd tapes +if exist "%FILE2%.tgz" goto nocurl2 +echof "fetching %FILE2%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE2%.tgz +if not exist "%FILE2%.tgz" echof "FAILED - file %FILE2% not available"; exit 1 +:nocurl2 +echof "untar %FILE2%.tgz file\n" +tar -xzf %FILE2%.tgz +cd .. +:exists2 +echof "file %FILE2% present, doing install" +; +; Set tape image filename +set env FILE3=utx21b3.tap +if exist "tapes/%FILE3%" goto exists3 +if not exist "tapes/%FILE3%" echof "file %FILE% missing, trying %FILE%.tgz" +cd tapes +if exist "%FILE3%.tgz" goto nocurl3 +echof "fetching %FILE3%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE3%.tgz +if not exist "%FILE3%.tgz" echof "FAILED - file %FILE% not available"; exit 1 +:nocurl3 +echof "untar %FILE3%.tgz file\n" +tar -xzf %FILE3%.tgz +cd .. +:exists3 +echof "file %FILE3% present, doing install" +; +; CPU type and memory +;set CPU 32/97 4M +;set CPU V6 4M +set CPU V6 8M +;set CPU V9 4M +;set CPU V9 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;set cpu history=10000 +; useful options +;set cpu debug=exp;irq;xio;trap;cmd +;;set cpu debug=cmd;exp;irq;trap;xio +;set cpu debug=cmd;irq;trap;exp +;;set cpu debug=irq;trap;exp;xio +;set cpu debug=irq;xio +; +; RTC realtime clock +set RTC enable +; address is 7f06 +set RTC 50 +;set RTC 60 +; RTC debug options +;set RTC debug=cmd +; +; ITM interval timer +; address is 7f04 +; set itm 3840 +;set ITM debug=cmd +; +; IOP at channel 7e00 +; useful options +;set iop debug=cmd;exp +;set iop debug=cmd +; make iop online +;set iop enable +; set iop channel address +;set iop0 dev=7e00 +; +; MFP at channel 7e00 +; useful options +;set mfp debug=cmd;exp +; make mfp online +set mfp enable +; set mfp channel address +set mfp0 dev=7e00 +;set mfp0 dev=7600 +; +; EC at channel 0e00 +; useful options +;set ec debug=cmd;exp +; set the mode +set EC mode=1 +; make ec online +set ec enable +; set ec channel address +set ec0 dev=0e00 +at ec tap:tap0 +; +; COM 8-Line +;set com debug=cmd; +;set coml0 enable +;set coml1 enable +;set coml2 enable +;set coml3 enable +;set coml4 enable +;set coml5 enable +;set coml6 enable +;set coml7 enable +; +; Enable telnet sessions on port 4747 +;set comc enable +;at comc 4747 +; +; LPR +;set lpr debug=cmd;detail +;set lpr enable +set lpr enable +; LPR output file +;at lpr lprout +at lpr lprout +; +; CON Console +; useful options +;set con debug=cmd;exp;detail +;set con debug=cmd;exp; +; enable console +set con enable +; set console address +; set con0 enable +set con0 dev=7efc +; set con1 enable +set con1 dev=7efd +; +; MTA Buffered tape processor +;set mta debug=cmd;exp;detail;data +; useful options +;set mta debug=cmd;detail;exp +; +; enable the MTA to change channel +set mta enable +; set mt channel +set mta0 dev=1000 +; attach in/out tape files +;at mta0 mpxsdt.tap +;at mta0 nbctape.tap +set mta0 locked +at mta0 tapes/utx21b1.tap +;at mta0 utx21a1.tap +;at mta1 temptape.tap +;at mta1 utx21a2.tap +;at mta2 output.tap +;at mta0 sim32sdt.tap +;at mta0 diag.tap +; +; DMA disk processor II/UDP +;set dma enable +; set disk chan to 0800 +;set dma0 dev=800 +; set disk type to MPX MH300 +;set dma0 type=MH300 +; set disk type to UTX 9346 +;set dma0 type=9346 +;set dma0 type=8155 +;set dma0 type=8887 +;set dma0 type=8148 +; Attach diskfile +;at dma0 utx0disk +;at dma0 utx1disk +;at dma0 sim32disk +;at dma0 diagdisk +; +;set dma debug=cmd;exp;detail;data +; useful options +;set dma debug=cmd;exp +;set dma debug=exp;cmd;detail +; +; SDA SCFI disk processor +;set sda debug=cmd;exp;data;detail +; Attach diskfiles +;at sda0 scsidisk0 +;at sda1 scsidisk1 +; +; SBA MFP SCSI bus 1 disk processor +set sba enable +; set disk chan to 7600 +;set sba0 dev=7600 +set sba0 dev=7e00 +;set sba1 dev=7e08 +; set disk type to MPX MH300 +set sba0 type=8821 +set sba1 type=8821 +;set sba0 type=SD300 +;set sba0 type=SD150 +;set sba0 type=8820 +;set sba debug=cmd;exp;data;detail +;set sba debug=cmd;exp;detail +; Attach diskfiles +at sba0 -i dsk/scsidiska0 +at sba1 -i dsk/scsidiska1 +; +; SBB MFP SCSI bus 2 disk processor +;;set sbb enable +; set disk chan to 7640 +;set sbb0 dev=7640 +;;set sbb0 dev=7e40 +; set disk type to MPX MH300 +;set sbb0 type=SD300 +;set sbb0 type=8821 +;;set sbb0 type=SD150 +;set sbb0 type=8820 +;set sbb debug=cmd;exp;data;detail +;;set sbb debug=cmd;exp;detail +; Attach diskfiles +;;at sbb0 scsidiskb0 +;at sbb1 scsi1disk +; +; DPA high speed disk processor +; enable the HSDP to change channel +;set dpa enable +; set channel addr +;set dpa0 dev=800 +; set disk type to UTX 8887 +;set dpa0 type=8887 +; Attach diskfiles +;at dpa0 utxdsk.dsk +;at dpa0 utx0hsdp +;at dpa1 utx1hsdp +; +;set dpa debug=cmd;detail;exp +; useful options +;set dpa debug=cmd;exp;detail +; +; set console switches +deposit CSW 0 +; +;UTX boot tape options +;set GPR 7 to 0x00 to boot in multi-user mode +;set GPR 7 to 0x01 to prompt for unix filename +;set GPR 7 to 0x02 to boot in single user mode +;set GPR 7 to 0x10 to disable swapping and paging +;set GPR 7 to 0x20 to boot from device specified in GPR6 +;set GPR 7 to 0x40 to allow progress messages on boot +;deposit BOOTR[7] 40 +;deposit BOOTR[7] 52 +deposit BOOTR[7] 42 +;deposit BOOTR[7] 2 +;deposit BOOTR[6] 800 +;deposit BOOTR[0] ffffffff +; +; Set register content at boot for SEL diagnostics +; uncomment next line to get diag loader prompt +;deposit bootr[0] ffffffff +;deposit bootr[1] 0 +;deposit bootr[2] 0 +; +; do not allow cpu to idle +; works around a reboot issue with UTX +; if allowed, installation will hang checking root file system +set cpu noidle +; +expect "#" continue +expect "#" send "prep /dev/rsd0a\r"; continue +expect "Ready to prep /dev/rsd0a" send "yes\r"; continue +expect "Which option ?" send "2\r"; continue +expect "Please select a drive type:" send "7\r"; continue +expect "#" continue +expect "#" continue +expect "#" continue +expect "Do you really want to do this ?" send "yes\r"; continue +expect "Which option ?" send "0\r"; continue +; +expect "#" continue +expect "#" continue +expect "#" send "prep /dev/rsd1a\r"; continue +expect "Which option ?" send "2\r"; continue +expect "Please select a drive type:" send "7\r"; continue +expect "#" continue +expect "#" continue +expect "#" continue +expect "Do you really want to do this ?" send "yes\r"; continue +expect "Ready to prep /dev/rsd1a" send "yes\r"; continue +expect "Which option ?" send "0\r"; continue +expect "#" continue +expect "#" continue +expect "#" send "newfs /dev/sd0a\r"; continue +expect "#" continue +expect "#" send "newfs /dev/sd0d\r"; continue +expect "#" continue +expect "#" send "newfs /dev/sd0e\r"; continue +expect "#" continue +expect "#" send "mount /dev/sd0a /mnt\r"; continue +expect "#" send "cd /mnt\r"; continue +expect "#" send "restore r\r"; continue +expect "#" send 'bin/echo "/dev/sd0a / 4.3 rw,noquota 1 1" >etc/fstab\r'; continue +expect "#" send 'bin/echo "#/dev/sd0b is the default swap partition" >>etc/fstab\r'; continue +expect "#" send 'bin/echo "/dev/sd0d /usr.POWERNODE 4.3 rw,noquota 1 2" >>etc/fstab\r'; continue +expect "#" send "cd /\r"; continue +expect "#" send "umount /dev/sd0a\r"; continue +expect "#" send "halt\r"; continue +;expect "#" send "/mnt/etc/reboot\r"; continue +; Boot from mag tape +bo mta0 +; Set expect script to load UTX 2.1B +deposit BOOTR[7] 2 +at mta0 tapes/utx21b2.tap +;set sba debug=cmd;exp;data;detail +; +expect "#" continue +expect "#" send "mount /dev/sd0d /usr.POWERNODE\r"; continue +expect "#" send "rm /restoresymtable\r"; continue +expect "#" send "cd /usr.POWERNODE\r"; continue +;expect "#" send "mkdir src\r"; continue +expect "#" send "restore rf /dev/rmt0\r"; continue +expect "then enter tape name (default: /dev/rmt0)" at mta0 tapes/utx21b3.tap; send "\r"; continue +expect "#" send "rm /usr.POWERNODE/restoresymtable\r"; continue +expect "#" send "cd /\r"; continue +expect "#" send "/ranlib.sh\r"; continue +;expect "#" send 'echo "/dev/sd0d /usr.POWERNODE 4.3 rw,noquota 1 2" >>/etc/fstab\r'; continue +expect "#" send 'echo "/dev/sd0e /usr.POWERNODE/src 4.3 rw,noquota 1 3" >>/etc/fstab\r'; continue +expect "echo" continue +;expect "#" send "mount /dev/sd0e /usr.POWERNODE/src\r"; at mta0 tapes/utx21b_src.tap; continue +;expect "#" send "cd /usr.POWERNODE/src\r"; continue +;expect "#" send "tar xf /dev/rmt0\r"; continue +expect "#" send "ed /etc/rc.boot\r"; continue +expect "1522" send "/preen/\r"; continue +expect "#" send "s/#/ /\r.+1\r"; continue +expect "#" continue +expect "echo" send "d\r"; 'expect "\r\n" send "/noname/\r"; continue' ; continue +expect "/bin/hostname noname" send "s/noname/%HOST%/\rw\rq\r"; continue +expect "#" send "ed /etc/hosts\r"; continue +expect "128" send "/sysname/\r"; continue +expect "sysname" continue +expect "sysname" send "d\r"; 'expect "\r\n" send "i\r%IP% %HOST%\r.\rw\rq\r"; continue'; continue +expect "#" send "ed /etc/rc.local\r" ; continue +expect "3849" send "/echo 'Setup/\r"; continue +expect "#" send "s/# //\r"; 'expect "\r\n" send "/en0 inet/\r"; continue' ; continue +expect "#" continue +expect "#" send "s/# //\r"; 'expect "\r\n" send "w\rq\r"; continue'; continue +expect "#" continue +expect "#" send "newfs /dev/sd1c\r"; continue +expect "#" continue +expect "#" send "mkdir /home\r"; continue +expect "#" send 'echo "/dev/sd1c /home 4.3 rw,noquota 2 1" >>/etc/fstab\r'; continue +expect "echo" continue +expect "#" send "mount /dev/sd1c /home\r"; continue +expect "#" send "df\r"; continue +expect "#" send 'bin/echo "stty intr \003" >>/.profile\r'; continue +expect "#" send 'bin/echo "Run runscsi21b.ini to run installed UTX 21b"\r'; continue +;expect "#" send "reboot\r"; continue +expect "#" send "halt\r"; continue +expect "sim>" send "q\r"; continue +;Boot from disk sba0 +bo sba0 +;stop simh execution +quit diff --git a/SEL32/installs/loadscsi3x.ini b/SEL32/installs/loadscsi3x.ini new file mode 100644 index 00000000..f6df2f55 --- /dev/null +++ b/SEL32/installs/loadscsi3x.ini @@ -0,0 +1,168 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX - Ver 3.4 hardware configuration +; CPU - 32/67 8M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; MFP - 7600 Model 8002 Multi Function Processor +; SBA - 7600 MFP SCSI Disk Controller +; sba0 SD300 Model 8828 300MB MHD +; sba0 <-> dsk/mpx3xsba0.dsk +; SBA - 7640 MFP SCSI Disk Controller +; sbb0 SD300 Model 8828 300MB MHD +; sbb0 <-> dsk/mpx3xsbb0.dsk +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/mpxsdt69.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set HOST simulator +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; Set directory for disk images +mkdir dsk +mkdir tapes +; Set tape image filename +set env FILE=mpxsdt69.tap +; Set github.com URL for downloading files +set env GITURL=https://github.com/AZBevier/SEL32-installs/raw/main/tapes/ +if exist "tapes/%FILE%" goto exists +if not exist "tapes/%FILE%" echof "file %FILE% missing, trying %FILE%.tgz" +cd tapes +if exist "%FILE%.tgz" goto nocurl +echof "fetching %FILE%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE%.tgz +if not exist "%FILE%.tgz" echof "FAILED - file %FILE% not available"; exit 1 +:nocurl +echof "untar %FILE%.tgz file\n" +tar -xzf %FILE%.tgz +cd .. +:exists +echof "file %FILE% present, doing install" +; +; Set directory for disk +mkdir dsk +; Set debug output +; set debug -n sel.log +; +; CPU type and memory size +set CPU 32/67 8M +;set CPU 32/97 8M +; +; RTC realtime clock at 7f06 +set RTC 60 +set RTC enable +; +; ITM interval timer at 7f04 +set ITM 3840 +; +; IOP at channel 7e00 +set iop enable +set iop0 dev=7e00 +; +; MFP at channel 7600 +set mfp enable +set mfp0 dev=7600 +; +; COM 8-Line at 7ec0 +set coml enable +set coml0 dev=7ec0 +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +; +; Enable telnet sessions on port 4747 +set comc enable +at comc 4747 +; +; LPR0 at 7ef8 +set lpr enable +; LPR output file +;at lpr lprout +; +; EC ethernet at 0e00 +; Support not available yet +;set ec enable +;set ec mode=2 +;set ec0 dev=0e00 +;at ec tap:tap0 +; set mac address to cause ec to be attached +;set ec MAC=08:00:5D:01:01:20 +; +; CON Console at 7efc +set con enable +set con0 dev=7efc +; +; MTA Buffered tape processor at 1000 +set mta enable +set mta0 dev=1000 +; Attach install sdt tape file +set mta0 locked +at mta0 tapes/mpxsdt69.tap +; +; SBA MFP SCSI buss 1 disk processor at 7600 +set sba enable +; set disk chan to 7600 +set sba0 dev=7600 +set sba0 type=SD300 +; Attach diskfile +at sba0 -i dsk/mpx3xsba0.dsk +; +; SBB MFP SCSI buss 2 disk processor at 7640 +set sbb enable +set sbb0 dev=7640 +set sbb0 type=SD300 +; Attach diskfile +at sbb0 -i dsk/mpx3xsbb0.dsk +; +; set console switches +deposit CSW 0 +; +; allow cpu idle +set cpu idle +; +; wait for expected output from simulator, then enter this text +expect "ENTER" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r"; continue +expect "FMT>" send "INITIALIZE DEVICE=DM7600 DEST=Y DISC=DM0300 CON=N\r"; continue +expect "FMT>" send "FORMAT DEVICE=DM7600 VOLUME=SYSTEM MAXRES=7000 CON=N\r"; continue +expect "ENTER SYSTEM VOLUME CHANNEL AND SUBADDRESS: " send "7600\r"; continue +expect "VOL>" send "CREATE D SYSTEM ENTRIES=2000\r"; continue +; restore system +expect "VOL>" send "RESTORE VOL=SYSTEM\r"; continue +; restore object, object_e, oldobj +expect "VOL>" send "RESTORE VOL=SYSTEM\r"; continue +; restore bin, doc, nblib, sample +expect "VOL>" send "RESTORE VOL=SYSTEM\r"; continue +expect "VOL>" send "REWIND\r"; continue +expect "VOL>" send "EXIT\r"; continue +; initialize 2nd disk +;expect "SYSTEM READY... PRESS ATTENTION FOR TSM..." send "@@A"; continue +expect "SYSTEM READY... PRESS ATTENTION FOR TSM..." send after=500000 delay=6000 "HIT @@A"; continue +;expect "" send after=1500000, delay=4000, " HIT @@A"; continue +expect "ENTER YOUR OWNERNAME:" send "SYSTEM\r"; continue +expect "TSM>" send "WHO\r"; continue +expect "TSM>" send "@SYSTEM(SYSTEM)J.VFMT\r"; continue +expect "FMT>" send "INITIALIZE DEV=DM7640 DES=Y DIS=DM0300 CON=N\r"; continue +expect "FMT>" send "FORMAT DEV=DM7640 VOL=WORK MAXRE=7000 CON=N\r"; continue +expect "TSM>" send "MOUNT WORK ON DM7640 OPTI=PUBLIC\r"; continue +expect "TSM>" send "VOLMGR\r"; continue +expect "VOL>" send "CREATE D @WORK^SYSTEM ENTRIES=1000\r"; continue +expect "VOL>" send "EXIT\r"; continue +expect "TSM>" send "!STAT VOL\r"; continue +;;expect "TSM>" send "WHO\r"; continue +expect "TSM>" send "EXIT\r"; continue +expect "RING IN FOR SERVICE" send "\r^E" +; Boot from mag tape +bo mta0 +det all +quit diff --git a/SEL32/installs/rundma1x67.ini b/SEL32/installs/rundma1x67.ini new file mode 100644 index 00000000..1a5cd49c --- /dev/null +++ b/SEL32/installs/rundma1x67.ini @@ -0,0 +1,215 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX - Ver 1.5F hardware configuration +; CPU - 32/67 4M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; DMA - 0800 2311/2314 Disk Processor II +; dma0 MH300 Model 8127 300MB MHD +; dma0 <-> dsk/mpx1xdma0.dsk +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/mpx1xsdt.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; Set directory for disk images +mkdir dsk +; Set debug output +; set debug -n sel.log +; +; CPU type and memory size +set CPU 32/67 4M +; +; RTC realtime clock at 7f06 +set RTC 60 +set RTC enable +; +; ITM interval timer at 7f04 +set ITM 3840 +; +; IOP at channel 7e00 +set iop enable +set iop0 dev=7e00 +; +; COM 8-Line at 7ec0 +set coml enable +set coml0 dev=7ec0 +; Set debug output +;set debug -n sel.log +; +; CPU type and memory size +;set CPU 32/27 4M +;set CPU 32/87 4M +set CPU 32/67 4M +;set CPU 32/97 4M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;set cpu history=10000 +; +; RTC realtime clock +; RTC debug options +;set RTC debug=cmd +; device address is 7f06 +set RTC enable +;set RTC 50 +set RTC 60 +; +; ITM interval timer +; ITM debug options +;set ITM debug=cmd +; device address is 7f04 +set ITM 3840 +; +; IOP at channel 7e00 +; IOP debug options +;set iop debug=cmd;exp +set iop enable +; set iop channel address +set iop0 dev=7e00 +; +; MFP at channel 7e00 +; Only supported on MPX-3X and UTX +; MFP debug options +;set mfp debug=cmd;exp +; enable MFP to change address +;set mfp enable +; set mfp channel address +;set mfp0 dev=7e00 +;set mfp0 dev=7600 +; +; COM 8-Line +; COM debug options +;set coml debug=cmd;exp;xio +; enable COML to change address +set coml enable +; MPX 3X wants 7ea0 +; set coml0 dev=7ea0 +; MPX 1X wants 7ec0 +set coml0 dev=7ec0 +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +; +; COMC 8-Line Mux +; COMC debug options +;set comc debug=cmd +; COMC has no address +set comc enable +; Enable telnet sessions on port 4747 +at comc 4747 +; +; LPR at 7ef8 +; LPR debug options +;set lpr debug=cmd;detail +; enable LPR to change address +set lpr enable +; attach LPR output file +at lpr lprout +; +; EC ethernet 0e00 +; Support not available yet +; EC debug options +;set ec debug=cmd;exp;xio;detail;irq +;set ec enable +;set ec0 dev=0e00 +;set ec mode=2 +;at ec tap:tap0 +; set mac address to cause ec to be attached +;set ec MAC=08:00:5D:01:01:20 +; +; CON Console +; CON debug options +;set con debug=cmd;exp;detail +; enable console +set con enable +; set console address +set con0 dev=7efc +; +; MTA Buffered tape processor +; MTA debug options +;set mta debug=cmd;exp;detail;data +; enable MTA to change channel +set mta enable +; set mta channel address +set mta0 dev=1000 +; Attach in/out tape files +;at mta0 output.tap +;set mta0 locked +; +; DMA disk processor II/UDP +; DMA debug options +;set dma debug=cmd;exp;detail;data +; enable DMA to change channel +set dma enable +; set channel address +set dma0 dev=800 +; set disk type to MPX MH300 (8887) +; must match sysgen assignment +set dma0 type=MH300 +; Attach diskfile +at dma0 dsk/mpx1xdma0.dsk +; +; SDA SCFI disk processor +; Only supported on MPX-1X +; SDA debug options +;set sda debug=cmd;exp;data;detail +; enable SCFI to change channel +;set sda enable +; set channel address +;set sda0 dev=800 +; set disk type to MPX SG120 +; must match sysgen assignment +;set sda0 type=SG120 +; Attach diskfiles +;at sda0 dsk/mpx1xsda0.dsk +; +; DPA high speed disk processor +; DPA debug options +;set dpa debug=cmd;exp;data;detail +; enable DPA to change channel +;set dpa enable +; set channel address +;set dpa0 dev=800 +; set disk type to MPX MH300 (8887) +; must match sysgen assignment +;set dpa0 type=MH300 +; Attach diskfiles +;at dpa0 dsk/mpx1xdpa0.dsk +; +; set console switches +deposit CSW 0 +; +;SEL32 boot register options +;deposit BOOTR[7] 0 +;deposit BOOTR[6] 800 +;; +; allow cpu idle +set cpu idle +; Set expect script for auto time entry on MPX at OPCOM prompt +;expect haltafter=20000 +; wait for expected output from simulator, then enter this text +expect " DO YOU WISH TO USE *SEL32SY1* DEFAULT IMAGE(Y/N)?" send "Y\r"; continue +expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r@@A"; GO +;expect "" send "@@A"; continue +expect "" send after=400000, delay=6000, " @@A" +expect "??" send "X\r"; continue +expect "TSM>" send "WHO\r"; continue +;expect "TSM>" send "EXIT\r"; continue +; +; Boot from disk +bo dma0 diff --git a/SEL32/installs/rundma21b.ini b/SEL32/installs/rundma21b.ini new file mode 100644 index 00000000..2454145e --- /dev/null +++ b/SEL32/installs/rundma21b.ini @@ -0,0 +1,70 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; UTX - Ver 2.1B hardware configuration +; CPU - V6 8M Sel32 Powernode +; MFP - 7e00 Model 8001 IOP Processor Controller +; DMA - 0800 2311/2314 Disk Processor II +; dma0 Model 8858 340MB +; dma0 <-> dsk/21bdisk0.dma +; dma1 Model 8858 340MB +; dma1 <-> dsk/21bdisk1.dma +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ee0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 50 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <-> not assigned +; EC - 0e00 Model 8516 Ethernet +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +set env IP=192.168.1.5 +;====================================================== +;set debug -n sel.log +mkdir dsk +set RTC 50 +set CPU V6 8M +set RTC enable +set iop enable +set iop0 dev=7e00 +set dma enable +set dma0 dev=800 +set dma0 type=8858 +set dma1 type=8858 +set coml0 dev=7ee0 +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +set con enable +set con0 dev=7efc +set mta enable +set mta0 dev=1000 +set lpr enable +set comc enable +at comc 4747 +set ec enable +set ec mode=1 +set ec0 dev=0e00 +; set mac address to cause ec to be attached +set ec MAC=08:00:5D:01:01:20 +;set ec debug=cmd;exp;xio;detail;irq +;at lpr lprout +set cpu idle +; +;deposit BOOTR[7] 42 +deposit BOOTR[7] 0 +deposit BOOTR[6] 800 +;at mta0 tapes/temp.tap +;at mta0 tapes/src.tar.tap +;at mta0 tapes/y2k21ab.tar.tap +at dma0 dsk/21bdisk0.dma +at dma1 dsk/21bdisk1.dma +at ec tap:tap0 +bo dma0 diff --git a/SEL32/installs/runscsi21b.ini b/SEL32/installs/runscsi21b.ini new file mode 100644 index 00000000..9cf048e9 --- /dev/null +++ b/SEL32/installs/runscsi21b.ini @@ -0,0 +1,248 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; UTX - Ver 2.1B hardware configuration +; CPU - V6 8M Sel32 Powernode +; MFP - 7e00 Model 8002 Multi-Function Processor +; SBA - 7e00/7e08 MFP SCSI Disk controller +; sba0 Model 8821 300MB +; sba0 <-> dsk/scsidiska0 +; sba1 Model 8821 300MB +; sba1 <-> dsk/scsidiska1 +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ee0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 50 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/utx21b1.tap +; EC - 0e00 Model 8516 Ethernet +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +set env IP=192.168.1.5 +;====================================================== +; Set debug output +;set debug -n sel.log +;set debug stderr +; +;mkdir dsk +; CPU type and memory +;set CPU 32/97 4M +;set CPU V6 4M +set CPU V6 8M +;set CPU V9 4M +;set CPU V9 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;set cpu history=10000 +; useful options +;set cpu debug=exp;irq;xio;trap;cmd +;;set cpu debug=cmd;exp;irq;trap;xio +;set cpu debug=cmd;irq;trap;exp +;;set cpu debug=irq;trap;exp;xio +;;set cpu debug=irq;xio +; +; RTC realtime clock +set RTC enable +; address is 7f06 +;set RTC 50 +set RTC 60 +; RTC debug options +;set RTC debug=cmd +; +; ITM interval timer +; address is 7f04 +; set itm 3840 +;set ITM debug=cmd +; +; IOP at channel 7e00 +; useful options +;set iop debug=cmd;exp +;set iop debug=cmd +; make iop online +;set iop enable +; set iop channel address +;set iop0 dev=7e00 +; +; MFP at channel 7e00 +; useful options +;set mfp debug=cmd;exp +; make mfp online +set mfp enable +; set mfp channel address +set mfp0 dev=7e00 +;set mfp0 dev=7600 +; +; EC at channel 0e00 +; useful options +;set ec debug=cmd;exp +; set the mode +set EC mode=1 +; make ec online +set ec enable +; set ec channel address +set ec0 dev=0e00 +at ec tap:tap0 +; +; COM 8-Line +;set com debug=cmd; +;set coml0 enable +;set coml1 enable +;set coml2 enable +;set coml3 enable +;set coml4 enable +;set coml5 enable +;set coml6 enable +;set coml7 enable +; +; Enable telnet sessions on port 4747 +;set comc enable +;at comc 4747 +; +; LPR +;set lpr debug=cmd;detail +;set lpr enable +set lpr enable +; LPR output file +;at lpr lprout +;at lpr lprout +; +; CON Console +; useful options +;set con debug=cmd;exp;detail +;set con debug=cmd;exp; +; enable console +set con enable +; set console address +; set con0 enable +set con0 dev=7efc +; set con1 enable +set con1 dev=7efd +; +; MTA Buffered tape processor +;set mta debug=cmd;exp;detail;data +; useful options +;set mta debug=cmd;detail;exp +; +; enable the MTA to change channel +set mta enable +; set mt channel +set mta0 dev=1000 +; attach in/out tape files +;at mta0 mpxsdt.tap +;at mta0 nbctape.tap +;at mta0 tapes/utx21b1.tap +;at mta0 utx21a1.tap +;at mta1 temptape.tap +;at mta1 utx21a2.tap +;at mta2 output.tap +;at mta0 sim32sdt.tap +;at mta0 diag.tap +; +; DMA disk processor II/UDP +;set dma enable +; set disk chan to 0800 +;set dma0 dev=800 +; set disk type to MPX MH300 +;set dma0 type=MH300 +; set disk type to UTX 9346 +;set dma0 type=9346 +;set dma0 type=8155 +;set dma0 type=8887 +;set dma0 type=8148 +; Attach diskfile +;at dma0 utx0disk +;at dma0 utx1disk +;at dma0 sim32disk +;at dma0 diagdisk +; +;set dma debug=cmd;exp;detail;data +; useful options +;set dma debug=cmd;exp +;set dma debug=exp;cmd;detail +; +; SDA SCFI disk processor +;set sda debug=cmd;exp;data;detail +; Attach diskfiles +;at sda0 scsidisk0 +;at sda1 scsidisk1 +; +; SBA MFP SCSI bus 1 disk processor +set sba enable +; set disk chan to 7600 +;set sba0 dev=7600 +set sba0 dev=7e00 +;set sba1 dev=7e08 +; set disk type to UTX MH300 +set sba0 type=8821 +set sba1 type=8821 +;set sba0 type=8820 +;set sba debug=cmd;exp;data;detail +;set sba debug=cmd;exp;detail +; Attach diskfiles +at sba0 dsk/scsidiska0 +at sba1 dsk/scsidiska1 +; +; SBB MFP SCSI bus 2 disk processor +;;set sbb enable +; set disk chan to 7640 +;set sbb0 dev=7640 +;;set sbb0 dev=7e40 +; set disk type to MPX MH300 +;set sbb0 type=SD300 +;set sbb0 type=8821 +;;set sbb0 type=SD150 +;set sbb0 type=8820 +;set sbb debug=cmd;exp;data;detail +;;set sbb debug=cmd;exp;detail +; Attach diskfiles +;;at sbb0 scsidiskb0 +;at sbb1 scsi1disk +; +; DPA high speed disk processor +; enable the HSDP to change channel +;set dpa enable +; set channel addr +;set dpa0 dev=800 +; set disk type to UTX 8887 +;set dpa0 type=8887 +; Attach diskfiles +;at dpa0 utxdsk.dsk +;at dpa0 utx0hsdp +;at dpa1 utx1hsdp +; +;set dpa debug=cmd;detail;exp +; useful options +;set dpa debug=cmd;exp;detail +; +; set console switches +deposit CSW 0 +; +;UTX boot tape options +;set GPR 7 to 0x00 to boot in multi-user mode +;set GPR 7 to 0x01 to prompt for unix filename +;set GPR 7 to 0x02 to boot in single user mode +;set GPR 7 to 0x10 to disable swapping and paging +;set GPR 7 to 0x20 to boot from device specified in GPR6 +;set GPR 7 to 0x40 to allow progress messages on boot +;deposit BOOTR[7] 40 +;deposit BOOTR[7] 52 +deposit BOOTR[7] 40 +;deposit BOOTR[7] 2 +;deposit BOOTR[6] 800 +;deposit BOOTR[0] ffffffff +; +; Set register content at boot for SEL diagnostics +; uncomment next line to get diag loader prompt +;deposit bootr[0] ffffffff +;deposit bootr[1] 0 +;deposit bootr[2] 0 +; +; allow cpu idle +set cpu idle +; +;Boot from disk +bo sba0 diff --git a/SEL32/installs/runscsi3x.ini b/SEL32/installs/runscsi3x.ini new file mode 100644 index 00000000..466af081 --- /dev/null +++ b/SEL32/installs/runscsi3x.ini @@ -0,0 +1,219 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX - Ver 3.4 hardware configuration +; CPU - 32/67 8M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; MFP - 7600 Model 8002 Multi Function Processor +; SBA - 7600 MFP SCSI Disk Controller +; sba0 SD300 Model 8828 300MB MHD +; sba0 <-> dsk/mpx3xsba0.dsk +; SBA - 7640 MFP SCSI Disk Controller +; sbb0 SD300 Model 8828 300MB MHD +; sbb0 <-> dsk/mpx3xsbb0.dsk +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/mpxsdt69.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set HOST simulator +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; Set debug output +;set debug -n sel.log +; +; CPU type and memory size +set CPU 32/67 8M +;set CPU 32/97 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;set cpu history=10000 +; +; RTC realtime clock +; RTC debug options +;set RTC debug=cmd +; device address is 7f06 +set RTC enable +;set RTC 50 +set RTC 60 +; +; ITM interval timer +; ITM debug options +;set ITM debug=cmd +; device address is 7f04 +set ITM 3840 +; +; IOP at channel 7e00 +; IOP debug options +;set iop debug=cmd;exp +set iop enable +; set iop channel address +set iop0 dev=7e00 +; +; MFP at channel 7600 +; Only supported on MPX-3X and UTX +; MFP debug options +;set mfp debug=cmd;exp +; enable MFP to change address +set mfp enable +; set mfp channel address +;set mfp0 dev=7e00 +set mfp0 dev=7600 +; +; COM 8-Line +; COM debug options +;set coml debug=cmd;exp;xio +; enable COML to change address +set coml enable +; MPX 3X wants 7ec0 +set coml0 dev=7ec0 +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +; +; COMC 8-Line Mux +; COMC debug options +;set comc debug=cmd +; COMC has no address +set comc enable +; Enable telnet sessions on port 4747 +at comc 4747 +; +; LPR at 7ef8 +; LPR debug options +;set lpr debug=cmd;detail +; enable LPR to change address +set lpr enable +; attach LPR output file +at lpr lprout +; +; EC ethernet 0e00 +; Support not available yet +; EC debug options +;set ec debug=cmd;exp;xio;detail;irq +;set ec enable +;set ec0 dev=0e00 +;set ec mode=2 +;at ec tap:tap0 +; set mac address to cause ec to be attached +;set ec MAC=08:00:5D:01:01:20 +; +; CON Console +; CON debug options +;set con debug=cmd;exp;detail +; enable console +set con enable +; set console address +set con0 dev=7efc +; +; MTA Buffered tape processor +; MTA debug options +;set mta debug=cmd;exp;detail;data +; enable MTA to change channel +set mta enable +; set mta channel address +set mta0 dev=1000 +; Attach in/out tape files +;at mta0 output.tap +;set mta0 locked +; +; DMA disk processor II/UDP +; DMA debug options +;set dma debug=cmd;exp;detail;data +; enable DMA to change channel +; set dma enable +; set channel address +; set dma0 dev=800 +; set disk type to MPX MH300 (8887) +; must match sysgen assignment +; set dma0 type=MH300 +; Attach diskfile +; at dma0 dsk/mpx3xdma0.dsk +; +; SDA SCFI disk processor +; Only supported on MPX-1X +; SDA debug options +;set sda debug=cmd;exp;data;detail +; enable SCFI to change channel +;set sda enable +; set channel address +;set sda0 dev=800 +; set disk type to MPX SG120 +; must match sysgen assignment +;set sda0 type=SG120 +; Attach diskfiles +;at sda0 dsk/mpx3xsda0.dsk +; +; DPA high speed disk processor +; DPA debug options +;set dpa debug=cmd;exp;data;detail +; enable DPA to change channel +;set dpa enable +; set channel address +;set dpa0 dev=800 +; set disk type to MPX MH300 (8887) +; must match sysgen assignment +;set dpa0 type=MH300 +; Attach diskfiles +;at dpa0 dsk/mpx3xdpa0.dsk +; +; SBA MFP SCSI buss 1 disk processor +; SBA debug options +;set sba debug=cmd;exp;data;detail +; enable SBA to change channel +set sba enable +; set channel address +set sba0 dev=7600 +; set disk type to MPX SD300 (8828) +set sba0 type=SD300 +; Attach diskfiles +at sba0 dsk/mpx3xsba0.dsk +; +; SBB SCSI buss 2 disk processor +; SBB debug options +;set sbb debug=cmd;exp;data;detail +; enable SBB to change channel +set sbb enable +; set channel address +set sbb0 dev=7640 +; set disk type to MPX SD300 (8828) +set sbb0 type=SD300 +; Attach diskfiles +at sbb0 dsk/mpx3xsbb0.dsk +; +; set console switches +deposit CSW 0 +; +;SEL32 boot register options +;deposit BOOTR[7] 0 +;deposit BOOTR[6] 800 +;; +; allow cpu idle +set cpu idle +; Set expect script for auto time entry on MPX at OPCOM prompt +;expect haltafter=20000 +; wait for expected output from simulator, then enter this text +expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r"; GO +;expect "??" send "X\r"; continue +;expect "SYSTEM READY... PRESS ATTENTION FOR TSM..." send "@@A"; continue +expect "SYSTEM READY... PRESS ATTENTION FOR TSM..." send after=500000 delay=4000 "@@A"; continue +expect "ENTER YOUR OWNERNAME:" send "SYSTEM\r"; continue +expect "TSM>" send "MOUNT WORK ON DM7640 OPTI=PUBLIC\r"; continue +expect "TSM>" send "!STAT VOL\r"; continue +expect "TSM>" send "WHO\r"; continue +;expect "TSM>" send "EXIT\r"; continue +; +; Boot from disk +bo sba0 diff --git a/SEL32/installs/sel32load1x.ini b/SEL32/installs/sel32load1x.ini new file mode 100644 index 00000000..7037d86b --- /dev/null +++ b/SEL32/installs/sel32load1x.ini @@ -0,0 +1,245 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX - Ver 1.5F hardware configuration +; CPU - 32/27 2M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; DMA - 0800 2311/2314 Disk Processor II +; dma0 MH300 Model 8127 300MB MHD +; dma0 <-> dsk/sel32disk +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/mpx1xsdt.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; Set directory for disk images +mkdir dsk +mkdir tapes +; Set tape image filename +set env FILE=mpx1xsdt.tap +; Set github.com URL for downloading files +set env GITURL=https://github.com/AZBevier/SEL32-installs/raw/main/tapes/ +if exist "tapes/%FILE%" goto exists +if not exist "tapes/%FILE%" echof "file %FILE% missing, trying %FILE%.tgz" +cd tapes +if exist "%FILE%.tgz" goto nocurl +echof "fetching %FILE%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE%.tgz +if not exist "%FILE%.tgz" echof "FAILED - file %FILE% not available"; exit 1 +:nocurl +echof "untar %FILE%.tgz file\n" +tar -xzf %FILE%.tgz +cd .. +:exists +echof "file %FILE% present, doing install" +; +; Set debug output +;set debug -n sel.log +;set debug stderr +; +; CPU type and memory +; Bad on UTX +set CPU 32/27 2M +;set CPU 32/27 4M +;set CPU 32/87 4M +;set CPU 32/67 4M +;End of Bad +;set CPU 32/97 4M +;set CPU V6 4M +;set CPU V6 8M +;set CPU V9 4M +;set CPU V9 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;set cpu history=10000 +; useful options +;set cpu debug=exp;xio;trap +;set cpu debug=cmd;exp;irq;trap;xio; +;set cpu debug=cmd;irq;trap;exp +;set cpu debug=irq;trap;exp;xio +;set cpu debug=irq;xio;exp;inst;cmd;trap +;set cpu debug=irq;xio;exp;cmd;trap +; +; RTC realtime clock +; address is 7f06 +;set RTC 50 +set RTC 60 +set RTC enable +; RTC debug options +;set RTC debug=cmd +; +; ITM interval timer +; address is 7f04 +; set ITM 3840 +;set ITM debug=cmd +; +; IOP at channel 7e00 +set iop enable +; set iop channel +set iop0 dev=7e00 +;set iop debug=cmd;exp +;set iop debug=cmd +; +; COM 8-Line +set coml enable +set coml0 dev=7ec0 +;set coml debug=cmd; +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +; +; Enable telnet sessions on port 4747 +set comc enable +;set comc debug=cmd; +at comc 4747 +; +; LPR +; LPR0 is at 7EF8 +; LPR1 is at 7EF9 +; useful options +;set lpr debug=cmd;detail +set lpr enable +; LPR output file +;at lpr lprout +; +;; CON Console +;set con debug=cmd;exp;detail +; useful options +; enable console +;;set con debug=cmd;exp +set con enable +; set console address +; set con0 enable +set con0 dev=7efc +; set con1 enable +set con1 dev=7efd +;set con debug=cmd;exp +; +; MTA Buffered tape processor +;set mta debug=cmd;exp;detail;data +; useful options +;;set mta debug=cmd;detail;exp +;set mta debug=cmd;exp +; +; enable MTA to change channel +set mta enable +; set mta channel +set mta0 dev=1000 +; +; Attach in/out tape files +set mta0 locked +at mta0 tapes/mpx1xsdt.tap +;at mta0 nbctape.tap +;at mta0 usertape.tap +;at mta0 mpxsdt6r.tap +;at mta0 tapes/sel32sdt.tap +;at mta0 diag.tap +;at mta1 temptape.tap +;at mta2 output.tap +; +; DMA disk processor II/UDP +; enable DMA to change channel +set dma enable +; set disk chan to 0800 +set dma0 dev=800 +; set disk type to MPX MH300 +set dma0 type=MH300 +; set disk type to MPX MH080 +;set dma0 type=MH080 +; set disk type to UTX 9346 +;set dma0 type=9346 +;set dma0 type=8155 +;set dma0 type=8887 +;set dma0 type=8148 +; +; Attach diskfile +at dma0 -i dsk/sel32disk +; +; Debug options +;set dma debug=cmd;exp;detail;data +; useful options +;set dma debug=cmd;exp +;set dma debug=exp +; +; SDA SCFI disk processor +;set sda debug=cmd;exp;data;detail +; Attach diskfiles +;at sda0 diskfile4 +;at sda1 diskfile5 +; +; DPA high speed disk processor +; enable HSDP to change channel +;set dpa enable +; set channel addr +;set dpa0 dev=800 +; set disk type to UTX 8887 +;set dpa0 type=8887 +; +; Attach diskfiles +;at dpa0 utxdsk.dsk +;at dpa0 utx0hsdp +;at dpa1 utx1hsdp +; +;set dpa debug=cmd;detail;exp +; useful options +;set dpa debug=cmd;exp +; +; set console switches +deposit CSW 0 +; +;UTX boot tape options +;set GPR 7 to 0x00 to boot in multi-user mode +;set GPR 7 to 0x01 to prompt for unix filename +;set GPR 7 to 0x02 to boot in single user mode +;set GPR 7 to 0x10 to disable swapping and paging +;set GPR 7 to 0x20 to boot from device specified in GPR6 +;set GPR 7 to 0x40 to allow progress messages on boot +;deposit BOOTR[7] 40 +;deposit BOOTR[7] 52 +;deposit BOOTR[7] 42 +;deposit BOOTR[7] 2 +;deposit BOOTR[6] 800 +;deposit BOOTR[0] ffffffff +; +; Set register content at boot for SEL diagnostics +; uncomment next line to get diag loader prompt +;deposit bootr[0] ffffffff +;deposit bootr[1] 0 +;deposit bootr[2] 0 +; +; allow cpu idle +set cpu idle +; wait for expected output from simulator, then enter this text +expect "COLD OR WARM START (C OR W)?" send "C\r"; continue +; Set expect script for auto time entry on MPX at OPCOM prompt +;expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r@@A"; continue +expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r@@Ax\r"; GO +expect "TSM>" send "A4 SLO=UT\r"; continue +expect "TSM>" send "A3 IN=M91000,TAP\r"; continue +expect "TSM>" send "PAGE 0\r"; continue +expect "TSM>" send "FILEMGR\r"; continue +; restore all files +expect "FIL>" send "RESTORE\r"; continue +expect "FIL>" send "EXIT\r"; continue +expect "TSM>" send "WHO\r"; continue +expect "TSM>" send "EXIT\r"; continue +expect "RING IN FOR SERVICE" send "\r^E" +; Boot from mag tape +bo mta0 +detach all +quit diff --git a/SEL32/installs/sel32run1x.ini b/SEL32/installs/sel32run1x.ini new file mode 100644 index 00000000..e5cc0632 --- /dev/null +++ b/SEL32/installs/sel32run1x.ini @@ -0,0 +1,210 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX - Ver 1.5F hardware configuration +; CPU - 32/27 2M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; DMA - 0800 2311/2314 Disk Processor II +; dma0 MH300 Model 8127 300MB MHD +; dma0 <-> dsk/sel32disk +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <-> (not assigned) +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; Set debug output +;set debug -n sel.log +;set debug stderr +; +; CPU type and memory +; Bad on UTX +set CPU 32/27 2M +;set CPU 32/27 4M +;set CPU 32/87 4M +;set CPU 32/67 4M +;End of Bad +;set CPU 32/97 4M +;set CPU V6 4M +;set CPU V6 8M +;set CPU V9 4M +;set CPU V9 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;set cpu history=10000 +; useful options +;set cpu debug=exp;xio;trap +;set cpu debug=cmd;exp;irq;trap;xio; +;set cpu debug=cmd;irq;trap;exp +;set cpu debug=irq;trap;exp;xio +;set cpu debug=irq;xio;exp;inst;cmd;trap +;set cpu debug=irq;xio;exp;cmd;trap +; +; RTC realtime clock +; address is 7f06 +;set RTC 50 +set RTC 60 +set RTC enable +; RTC debug options +;set RTC debug=cmd +; +; ITM interval timer +; address is 7f04 +set ITM 3840 +;set ITM debug=cmd +; +; IOP at channel 7e00 +set iop enable +; set iop channel +set iop0 dev=7e00 +;set iop debug=cmd;exp +;set iop debug=cmd +; +; COM 8-Line +set coml enable +set coml0 dev=7ec0 +;set coml debug=cmd; +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +; +; Enable telnet sessions on port 4747 +set comc enable +;set comc debug=cmd; +at comc 4747 +; +; LPR +;set lpr debug=cmd;detail +set lpr enable +; LPR output file +;at lpr lprout +; +;; CON Console +;set con debug=cmd;exp;detail +; useful options +; enable console +;;set con debug=cmd;exp +set con enable +; set console address +; set con0 enable +set con0 dev=7efc +;set con debug=cmd;exp +; +; MTA Buffered tape processor +;set mta debug=cmd;exp;detail;data +; useful options +;;set mta debug=cmd;detail;exp +;set mta debug=cmd;exp +; +; enable MTA to change channel +set mta enable +; set mta channel +set mta0 dev=1000 +; +; Attach in/out tape files +;at mta0 tapes/mpx1xsdt.tap +;at mta0 nbctape.tap +;set mta0 locked +;at mta0 usertape.tap +;at mta0 mpxsave6.tap +;at mta0 tapes/sel32sdt.tap +;at mta0 diag.tap +;at mta1 temptape.tap +;at mta2 output.tap +; +; DMA disk processor II/UDP +; enable DMA to change channel +set dma enable +; set disk chan to 0800 +set dma0 dev=800 +; set disk type to MPX MH300 +set dma0 type=MH300 +; set disk type to MPX MH080 +;set dma0 type=MH080 +; set disk type to UTX 9346 +;set dma0 type=9346 +;set dma0 type=8155 +;set dma0 type=8887 +;set dma0 type=8148 +; +; Attach diskfile +;at dma0 diskfile6r +at dma0 dsk/sel32disk +;at dma0 diagdisk +; +; Debug options +;set dma debug=cmd;exp;detail;data +; useful options +;set dma debug=cmd;exp +;set dma debug=exp +; +; SDA SCFI disk processor +;set sda debug=cmd;exp;data;detail +; Attach diskfiles +;at sda0 diskfile4 +;at sda1 diskfile5 +; +; DPA high speed disk processor +; enable HSDP to change channel +;set dpa enable +; set channel addr +;set dpa0 dev=800 +; set disk type to UTX 8887 +;set dpa0 type=8887 +; +; Attach diskfiles +;at dpa0 utxdsk.dsk +;at dpa0 utx0hsdp +;at dpa1 utx1hsdp +; +;set dpa debug=cmd;detail;exp +; useful options +;set dpa debug=cmd;exp +; +; set console switches +deposit CSW 0 +; +;UTX boot tape options +;set GPR 7 to 0x00 to boot in multi-user mode +;set GPR 7 to 0x01 to prompt for unix filename +;set GPR 7 to 0x02 to boot in single user mode +;set GPR 7 to 0x10 to disable swapping and paging +;set GPR 7 to 0x20 to boot from device specified in GPR6 +;set GPR 7 to 0x40 to allow progress messages on boot +;deposit BOOTR[7] 40 +;deposit BOOTR[7] 52 +;deposit BOOTR[7] 42 +;deposit BOOTR[7] 2 +;deposit BOOTR[6] 800 +;deposit BOOTR[0] ffffffff +; +; Set register content at boot for SEL diagnostics +; uncomment next line to get diag loader prompt +;deposit bootr[0] ffffffff +;deposit bootr[1] 0 +;deposit bootr[2] 0 +; +; allow cpu idle +set cpu idle +; Set expect script for auto time entry on MPX at OPCOM prompt +;expect haltafter=20000 +; wait for expected output from simulator, then enter this text +expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r@@Ax\r"; GO +expect "TSM>" send "WHO\r"; continue +; Boot from disk +;bo dpa0 +bo dma0 diff --git a/SEL32/installs/user36erunp2.ini b/SEL32/installs/user36erunp2.ini new file mode 100644 index 00000000..02e3d491 --- /dev/null +++ b/SEL32/installs/user36erunp2.ini @@ -0,0 +1,327 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX - Ver 3.6 extended hardware configuration +; CPU - 32/67 16M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; MFP - 7600 Model 8002 Multi Function Processor +; SBA - 7e00/7e08 MFP SCSI Disk controller +; sba0 SD700 Model 8833 700MB +; sba0 <-> dsk/scsi35m1disk0 +; sba1 SD700 Model 8833 700MB +; sba1 <-> dsk/scsi35m2disk0 +; DMA - 0800 DMA HSDP Disk Controller +; dma0 MD300 Model 8127 300MB MHD +; dma0 <-> dsk/user36p2udp0 +; - 0802 DMA HSDP Disk Controller +; dma1 MH600 Model 8155 600MB MHD +; dma1 <-> dsk/user36s1udp1 +; - 0804 DMA HSDP Disk Controller +; dma1 MH600 Model 8155 600MB MHD +; dma1 <-> dsk/user36s1udp2 +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/nbctape3x.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set HOST simulator +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; Set debug output +;set debug -n sel.log +;set debug stderr +; +; CPU type and memory +; Bad on UTX +;set CPU 32/27 2M +;set CPU 32/27 4M +;set CPU 32/87 4M +;set CPU 32/87 8M +;End of Bad +;set CPU 32/67 4M +;set CPU 32/67 8M +;set CPU 32/67 12M +set CPU 32/67 16M +;set CPU 32/97 4M +;set CPU 32/97 8M +;set CPU V6 4M +;set CPU V6 8M +;set CPU V9 4M +;set CPU V9 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;set cpu history=10000 +; useful options +;set cpu debug=exp +;set cpu debug=cmd;exp;irq;trap;xio;inst +;;;;set cpu debug=cmd;exp;irq;trap;xio +;set cpu debug=cmd;irq;trap;exp +;set cpu debug=cmd;exp;xio +;;;set cpu debug=cmd;irq;trap;exp;xio +; +; RTC realtime clock +; address is 7f06 +;set RTC 50 +set RTC 60 +; enable RTC +set RTC enable +; RTC debug options +;set RTC debug=cmd +; +; ITM interval timer +; address is 7f04 + set ITM 3840 +;set ITM debug=cmd +; +; IOP at channel 7e00 +; useful options +;;;;set iop debug=cmd;exp +;;set iop debug=cmd +; make iop online +set iop enable +; set iop channel address +set iop0 dev=7e00 +; +; MFP at channel 7e00 +; useful options +;;;;set mfp debug=cmd;exp +; make mfp online +set mfp enable +; set mfp channel address +;set mfp0 dev=7e00 +set mfp0 dev=7600 +; +; COM 8-Line on 7ec0 +; useful options +;;set com debug=cmd; +set coml enable +set coml0 dev=7ec0 +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +; +; Enable telnet sessions on port 4747 +set comc enable +at comc 4747 +; +; LPR +; LPR0 is at 7EF8 +; LPR1 is at 7EF9 +; useful options +;;set lpr debug=cmd;detail +;set lpr debug=cmd +set lpr enable +; LPR output file +at lpr lprout +; +; CON Console +; useful options +;set con debug=cmd;exp;detail +; enable console +set con enable +; set console address +set con0 dev=7efc +;;;;set con debug=cmd;exp +; +; MTA Buffered tape processor +;set mta debug=cmd;exp;xio;data +; useful options +;set mta debug=cmd;exp;xio;data +;;set mta debug=cmd;exp;xio +; +; enable MTA to change channel +set mta enable +; set mt channel +set mta0 dev=1000 +; +; Attach in/out tape files +;at mta0 user36sdts2.tap +;at mta0 user36sdts1.tap +set mta0 locked +at mta0 tapes/nbctape3x.tap +;at mta0 test.tap +;at mta0 user36sdt.tap +;at mta1 output.tap +;at mta0 iscsys_dsk.tap +; +; EC at channel 0d00 +; useful options +;set ec debug=cmd;exp +; set mode +;;set mode=1 +; make ec online +;;set ec enable +; set ec channel address +;;set ec0 dev=0d00 +; set mac address to cause ec to be attached +;set ec MAC=00:00:02:00:00:00 +;;at ec tap:tap0 +; +; DMA disk processor II/UDP +; enable DMA to change channel +set dma enable +; set disk chan to 0800 +set dma0 dev=800 +; set disk type to MPX MH300 8127 +set dma0 type=MH300 +; set disk type to MPX MH600 8155 +;set dma0 type=MH600 +; set disk chan to 0802 +set dma1 dev=802 +; set disk type to MPX MH300 8127 +;set dma1 type=MH300 +; set disk type to MPX MH600 8155 +set dma1 type=MH600 +; set disk chan to 0804 +set dma2 dev=804 +; set disk type to MPX MH300 8127 +;set dma2 type=MH300 +; set disk type to MPX MH600 8155 +set dma2 type=MH600 +; +; Attach diskfile +;at dma0 -i user36s1udp0 +at dma0 dsk/user36p2udp0 +;at dma1 -i user36s1udp1 +at dma1 dsk/user36s1udp1 +;at dma2 -i user36s1udp2 +;at dma2 dsk/user36s1udp2 +;;at dma0 mpx0disk +;;at dma1 mpx1disk +; +;set dma debug=cmd;exp;detail;data +; useful options +;;set dma debug=cmd;exp +;set dma debug=exp;cmd;detail +; +; SDA SCFI disk processor +;set sda debug=cmd;exp;data;detail +;set sda debug=cmd;exp +; Attach diskfiles +;at sda0 diskfile4 +;at sda1 diskfile5 +; +; SBA MFP SCSI buss 1 disk processor +set sba enable +; set disk chan to 7600 +set sba0 dev=7600 +; set disk type to MPX MH300 +;set sba0 type=SD300 +;set sba0 type=SD150 +;;set sba0 type=SD700 +set sba0 type=SD700 +set sba1 type=SD700 +;;;;set sba debug=cmd;exp;data;detail +;;;;set sba debug=cmd;exp;xio;exp;data +; Attach diskfiles +;;at sba0 -i scsi36m1disk0 +at sba0 dsk/scsi35m1disk0 +;at sba1 scsi1disk +at sba1 dsk/scsi35m2disk0 +; +; SBB SCSI buss 2 disk processor +;set sbb enable +; set disk chan to 7640 +;set sbb0 dev=7640 +; set disk type to MPX MH300 +;;;;set sbb0 type=SD150 +;set sbb0 type=SD150 +;set sbb0 type=SD700 +;set sbb0 type=SD300 +;set sbb debug=cmd;exp;data;xio;detail +;set sbb debug=cmd;exp +; Attach diskfiles +;at sbb0 scsi35m2disk0 +;at sbb1 scsi1disk +; +; DPA high speed disk processor +; enable HSDP to change channel +;set dpa enable +; set channel addr +;set dpa0 dev=800 +; set disk type to UTX 8887 +;set dpa0 type=8887 +; +; Attach diskfiles +;at dpa0 mpx0hsdp +;at dpa1 mpx1hsdp +; +; useful options +;set dpa debug=cmd;exp +; +; set console switches +deposit CSW 0 +; +; Set register content at boot for SEL diagnostics +; uncomment next line to get diag loader prompt +;deposit bootr[0] ffffffff +;deposit bootr[1] 0 +;deposit bootr[2] 0 +; +; set Boot reg 0 1 to boot MSTRALL from master SDT +deposit bootr[0] 1 +; set Boot reg 0 2 to boot MSTREXT from master SDT +;deposit bootr[0] 2 +; +; allow cpu idle +set cpu idle +; Set expect script for auto time entry on MPX at OPCOM prompt +;expect haltafter=20000 +; +; wait for expected output from simulator, then enter this text +;expect " >>" send "BR 31D10\r"; continue +;expect " >>" send "BR 2b4q\r"; continue +;expect " >>" send "BR 430q\r"; continue +expect " >>" send "TE\r"; continue +;expect "ENTER SYSTEM DEVICE CHANNEL AND SUBADDRESS: " send "7600\r"; continue +;expect "ENTER SYSTEM DEVICE CHANNEL AND SUBADDRESS: " send "0800\r"; continue +;expect "PLEASE ENTER THE 4 CHAR. DEVICE....." send "0800\r"; continue +;expect "PLEASE ENTER THE 4 CHAR. DEVICE....." send "7600\r"; continue +;expect "ENTER DISC CONTROLLER TYPE:" send "X\r"; continue +;expect " (OR IF SYSTEM VOLUME):" send "\r"; continue +;expect "ENTER DISC CONTROLLER TYPE:" send "M\r"; continue +expect "ENTER DATE" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r"; GO +expect "ENTER SWAP DEVICE CHANNEL AND SUBADDRESS" send "0800\r"; continue +expect "TASK J.INIT , 04000002 REPLY R, H, A, OR DEVICE:" send "R\r"; continue +expect "TASK J.INIT , 04000002 REPLY R, H, A, OR DEVICE:" send "R\r"; continue +expect "TASK J.INIT , 04000002 REPLY R, H, A, OR DEVICE:" send "R\r"; continue +expect "TASK J.INIT , 04000002 REPLY R, H, A, OR DEVICE:" send "R\r"; continue +;expect "MOUNT DISK VOLUME ISCSYS ON DRIVE DM0802 ---" send "R\r"; continue +;expect "MOUNT DISK VOLUME NBCSRC ON DRIVE DM0804 ---" send "R\r"; continue +;expect "MOUNT DISK VOLUME ISCSRC ON DRIVE DM7600 ---" send "R\r"; continue +;expect "MOUNT DISK VOLUME IRELAND ON DRIVE DM7608 ---" send "R\r"; continue +; +;expect "ENTER SYSTEM VOLUME CHANNEL AND SUBADDRESS: " send "7600\r"; continue +;expect "ENTER SYSTEM VOLUME CHANNEL AND SUBADDRESS: " send "0800\r"; continue +;expect "SYSTEM READY... PRESS ATTENTION FOR TSM..." +expect "SYSTEM READY... PRESS ATTENTION FOR TSM..." send "@@A"; continue +expect "ENTER YOUR OWNERNAME:" send "SYSTEM\r"; continue +expect "TSM>" send "WHO\r"; continue +expect "TSM>" send "SYSINFO\r"; continue +expect "TSM>" send "MOUNT WORK ON DM0802 OPTI=PUBLIC\r"; continue +;expect "MOUNT DISK VOLUME WORK ON DRIVE DM0802 ---" send "R\r"; continue +expect "TASK J.TSM" send "R\r"; continue +expect "TSM>" send "!STAT VOL\r"; continue +;;;expect "TSM>" send "EXIT\r"; continue +#expect "TSM>" send "J.VFMT\r"; continue +#expect "FMT>" send "INITIALIZE DEV=DM0804 DIS=MH0600 DES=Y CON=N\r"; continue +#expect "FMT>" send "FORMAT DEV=DM0804 VOL=NBCSRC MAXRE=9000 CON=N\r"; continue +#expect "TSM>" send "VOLMGR\r"; continue +#expect "VOL>" send "CREATE D @NBCSRC^SYSTEM ENTRIES=1000\r"; continue +#expect "VOL>" send "EXIT\r"; continue +; +; Boot from disk +bo dma0 +;bo sba0 diff --git a/SEL32/installs/user36esdtp2.ini b/SEL32/installs/user36esdtp2.ini new file mode 100644 index 00000000..e02125aa --- /dev/null +++ b/SEL32/installs/user36esdtp2.ini @@ -0,0 +1,364 @@ +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX - Ver 3.6 extended hardware configuration +; CPU - 32/67 16M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; MFP - 7600 Model 8002 Multi Function Processor +; SBA - 7e00/7e08 MFP SCSI Disk controller +; sba0 SD700 Model 8833 700MB +; sba0 <-> dsk/scsi35m1disk0 +; sba1 SD700 Model 8833 700MB +; sba1 <-> dsk/scsi35m2disk0 +; DMA - 0800 DMA HSDP Disk Controller +; dma0 MD300 Model 8127 300MB MHD +; dma0 <-> dsk/user36p2udp0 +; - 0802 DMA HSDP Disk Controller +; dma1 MH600 Model 8155 600MB MHD +; dma1 <-> dsk/user36s1udp1 +; - 0804 DMA HSDP Disk Controller +; dma2 MH600 Model 8155 600MB MHD (N/U) +; dma2 <-> dsk/user36s1udp2 (N/U) +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- tapes/user36esdtp2.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set HOST simulator +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; Set directory for disk images +mkdir dsk +mkdir tapes +; Set tape image filename +set env FILE=user36esdtp2.tap +; Set github.com URL for downloading files +set env GITURL=https://github.com/AZBevier/SEL32-installs/raw/main/tapes/ +if exist "tapes/%FILE%" goto exists +if not exist "tapes/%FILE%" echof "file %FILE% missing, trying %FILE%.tgz" +cd tapes +if exist "%FILE%.tgz" goto nocurl +echof "fetching %FILE%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE%.tgz +if not exist "%FILE%.tgz" echof "FAILED - file %FILE% not available"; exit 1 +:nocurl +echof "untar %FILE%.tgz file\n" +tar -xzf %FILE%.tgz +cd .. +:exists +echof "file %FILE% present, doing install" +; +; Set NBC tape image filename +set env FILE2=nbctape3x.tap +if exist "tapes/%FILE2%" goto exists2 +if not exist "tapes/%FILE2%" echof "file %FILE2% missing, trying %FILE2%.tgz" +cd tapes +if exist "%FILE2%.tgz" goto nocurl2 +echof "fetching %FILE2%.tgz file from github.com\n" +curl -LJO %GITURL%/%FILE2%.tgz +if not exist "%FILE2%.tgz" echof "FAILED - file %FILE2% not available"; exit 1 +:nocurl2 +echof "untar %FILE2%.tgz file\n" +tar -xzf %FILE2%.tgz +cd .. +:exists2 +echof "file %FILE2% present, doing install" +; +; Set debug output +;set debug -n sel.log +;set debug stderr +; +; CPU type and memory +;set CPU 32/27 2M +;set CPU 32/27 4M +;set CPU 32/87 4M +;set CPU 32/87 8M +;set CPU 32/67 4M +set CPU 32/67 8M +;set CPU 32/67 16M +;set CPU 32/97 4M +;set CPU 32/97 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;set cpu history=10000 +; useful options +;set cpu debug=exp +;set cpu debug=cmd;exp;irq;trap;xio;inst +;;;;set cpu debug=cmd;exp;irq;trap;xio +;set cpu debug=cmd;irq;trap;exp +;set cpu debug=cmd;exp;xio +;set cpu debug=irq;trap;exp;xio +; +; RTC realtime clock +; address is 7f06 +;set RTC 50 +set RTC 60 +; enable RTC +set RTC enable +; RTC debug options +;set RTC debug=cmd +; +; ITM interval timer +; address is 7f04 + set ITM 3840 +;set ITM debug=cmd +; +; IOP at channel 7e00 +; useful options +;;;;set iop debug=cmd;exp +;;set iop debug=cmd +; make iop online +set iop enable +; set iop channel address +set iop0 dev=7e00 +; +; MFP at channel 7e00 +; useful options +;;;;set mfp debug=cmd;exp +; make mfp online +set mfp enable +; set mfp channel address +;set mfp0 dev=7e00 +set mfp0 dev=7600 +; +; COM 8-Line on 7ec0 +; useful options +;;set com debug=cmd; +set coml enable +set coml0 dev=7ec0 +set coml0 enable +set coml1 enable +set coml2 enable +set coml3 enable +set coml4 enable +set coml5 enable +set coml6 enable +set coml7 enable +; +; Enable telnet sessions on port 4747 +;set comc enable +;at comc 4747 +; +; LPR +; LPR0 is at 7EF8 +; LPR1 is at 7EF9 +; useful options +;set lpr debug=cmd;detail +;;;;set lpr debug=cmd +set lpr enable +; LPR output file +;at lpr lprout +; +; CON Console +; useful options +;set con debug=cmd;exp;detail +; enable console +set con enable +; set console address +set con0 dev=7efc +;;;;set con debug=cmd;exp +; +; MTA Buffered tape processor +;set mta debug=cmd;exp;xio;data +; useful options +;set mta debug=cmd;exp;xio;data +;set mta debug=cmd;exp;xio +; +; enable MTA to change channel +set mta enable +; set mt channel +set mta0 dev=1000 +; +; Attach in/out tape files +set mta0 locked +at mta0 tapes/user36esdtp2.tap +;at mta0 user36sdts1.tap +;at mta1 temptape.tap +;at mta2 output.tap +; +; DMA disk processor II/UDP +; enable DMA to change channel +set dma enable +; set disk chan to 0800 +set dma0 dev=800 +; set disk type to MPX MH300 8127 +set dma0 type=MH300 +; set disk type to MPX MH600 8155 +;set dma0 type=MH600 +; set disk chan to 0802 +set dma1 dev=802 +; set disk type to MPX MH300 8127 +;set dma1 type=MH300 +; set disk type to MPX MH600 8155 +set dma1 type=MH600 +; +; Attach diskfile +;at dma0 udp35disk0 +at dma0 -i dsk/user36p2udp0 +;at dma1 udp35disk1 +; use s1 disk 2 +at dma1 -i dsk/user36s1udp1 +;;at dma0 mpx0disk +;;at dma1 mpx1disk +;at dma2 -i dsk/user36s1udp2 +; +;set dma debug=cmd;exp;detail;data +; useful options +;;set dma debug=cmd;exp +;set dma debug=exp;cmd;detail +; +; SDA SCFI disk processor +;set sda debug=cmd;exp;data;detail +;set sda debug=cmd;exp +; Attach diskfiles +;at sda0 diskfile4 +;at sda1 diskfile5 +; +; SBA MFP SCSI buss 1 disk processor +set sba enable +; set disk chan to 7600 +set sba0 dev=7600 +; set disk type to MPX MH300 +;set sba0 type=SD300 +;set sba0 type=SD150 +set sba0 type=SD700 +set sba1 type=SD700 +;;;;set sba debug=cmd;exp;data;detail +;;;;set sba debug=cmd;exp;xio;exp;data +; Attach diskfiles +;at sba0 scsia0disk +at sba0 -i dsk/scsi35m1disk0 +;at sba1 scsi1disk +at sba1 -i dsk/scsi35m2disk0 +; +; SBB SCSI buss 2 disk processor +;set sbb enable +; set disk chan to 7640 +;set sbb0 dev=7640 +; set disk type to MPX MH300 +;;;;set sbb0 type=SD150 +;set sbb0 type=SD150 +;set sbb0 type=SD700 +;set sbb0 type=SD300 +;set sbb debug=cmd;exp;data;xio;detail +;set sbb debug=cmd;exp +; Attach diskfiles +;at sbb0 -i scsi35m2disk0 +;at sbb1 scsi1disk +; +; DPA high speed disk processor +; enable HSDP to change channel +;set dpa enable +; set channel addr +;set dpa0 dev=800 +; set disk type to UTX 8887 +;set dpa0 type=8887 +; +; Attach diskfiles +;at dpa0 utxdsk.dsk +;at dpa0 utx0hsdp +;at dpa1 utx1hsdp +; +; useful options +;set dpa debug=cmd;exp +; +; set console switches +deposit CSW 0 +; +;UTX boot tape options +;set GPR 7 to 0x00 to boot in multi-user mode +;set GPR 7 to 0x01 to prompt for unix filename +;set GPR 7 to 0x02 to boot in single user mode +;set GPR 7 to 0x10 to disable swapping and paging +;set GPR 7 to 0x20 to boot from device specified in GPR6 +;set GPR 7 to 0x40 to allow progress messages on boot +;deposit BOOTR[7] 40 +;deposit BOOTR[7] 52 +deposit BOOTR[7] 42 +;deposit BOOTR[7] 2 +;deposit BOOTR[6] 800 +;deposit BOOTR[0] ffffffff +; +; Set register content at boot for SEL diagnostics +; uncomment next line to get diag loader prompt +;deposit bootr[0] ffffffff +;deposit bootr[1] 0 +;deposit bootr[2] 0 +; set Boot reg 0 1 to boot MSTRALL from master SDT +deposit bootr[0] 1 +; set Boot reg 0 2 to boot MSTREXT from master SDT +;deposit bootr[0] 2 +; +; allow cpu idle +set cpu idle +; Set expect script for auto time entry on MPX at OPCOM prompt +;expect haltafter=20000 +; +; wait for expected output from simulator, then enter this text +;expect " >>" send "BR 31D10\r"; continue +;expect " >>" send "BR 2b4q\r"; continue +;expect " >>" send "BR 430q\r"; continue +expect " >>" send "TE\r"; continue +;expect "ENTER SYSTEM VOLUME CHANNEL AND SUBADDRESS: " send "7600\r"; continue +expect "ENTER SYSTEM DEVICE CHANNEL AND SUBADDRESS: " send "0800\r"; continue +;;expect "BOOT FROM A SCSI TAPE? (REPLY Y OR N): " send "N\r"; continue +;;expect "PLEASE ENTER THE 4 CHAR. DEVICE....." send "0800\r"; continue +;expect "PLEASE ENTER THE 4 CHAR. DEVICE....." send "7600\r"; continue +;;expect "ENTER DISC CONTROLLER TYPE:" send "X\r"; continue +;expect "ENTER DISC CONTROLLER TYPE:" send "M\r"; continue +expect "ENTER DATE" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r"; GO +; +expect "FMT>" send "INITIALIZE DEV=DM0800 DIS=MH0300 DES=Y CON=N\r"; continue +;expect "FMT>" send "INITIALIZE DEV=DM7600 DIS=SD0700 DES=Y CON=N\r"; continue +;expect "FMT>" send "INITIALIZE DEV=DM7600 DIS=SD0300 DES=Y CON=N\r"; continue +expect "FMT>" send "FORMAT DEV=DM0800 VOL=SYSTEM MAXRE=8000 DES=Y CON=N\r"; continue; +;expect "FMT>" send "FORMAT DEV=DM7600 VOL=SYSTEM MAXRE=8000 CON=N\r"; continue +;expect "FMT>" send "INI DEV=DM7600 DIS=SD0150 DES=Y CON=N\r"; continue +;expect "FMT>" send "FOR DEV=DM7600 DIS=SD0700 VOL=SYSTEM MAXRE=8000 DES=Y CON=N\r"; continue +;expect "FMT>" send "INITIALIZE DEVICE=DM7600 DEST=Y DISC=SD0700 CONFIRM=N\r"; continue +;expect "FMT>" send "INITIALIZE DISC=SD0700 DEST=Y CONFIRM=N\r"; continue +;expect "FMT>" send "INITIALIZE DEST=Y CONFIRM=N\r"; continue +;;expect "FMT>" send "EXIT\r"; continue +expect "VOL>" send "CREATE D SYSTEM ENTRIES=2000\r"; continue +; restore system +expect "VOL>" send "RESTORE VOL=SYSTEM\r"; continue +; restore object, object_e, oldobj +;;expect "VOL>" send "RESTORE VOL=SYSTEM\r"; continue +; restore bin, doc, nblib, sample +;;expect "VOL>" send "RESTORE VOL=SYSTEM\r"; continue +expect "VOL>" send "REWIND\r"; continue +expect "VOL>" send "EXIT\r"; continue +;expect "SYSTEM READY... PRESS ATTENTION FOR TSM..." +expect "SYSTEM READY... PRESS ATTENTION FOR TSM..." send "@@A"; continue +expect "ENTER YOUR OWNERNAME:" send "SYSTEM\r"; continue +expect "TSM>" send "WHO\r"; continue +expect "TSM>" send "J.VFMT\r"; continue +expect "FMT>" send "INITIALIZE DEV=DM0802 DIS=MH0600 DES=Y CON=N\r"; continue +expect "CONTINUE - Y/N" send "Y\r"; continue +expect "TASK J.VFMT" send "R\r"; continue +expect "FMT>" send "FORMAT DEV=DM0802 VOL=WORK MAXRE=10000 DES=Y CON=N\r"; continue +expect "TSM>" send "MOUNT WORK ON DM0802 OPTI=PUBLIC\r"; continue +expect "TASK J.TSM" send "R\r"; continue +expect "TSM>" send "VOLMGR\r"; continue +expect "VOL>" send "CREATE D @WORK^SYSTEM ENTRIES=2000\r"; continue +expect "VOL>" send "EXIT\r"; continue +expect "TSM>" send "!STAT VOL\r"; continue +expect "TSM>" send "SYSINFO\r"; continue +;;expect "TSM>" send "WHO\r"; continue +expect "TSM>" send "SHUTDOWN 0\r"; continue +;;;expect "TSM>" send "EXIT\r"; continue +expect "sim>" send "q\r"; continue +; +; Boot from disk +;bo dma0 +; +; Boot from mag tape +bo mta0 +quit diff --git a/SEL32/sel32_chan.c b/SEL32/sel32_chan.c new file mode 100644 index 00000000..db4d1b0d --- /dev/null +++ b/SEL32/sel32_chan.c @@ -0,0 +1,2971 @@ +/* sel32_chan.c: SEL 32 Channel functions. + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers + + 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 + JAMES C. BEVIER 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. + +*/ + +/* Handle Class E and F channel I/O operations */ +#include "sel32_defs.h" + +/* Class E I/O device instruction format */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* |00 01 02 03 04 05|06 07 08 09|10 11 12|13 14 15|16 17 18 19 20 21 22 23|24 25 26 27 28 29 30 31| */ +/* | Op Code | Channel |sub-addr| Aug | Command Code | */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* */ + +/* Bits 00-05 - Op code = 0xFC */ +/* Bits 00-09 - I/O channel Address (0-15) */ +/* Bits 10-12 - I/O sub address (0-7) */ +/* Bits 13-15 - Aug code = 6 - CD */ +/* Bits 16-31 - Command Code (Device Dependent) */ + +/* Bits 13-15 - Aug code = 5 - TD */ +/* Bits 16-18 - TD Level 2000, 4000, 8000 */ +/* 01 - TD 2000 Level Status Testing */ +/* 02 - TD 4000 Level Status Testing */ +/* 04 - TD 8000 Level Status Testing */ +/* CC1 CC2 CC3 CC4 */ +/* TD8000 Undefined I/O Activ I/O Error Dev Stat Present */ +/* TD4000 Invd Mem Acc Mem Parity Prog Viol Data Ovr/Undr */ +/* TD2000 - Status Err - Controlr Absent */ + +/* Class F I/O device instruction format */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* |00 01 02 03 04 05|06 07 08|09 10 11 12|13 14 15|16|17 18 19 20 21 22 23|24 25 26 27 28 29 30 31| */ +/* | Op Code | Reg | I/O type | Aug |0 | Channel Address | Device Sub-address | */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* */ + +/* Bits 00-06 - Op code 0xFC */ +/* Bits 09-12 - I/O type */ +/* 00 - Unassigned */ +/* 01 - Unassigned */ +/* 02 - Start I/O (SIO) */ +/* 03 - Test I/O (TIO) */ +/* 04 - Stop I/O (STPIO */ +/* 05 - Reset channel (RSCHNL) */ +/* 06 - Halt I/O (HIO) */ +/* 07 - Grab controller (GRIO) Not supported */ +/* 08 - Reset controller (RSCTL) */ +/* 09 - Enable write channel WCS (ECWCS) Not supported */ +/* 0A - Unassigned */ +/* 0B - Write channel WCS (WCWCS) Not supported */ +/* 0C - Enable channel interrupt (ECI) */ +/* 0D - Disable channel interrupt (DCI) */ +/* 0E - Activate channel interrupt (ACI) */ +/* 0F - Deactivate channel interrupt (DACI) */ +/* Bits 13-15 - Aug Code */ +/* Bit 16 - unused - must be zero */ +/* Bits 16-23 - Channel address (0-127) */ +/* Bits 24-31 - Device Sub address (0-255) */ + +uint32 channels = MAX_CHAN; /* maximum number of channels */ +int subchannels = SUB_CHANS; /* maximum number of subchannel devices */ +int irq_pend = 0; /* pending interrupt flag */ + +extern uint32 CPUSTATUS; /* CPU status word */ +extern uint32 INTS[]; /* Interrupt status flags */ +extern uint32 TPSD[]; /* Temp save of PSD from memory 0&4 */ +extern uint8 waitqcnt; /* # of instructions to xeq b4 int */ +extern uint32 inbusy; +extern uint32 outbusy; + +DIB *dib_unit[MAX_DEV]; /* Pointer to Device info block */ +DIB *dib_chan[MAX_CHAN]; /* pointer to channel mux dib */ +uint16 loading; /* set when booting */ + +/* forward definitions */ +CHANP *find_chanp_ptr(uint16 chsa); /* find chanp pointer */ +UNIT *find_unit_ptr(uint16 chsa); /* find unit pointer */ +int chan_read_byte(uint16 chsa, uint8 *data); +int chan_write_byte(uint16 chsa, uint8 *data); +void set_devattn(uint16 chsa, uint16 flags); +void set_devwake(uint16 chsa, uint16 flags); /* wakeup O/S for async line */ +void chan_end(uint16 chsa, uint16 flags); +int test_write_byte_end(uint16 chsa); +t_stat checkxio(uint16 chsa, uint32 *status); /* check XIO */ +t_stat startxio(uint16 chsa, uint32 *status); /* start XIO */ +t_stat testxio(uint16 chsa, uint32 *status); /* test XIO */ +t_stat stoptxio(uint16 chsa, uint32 *status); /* stop XIO */ +t_stat rschnlxio(uint16 chsa, uint32 *status); /* reset channel XIO */ +t_stat haltxio(uint16 chsa, uint32 *status); /* halt XIO */ +t_stat grabxio(uint16 chsa, uint32 *status); /* grab XIO n/u */ +t_stat rsctlxio(uint16 chsa, uint32 *status); /* reset controller XIO */ +uint32 find_int_icb(uint16 chsa); +uint32 find_int_lev(uint16 chsa); +uint32 scan_chan(uint32 *ilev); +uint32 cont_chan(uint16 chsa); +t_stat set_inch(UNIT *uptr, uint32 inch_addr, uint32 num_inch); /* set inch addr */ +t_stat chan_boot(uint16 chsa, DEVICE *dptr); +t_stat chan_set_devs(); +t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc); +DEVICE *get_dev(UNIT *uptr); +void store_csw(CHANP *chp); +void push_csw(CHANP *chp); +int16 post_csw(CHANP *chp, uint32 rstat); + +/* FIFO support */ +/* These are FIFO queues which return an error when full. + * + * FIFO is empty when in == out. + * If in != out, then + * - items are placed into in before incrementing in + * - items are removed from out before incrementing out + * FIFO is full when in == (out-1 + FIFO_SIZE) % FIFO_SIZE; + * + * The queue will hold FIFO_SIZE items before the calls + * to FIFO_Put fails. + */ + +/* initialize FIFO to empty in boot channel code */ + +/* add an entry to the start of the FIFO */ +int32 FIFO_Push(uint16 chsa, uint32 entry) +{ + int32 num; /* number of entries */ + DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ + if (dibp == NULL) { + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Push ERR NULL dib ptr for chsa %04x\n", chsa); + return -1; /* FIFO address error */ + } + + if (dibp->chan_fifo_in == ((dibp->chan_fifo_out-1+FIFO_SIZE) % FIFO_SIZE)) { + num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Push ERR FIFO full for chsa %04x count %02x\n", chsa, num); + return -1; /* FIFO Full */ + } + dibp->chan_fifo_out += (FIFO_SIZE - 1); /* get index to previous first entry */ + dibp->chan_fifo_out %= FIFO_SIZE; /* modulo FIFO size */ + dibp->chan_fifo[dibp->chan_fifo_out] = entry; /* add new entry to be new first */ + num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Push to FIFO for chsa %04x count %02x\n", chsa, num); + return SCPE_OK; /* all OK */ +} + +/* add an entry to the FIFO */ +int32 FIFO_Put(uint16 chsa, uint32 entry) +{ + int32 num; /* number of entries */ + DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ + if (dibp == NULL) { + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Put ERR NULL dib ptr for chsa %04x\n", chsa); + return -1; /* FIFO address error */ + } + + if (dibp->chan_fifo_in == ((dibp->chan_fifo_out-1+FIFO_SIZE) % FIFO_SIZE)) { + num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Put ERR FIFO full for chsa %04x count %02x\n", chsa, num); + return -1; /* FIFO Full */ + } + dibp->chan_fifo[dibp->chan_fifo_in] = entry; /* add new entry */ + dibp->chan_fifo_in += 1; /* next entry */ + dibp->chan_fifo_in %= FIFO_SIZE; /* modulo FIFO size */ + num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; + return SCPE_OK; /* all OK */ +} + +/* get the next entry from the FIFO */ +int32 FIFO_Get(uint16 chsa, uint32 *old) +{ + DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ + if (dibp == NULL) { + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Get ERR NULL dib ptr for chsa %04x\n", chsa); + return -1; /* FIFO address error */ + } + + /* see if the FIFO is empty */ + if (dibp->chan_fifo_in == dibp->chan_fifo_out) { + return -1; /* FIFO is empty, tell caller */ + } + *old = dibp->chan_fifo[dibp->chan_fifo_out]; /* get the next entry */ + dibp->chan_fifo_out += 1; /* next entry */ + dibp->chan_fifo_out %= FIFO_SIZE; /* modulo FIFO size */ + return SCPE_OK; /* all OK */ +} + +/* get number of entries in FIFO for channel */ +int32 FIFO_Num(uint16 chsa) +{ + int32 num; /* number of entries */ + DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ + if (dibp == NULL) { + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Num ERR NULL dib ptr for chsa %04x\n", chsa); + return 0; /* FIFO address error */ + } + /* calc entries */ + num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; + return (num>>1); /*GT*/ /* two words/entry */ +} + +/* add an entry to the IOCLQ */ +int32 IOCLQ_Put(IOCLQ *qptr, uint32 entry) +{ + int32 num; /* number of entries */ + if (qptr == NULL) { + sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Put ERROR NULL qptr\n"); + return -1; /* IOCLQ address error */ + } + + if (qptr->ioclq_in == ((qptr->ioclq_out-1+IOCLQ_SIZE) % IOCLQ_SIZE)) { + num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE; + sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Put ERROR IOCLQ full, entries %02x\n", num); + return -1; /* IOCLQ Full */ + } + qptr->ioclq_fifo[qptr->ioclq_in] = entry; /* add new entry */ + qptr->ioclq_in += 1; /* next entry */ + qptr->ioclq_in %= IOCLQ_SIZE; /* modulo IOCLQ size */ + num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE; + return SCPE_OK; /* all OK */ +} + +/* get the next entry from the IOCLQ */ +int32 IOCLQ_Get(IOCLQ *qptr, uint32 *old) +{ + if (qptr == NULL) { + sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Get ERROR NULL qptr\n"); + return -1; /* IOCLQ address error */ + } + + /* see if the IOCLQ is empty */ + if (qptr->ioclq_in == qptr->ioclq_out) { + return -1; /* IOCLQ is empty, tell caller */ + } + *old = qptr->ioclq_fifo[qptr->ioclq_out]; /* get the next entry */ + qptr->ioclq_out += 1; /* next entry */ + qptr->ioclq_out %= IOCLQ_SIZE; /* modulo IOCLQ size */ + return SCPE_OK; /* all OK */ +} + +/* get number of entries in IOCLQ for channel */ +int32 IOCLQ_Num(IOCLQ *qptr) +{ + int32 num = 0; /* number of entries */ + if (qptr == NULL) { + sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Num ERROR NULL qptr\n"); + return num; /* IOCLQ address error */ + } + /* calc entries */ + num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE; + return num; /* one words/entry */ +} + +/* + * Number of inch buffers defined for each channel + * IOP 128 Dbl words + * MFP 128 Dbl words + * 8-line uses IOP/MFP (128) + * BTP tape 2 DBL wds + * UDP disk 33 Dbl wds + * SCFI disk 33 Dbl wds + * HSDP disk 33 Dbl wds + * SCSI disk uses MFP (128) + * LP uses IOP/MFP (128) + * Console uses IOP/MFP (128) + * Ethernet 1 Dbl wd + * */ +/* Set INCH buffer address for channel */ +/* return SCPE_OK or SCPE_MEM if invalid address or SCPE_ARG if already defined */ +t_stat set_inch(UNIT *uptr, uint32 inch_addr, uint32 num_inch) { + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + uint32 chan = chsa & 0x7f00; /* get just channel address */ + uint32 last = inch_addr + (num_inch-1)*8; /* last inch address to use */ + CHANP *chp; + int i, j; + DIB *dibp = dib_chan[chan>>8]; /* get channel dib ptr */ + CHANP *pchp = 0; /* for channel prog ptr */ + + /* must be valid DIB pointer */ + if (dibp == NULL) + return SCPE_MEM; /* return memory error */ + pchp = dibp->chan_prg; /* get parent channel prog ptr */ + + /* must be valid channel pointer */ + if (pchp == NULL) + return SCPE_MEM; /* return memory error */ + + /* see if start valid memory address */ + if (!MEM_ADDR_OK(inch_addr)) /* see if mem addr >= MEMSIZE */ + return SCPE_MEM; /* return memory error */ + + /* see if end valid memory address */ + if (!MEM_ADDR_OK(last)) /* see if mem addr >= MEMSIZE */ + return SCPE_MEM; /* return memory error */ + + /* set INCH address for all units on master channel */ + chp = pchp; + for (i=0; inumunits; i++) { + chp->chan_inch_addr = inch_addr; /* set the current inch addr */ + chp->base_inch_addr = inch_addr; /* set the base inch addr */ + chp->max_inch_addr = last; /* set the last inch addr */ + chp++; /* next unit channel */ + } + + sim_debug(DEBUG_XIO, &cpu_dev, + "set_inch chan %04x inch addr %06x last %06x chp %p\n", + chan, inch_addr, last, chp); + + /* now go through all the sub addresses for the channel and set inch addr */ + for (i=0; ichan_prg; /* get first unit channel prog ptr */ + /* set INCH address for all units on channel */ + for (j=0; jnumunits; j++) { + chp->chan_inch_addr = inch_addr; /* set the inch addr */ + chp->base_inch_addr = inch_addr; /* set the base inch addr */ + chp->max_inch_addr = last; /* set the last inch addr */ + chp++; /* next unit channel */ + } + } + return SCPE_OK; /* All OK */ +} + +/* Find interrupt level for the given physical device (ch/sa) */ +/* return 0 if not found, otherwise level number */ +uint32 find_int_lev(uint16 chsa) +{ + uint32 inta; + /* get the device entry for channel in SPAD */ + uint32 spadent = SPAD[get_chan(chsa)]; /* get spad device entry for logical channel */ + + if ((spadent == 0) || ((spadent&MASK24) == MASK24)) { /* see if valid entry */ + sim_debug(DEBUG_EXP, &cpu_dev, + "find_int_lev ERR chsa %04x spadent %08x\n", chsa, spadent); + return 0; /* not found */ + } + inta = ((~spadent)>>16)&0x7f; /* get interrupt level */ + return(inta); /* return the level*/ +} + +/* Find interrupt context block address for given device (ch/sa) */ +/* return 0 if not found, otherwise ICB memory address */ +uint32 find_int_icb(uint16 chsa) +{ + uint32 inta, icba; + + inta = find_int_lev(chsa); /* find the int level */ + if (inta == 0) { + sim_debug(DEBUG_EXP, &cpu_dev, + "find_int_icb ERR chsa %04x inta %02x\n", chsa, inta); + return 0; /* not found */ + } + /* add interrupt vector table base address plus int # byte address offset */ + icba = SPAD[0xf1] + (inta<<2); /* interrupt vector address in memory */ + if (!MEM_ADDR_OK(icba)) { /* needs to be valid address in memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "find_int_icb ERR chsa %04x icba %02x\n", chsa, icba); + return 0; /* not found */ + } + icba = RMW(icba); /* get address of ICB from memory */ + if (!MEM_ADDR_OK(icba)) { /* needs to be valid address in memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "find_int_icb ERR chsa %04x icba %02x\n", chsa, icba); + return 0; /* not found */ + } + return(icba); /* return the address */ +} + +/* Find unit pointer for given device (ch/sa) */ +UNIT *find_unit_ptr(uint16 chsa) +{ + struct dib *dibp; /* DIB pointer */ + UNIT *uptr; /* UNIT pointer */ + int i; + + dibp = dib_unit[chsa]; /* get DIB pointer from device address */ + if (dibp == 0) { /* if zero, not defined on system */ + sim_debug(DEBUG_EXP, &cpu_dev, + "find_unit_ptr ERR chsa %04x dibp %p\n", chsa, dibp); + return NULL; /* tell caller */ + } + + uptr = dibp->units; /* get the pointer to the units on this channel */ + if (uptr == 0) { /* if zero, no devices defined on system */ + sim_debug(DEBUG_EXP, &cpu_dev, + "find_unit_ptr ERR chsa %04x uptr %p\n", chsa, uptr); + return NULL; /* tell caller */ + } + + for (i = 0; i < dibp->numunits; i++) { /* search through units to get a match */ + if (chsa == GET_UADDR(uptr->u3)) { /* does ch/sa match? */ + return uptr; /* return the pointer */ + } + uptr++; /* next unit */ + } + return NULL; /* device not found on system */ +} + +/* Find channel program pointer for given device (ch/sa) */ +CHANP *find_chanp_ptr(uint16 chsa) +{ + struct dib *dibp; /* DIB pointer */ + UNIT *uptr; /* UNIT pointer */ + CHANP *chp; /* CHANP pointer */ + int i; + + dibp = dib_unit[chsa]; /* get DIB pointer from unit address */ + if (dibp == 0) { /* if zero, not defined on system */ + sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x dibp %p\n", chsa, dibp); + return NULL; /* tell caller */ + } + if ((chp = (CHANP *)dibp->chan_prg) == NULL) { /* must have channel information for each device */ + sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x chp %p\n", chsa, chp); + return NULL; /* tell caller */ + } + + uptr = dibp->units; /* get the pointer to the units on this channel */ + if (uptr == 0) { /* if zero, no devices defined on system */ + sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x uptr %p\n", chsa, uptr); + return NULL; /* tell caller */ + } + + for (i = 0; i < dibp->numunits; i++) { /* search through units to get a match */ + if (chsa == GET_UADDR(uptr->u3)) { /* does ch/sa match? */ + return chp; /* return the pointer */ + } + uptr++; /* next UNIT */ + chp++; /* next CHANP */ + } + sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x no match uptr %p\n", chsa, uptr); + return NULL; /* device not found on system */ +} + +/* Read a full word into memory. + * Return 1 if fail. + * Return 0 if success. + */ +int readfull(CHANP *chp, uint32 maddr, uint32 *word) +{ + maddr &= MASK24; /* mask addr to 24 bits */ + if (!MEM_ADDR_OK(maddr)) { /* see if mem addr >= MEMSIZE */ + chp->chan_status |= STATUS_PCHK; /* program check error */ + sim_debug(DEBUG_EXP, &cpu_dev, + "readfull read %08x from addr %08x ERROR\n", *word, maddr); + return 1; /* show we have error */ + } + *word = RMW(maddr); /* get 1 word */ + sim_debug(DEBUG_XIO, &cpu_dev, "READFULL chsa %04x read %08x from addr %08x\n", + chp->chan_dev, *word, maddr); + return 0; /* return OK */ +} + +/* Read a byte into the channel buffer. + * Return 1 if fail. + * Return 0 if success. + */ +int readbuff(CHANP *chp) +{ + uint32 addr = chp->ccw_addr; /* channel buffer address */ + + if (!MEM_ADDR_OK(addr & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ + sim_debug(DEBUG_EXP, &cpu_dev, + "readbuff PCHK addr %08x to big mem %08x status %04x\n", + addr, MEMSIZE, chp->chan_status); + chp->chan_byte = BUFF_CHNEND; /* force channel end & busy */ + return 1; /* done, with error */ + } + chp->chan_buf = RMB(addr&MASK24); /* get 1 byte */ + return 0; +} + +/* Write byte to channel buffer in memory. + * Return 1 if fail. + * Return 0 if success. + */ +int writebuff(CHANP *chp) +{ + uint32 addr = chp->ccw_addr; + + if (!MEM_ADDR_OK(addr & MASK24)) { /* make sure write to good addr */ + chp->chan_status |= STATUS_PCHK; /* non-present memory, abort */ + sim_debug(DEBUG_EXP, &cpu_dev, + "writebuff PCHK addr %08x to big mem %08x status %04x\n", + addr, MEMSIZE, chp->chan_status); + chp->chan_byte = BUFF_CHNEND; /* force channel end & busy */ + return 1; + } + addr &= MASK24; /* good address, write the byte */ + sim_debug(DEBUG_DATA, &cpu_dev, "writebuff WRITE addr %06x DATA %08x status %04x\n", + addr, chp->chan_buf, chp->chan_status); + WMB(addr, chp->chan_buf); /* write byte to memory */ + return 0; +} + +/* load in the IOCD and process the commands */ +/* return = 0 OK */ +/* return = 1 error, chan_status will have reason */ +int32 load_ccw(CHANP *chp, int32 tic_ok) +{ + uint32 word1 = 0; + uint32 word2 = 0; + int32 docmd = 0; + DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ + UNIT *uptr = chp->unitptr; /* get the unit ptr */ + uint16 chan = get_chan(chp->chan_dev); /* our channel */ + uint16 chsa = chp->chan_dev; /* our chan/sa */ + uint16 devstat = 0; + + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x entry chan_status[%02x]=%04x\n", + chp->chan_caw, chan, chp->chan_status); +#ifdef TEST_FOR_IOCL_CHANGE + /* see if iocla or iocd has changed since start */ + if (!loading && (chp->chan_info & INFO_SIOCD)) { /* see if 1st IOCD in channel prog */ + uint32 chan_icb; /* Interrupt level context block address */ + uint32 iocla; /* I/O channel IOCL address int ICB */ + + chan_icb = find_int_icb(chsa); /* Interrupt level context block address */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + word1 = RMW(iocla & MASK24); /* get 1st IOCL word */ + word2 = RMW((iocla + 4) & MASK24); /* get 2nd IOCL word */ + if (chp->chan_caw != iocla) { + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw iocla (%06x) != chan_caw (%06x) chsa %04x\n", + iocla, chp->chan_caw, chsa); + } else + { + /* iocla has not changed, see if IOCD has */ + if (chp->new_iocla != iocla) { /* check current iocla */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw iocla (%06x) != new_iocla (%06x) chsa %04x\n", + iocla, chp->new_iocla, chsa); + } + if (word1 != chp->new_iocd1) { /* check word1 from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw iocd1 (%06x) != new_iocd1 (%06x) chsa %04x\n", + word1, chp->new_iocd1, chsa); + } + if (word2 != chp->new_iocd2) { /* check word2 from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw iocd2 (%06x) != new_iocd2 (%06x) chsa %04x\n", + word2, chp->new_iocd2, chsa); + } + } + } +#endif + + /* determine if channel DIB has a pre iocl processor */ + if (dibp->iocl_io != NULL) { /* NULL if no function */ + /* call the device controller to process the iocl */ + int32 tempa = dibp->iocl_io(chp, tic_ok); /* process IOCL */ + if (tempa != SCPE_OK) { /* see if OK */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw iocl_io call return ERROR chan %04x cstat %01x\n", chan, tempa); + } else { + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw iocl_io call return OK chan %04x cstat %01x\n", chan, tempa); + } + return tempa; /* just return status */ + } + /* check for valid iocd address if 1st iocd */ + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + if (chp->chan_caw & 0x3) { /* must be word bounded */ + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw iocd bad address chsa %02x caw %06x\n", + chsa, chp->chan_caw); + /* the disk returns the bad iocl in sw1 */ + chp->ccw_addr = chp->chan_caw & MASK24; /* set the bad IOCL address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ + return 1; /* error return */ + } + } + +loop: + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x @loop chan_status[%02x]=%04x\n", + chp->chan_caw, chan, chp->chan_status); + + /* Abort if we have any errors */ + if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw ERROR1 chan_status[%02x]=%04x\n", chan, chp->chan_status); + return 1; + } + + /* Read in first CCW */ + if (readfull(chp, chp->chan_caw, &word1) != 0) { /* read word1 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw ERROR2 chan_status[%02x]=%04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Read in second CCW */ + if (readfull(chp, chp->chan_caw+4, &word2) != 0) { /* read word2 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw ERROR3 chan_status[%02x]=%04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x read ccw chan %02x IOCD wd 1 %08x wd 2 %08x\n", + chp->chan_caw, chan, word1, word2); + + chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */ + + /* Check if we had data chaining in previous iocd */ + /* if we did, use previous cmd value */ + if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + (chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */ + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x DO DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + } else + chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ + + if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw bad IOCD1 chan_status[%02x]=%04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2*/ + + /* here is where we would validate the device commands */ + + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + /* 1st command can not be a TIC */ + if (chp->ccw_cmd == CMD_TIC) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw TIC bad cmd chan_status[%02x]=%04x\n", + chan, chp->chan_status); + return 1; /* error return */ + } + } + + /* TIC can't follow TIC or be first in command chain */ + /* diags send bad commands for testing. Use all of op */ + if (chp->ccw_cmd == CMD_TIC) { + if (tic_ok) { + if (((word1 & MASK24) == 0) || (word1 & 0x3)) { + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw tic cmd bad address chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + return 1; /* error return */ + } + tic_ok = 0; /* another tic not allowed */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw tic cmd ccw chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + goto loop; /* restart the IOCD processing */ + } + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw TIC ERROR chan_status[%02x]=%04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Check if we had data chaining in previous iocd */ + if ((chp->chan_info & INFO_SIOCD) || /* see if 1st IOCD in channel prog */ + (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + ((chp->ccw_flags & FLAG_DC) == 0))) { /* last IOCD have DC set? */ + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x DO CMD No DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + docmd = 1; /* show we have a command */ + } + + /* Set up for this command */ + chp->ccw_flags = (word2 >> 16) & 0xfc00; /* get flags from bits 0-6 of WD 2 of IOCD */ + chp->chan_status = 0; /* clear status for next IOCD */ + /* make a 24 bit address */ + chp->ccw_addr = word1 & MASK24; /* set the data/seek address */ + + if (chp->ccw_flags & FLAG_PCI) { /* do we have prog controlled int? */ + chp->chan_status |= STATUS_PCI; /* set PCI flag in status */ + irq_pend = 1; /* interrupt pending */ + } + + /* validate parts of IOCD2 that is reserved, bits 5-15 */ + if (word2 & 0x07ff0000) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw bad IOCD2 chan_status[%02x]=%04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* DC can only be used with a read/write cmd */ + /* TODO move ccw code to LPR processing */ + /* TEMP FIX FOR LPR */ + if ((chp->ccw_flags & FLAG_DC) && (chsa != 0x7ef8)) { + if ((chp->ccw_cmd != 0x02) && (chp->ccw_cmd != 0x01)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid DC */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw DC ERROR chan_status[%02x]=%04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + } + + chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ + + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x read docmd %01x addr %06x count %04x chsa %04x ccw_flags %04x\n", + chp->chan_caw, docmd, chp->ccw_addr, chp->ccw_count, chsa, chp->ccw_flags); + + if (docmd) { /* see if we need to process a command */ + DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ + + uptr = chp->unitptr; /* get the unit ptr */ + if (dibp == 0 || uptr == 0) { + chp->chan_status |= STATUS_PCHK; /* program check if it is */ + return 1; /* if none, error */ + } + + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x before start_cmd chsa %04x status %04x count %04x SNS %08x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count, uptr->u5); + + /* call the device startcmd function to process the current command */ + /* just replace device status bits */ + chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ + devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd); + chp->chan_status = (chp->chan_status & 0xff00) | devstat; + chp->chan_info &= ~INFO_SIOCD; /* not first IOCD in channel prog */ + + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x after start_cmd chsa %04x status %08x count %04x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count); + + /* We will get a SNS_BSY status returned if device doing a command */ + /* We get STATUS_CEND & STATUS_DEND and an error */ + /* We get SCPE_OK (0) saying cmd is ready to process */ + /* see if bad status */ + if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) { + chp->chan_status |= STATUS_CEND; /* channel end status */ + chp->ccw_flags = 0; /* no flags */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw bad status chsa %04x status %04x cmd %02x\n", + chsa, chp->chan_status, chp->ccw_cmd); + /* done with command */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw ERROR return chsa %04x status %08x\n", + chp->chan_dev, chp->chan_status); + return 1; /* error return */ + } + /* NOTE this code needed for MPX 1.X to run! */ + /* see if command completed */ + /* we have good status */ + /* TODO Test if chan_end called? */ + if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n", + chp->chan_caw, FIFO_Num(chsa), chan, chp->chan_status, chp->ccw_count); + } + } + /* the device processor returned OK (0), so wait for I/O to complete */ + /* nothing happening, so return */ + sim_debug(DEBUG_XIO, &cpu_dev, + "load_ccw @%06x return, chsa %04x status %04x count %04x irq_pend %1x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count, irq_pend); + return 0; /* good return */ +} + +/* read byte from memory */ +/* write to device */ +int chan_read_byte(uint16 chsa, uint8 *data) +{ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + int byte; + + /* Abort if we have any errors */ + if (chp->chan_status & STATUS_ERROR) /* check channel error status */ + return 1; /* return error */ + + if (chp->chan_byte == BUFF_CHNEND) /* check for end of data */ + return 1; /* yes, return error */ + + if (chp->ccw_count == 0) { /* see if more data required */ + if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if Data Chain */ + chp->chan_byte = BUFF_CHNEND; /* buffer end too */ + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_read_byte no DC chan end, cnt %04x addr %06x chsa %04x\n", + chp->ccw_count, chp->ccw_addr, chsa); + return 1; /* return error */ + } else { + /* we have data chaining, process iocl */ + if (load_ccw(chp, 1)) { /* process data chaining */ + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_read_byte with DC error, cnt %04x addr %06x chsa %04x\n", + chp->ccw_count, chp->ccw_addr, chsa); + return 1; /* return error */ + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "chan_read_byte with DC IOCD loaded, cnt %04x addr %06x chsa %04x\n", + chp->ccw_count, chp->ccw_addr, chsa); + } + } + /* get the next byte from memory */ + if (readbuff(chp)) /* read next char */ + return 1; /* return error */ + + /* get the byte of data */ + byte = chp->chan_buf; /* read byte from memory */ + *data = byte; /* return the data */ + sim_debug(DEBUG_DATA, &cpu_dev, "chan_read_byte transferred %02x\n", byte); + chp->ccw_addr += 1; /* next byte address */ + chp->ccw_count--; /* one char less to process */ + return 0; /* good return */ +} + +/* test end of write byte I/O (device read) */ +int test_write_byte_end(uint16 chsa) +{ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + + /* see if at end of buffer */ + if (chp->chan_byte == BUFF_CHNEND) /* check for end of data */ + return 1; /* return done */ + if (chp->ccw_count == 0) { + if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if we have data chaining */ + chp->chan_byte = BUFF_CHNEND; /* thats all the data we want */ + return 1; /* return done */ + } + } + return 0; /* not done yet */ +} + +/* write byte to memory */ +/* read from device */ +int chan_write_byte(uint16 chsa, uint8 *data) +{ + int chan = get_chan(chsa); /* get the channel number */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + + /* Abort if we have any errors */ + if (chp->chan_status & STATUS_ERROR) /* check channel error status */ + return 1; /* return error */ + + /* see if at end of buffer */ + if (chp->chan_byte == BUFF_CHNEND) { /* check for end of data */ + /* if SLI not set, we have incorrect length */ + if ((chp->ccw_flags & FLAG_SLI) == 0) { + sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte 4 setting SLI ret\n"); + chp->chan_status |= STATUS_LENGTH; /* set SLI */ + } + return 1; /* return error */ + } + if (chp->ccw_count == 0) { + if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if we have data chaining */ + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_write_byte no DC ccw_flags %04x\n", chp->ccw_flags); + chp->chan_status |= STATUS_CEND; /* no, end of data */ + chp->chan_byte = BUFF_CHNEND; /* thats all the data we want */ + return 1; /* return done error */ + } else { + /* we have data chaining, process iocl */ + if (load_ccw(chp, 1)) { /* process data chaining */ + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_write_byte with DC error, cnt %04x addr %06x chan %04x\n", + chp->ccw_count, chp->ccw_addr, chan); + return 1; /* return error */ + } + } + } + /* we have data byte to write to chp->ccw_addr */ + /* see if we want to skip writing data to memory */ + if (chp->ccw_flags & FLAG_SKIP) { + chp->ccw_count--; /* decrement skip count */ + chp->chan_byte = BUFF_BUSY; /* busy, but no data */ + if ((chp->ccw_cmd & 0xff) == CMD_RDBWD) + chp->ccw_addr--; /* backward */ + else + chp->ccw_addr++; /* forward */ + return 0; + } + chp->chan_buf = *data; /* get data byte */ + if (writebuff(chp)) /* write the byte */ + return 1; + + chp->ccw_count--; /* reduce count */ + chp->chan_byte = BUFF_BUSY; /* busy, but no data */ + if ((chp->ccw_cmd & 0xff) == CMD_RDBWD) /* see if reading backwards */ + chp->ccw_addr -= 1; /* no, use previous address */ + else + chp->ccw_addr += 1; /* yes, use next address */ + return 0; +} + +/* post wakeup interrupt for specified async line */ +void set_devwake(uint16 chsa, uint16 flags) +{ + uint32 stwd1, stwd2; /* words 1&2 of stored status */ + /* put sub address in byte 0 */ + stwd1 = (chsa & 0xff) << 24; /* subaddress and IOCD address to SW 1 */ + /* save 16 bit channel status and residual byte count in SW 2 */ + stwd2 = (uint32)flags << 16; + if ((FIFO_Put(chsa, stwd1) == -1) || (FIFO_Put(chsa, stwd2) == -1)) { + sim_debug(DEBUG_EXP, &cpu_dev, + "set_devwake FIFO Overflow ERROR on chsa %04x\n", chsa); + } + irq_pend = 1; /* wakeup controller */ +} + +/* post interrupt for specified channel */ +void set_devattn(uint16 chsa, uint16 flags) +{ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + + if (chp == NULL) { + /* can not do anything, so just return */ + sim_debug(DEBUG_EXP, &cpu_dev, "set_devattn chsa %04x, flags %04x\n", chsa, flags); + fprintf(stdout, "set_devattn chsa %04x invalid configured device\n", chsa); +// fflush(stdout); + return; + } + + if (chp->chan_dev == chsa && (chp->chan_status & STATUS_CEND) != 0 && (flags & SNS_DEVEND) != 0) { + chp->chan_status |= ((uint16)flags); + } + sim_debug(DEBUG_CMD, &cpu_dev, "set_devattn(%04x, %04x) %04x\n", chsa, flags, chp->chan_dev); + irq_pend = 1; +} + +/* channel operation completed */ +void chan_end(uint16 chsa, uint16 flags) { + uint16 tstat, tcnt; + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + + sim_debug(DEBUG_CMD, &cpu_dev, + "chan_end entry chsa %04x flags %04x status %04x cmd %02x cpustatus %08x\n", + chsa, flags, chp->chan_status, chp->ccw_cmd, CPUSTATUS); +// fflush(sim_deb); + + /* see if already called */ + if (chp->chan_info & INFO_CEND) { + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_end INFO_CEND set chsa %04x ccw_flags %04x status %04x byte %02x\n", + chsa, chp->ccw_flags, chp->chan_status, chp->chan_byte); + } + chp->chan_info |= INFO_CEND; /* we have been here */ + + chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */ + chp->chan_status |= STATUS_CEND; /* set channel end */ + chp->chan_status |= ((uint16)flags); /* add in the callers flags */ + + /* read/write must have none-zero byte count */ + /* all others can be zero, except NOP, which must be 0 */ + /* a NOP is Control command 0x03 with no modifier bits */ + /* see if this is a read/write cmd */ + if (((chp->ccw_cmd & 0x7) == 0x02) || ((chp->ccw_cmd & 0x7) == 0x01)) { + /* test for incorrect transfer length */ + if (chp->ccw_count != 0 && ((chp->ccw_flags & FLAG_SLI) == 0)) { + if ((chp->chan_status & STATUS_PCHK) == 0) /* No SLI if channel prg check */ + chp->chan_status |= STATUS_LENGTH; /* show incorrect length status */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "chan_end setting SLI chsa %04x count %04x ccw_flags %04x status %04x\n", + chsa, chp->ccw_count, chp->ccw_flags, chp->chan_status); + chp->ccw_flags = 0; /* no iocl flags */ + } + } + + /* Diags do not want SLI if we have no device end status */ + if ((chp->chan_status & STATUS_LENGTH) && ((chp->chan_status & STATUS_DEND) == 0)) + chp->chan_status &= ~STATUS_LENGTH; + + /* no flags for attention status */ + if (flags & (SNS_ATTN|SNS_UNITCHK|SNS_UNITEXP)) { + chp->ccw_flags = 0; /* no flags */ + } + + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_end test end chsa %04x ccw_flags %04x status %04x byte %02x\n", + chsa, chp->ccw_flags, chp->chan_status, chp->chan_byte); + + /* test for device or controller end */ + if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { + chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */ + sim_debug(DEBUG_XIO, &cpu_dev, + "chan_end FIFO #%1x IOCL done chsa %04x ccw_flags %04x status %04x\n", + FIFO_Num(chsa), chsa, chp->ccw_flags, chp->chan_status); + + /* handle a PPCI here. DC is done and maybe have CC */ + if ((chp->chan_status & STATUS_PCI) && (chp->ccw_flags & FLAG_CC)) { + chp->chan_status &= ~STATUS_PCI; /* done with PCI */ + tstat = chp->chan_status; /* save status */ + tcnt = chp->ccw_count; /* save count */ + chp->chan_status = STATUS_PCI; /* set PCI status */ + chp->ccw_count = 0; /* zero count */ + store_csw(chp); /* store the status */ + chp->chan_status = tstat; /* restore status */ + chp->ccw_count = tcnt; /* restore count */ + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_end done PCI chsa %04x ccw_flags %04x stat %04x cnt %04x\n", + chsa, chp->ccw_flags, tstat, tcnt); + } + + /* If channel end, check if we should continue */ + if (chp->ccw_flags & FLAG_CC) { /* command chain flag */ + /* we have channel end and CC flag, continue channel prog */ + sim_debug(DEBUG_CMD, &cpu_dev, + "chan_end chan end & CC chsa %04x status %04x\n", + chsa, chp->chan_status); + if (chp->chan_status & STATUS_DEND) { /* device end? */ + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_end dev end & CC chsa %04x status %04x IOCLA %08x\n", + chsa, chp->chan_status, chp->chan_caw); + /* Queue us to continue from cpu level */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_end set RDYQ %04x Have CC BUFF_NEXT chp %p chan_byte %04x\n", + chsa, chp, chp->chan_byte); + if (cont_chan(chsa)) { /* continue processing channel */ + sim_debug(DEBUG_EXP, &cpu_dev, "call cont_chan returns not OK\n"); + } + } + /* just return */ + goto goout; + } else { + /* we have channel end and no CC flag, continue channel prog */ + UNIT *uptr = chp->unitptr; /* get the unit ptr */ + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->u3); + int unit = (uptr-dptr->units); /* get the UNIT number */ + DIB* dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */ + IOCLQ *qp = &dibp->ioclq_ptr[unit]; /* IOCLQ pointer */ + uint32 iocla; + + /* we have channel end and no CC flag, end this iocl command */ + sim_debug(DEBUG_CMD, &cpu_dev, + "chan_end chan end & no CC chsa %04x status %04x cmd %02x\n", + chsa, chp->chan_status, chp->ccw_cmd); + + /* we have completed channel program */ + /* handle case where we are loading the O/S on boot */ + /* if loading, store status to be discovered by scan_chan */ + if (!loading) { + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_end call store_csw dev/chan end chsa %04x cpustat %08x iocla %08x\n", + chsa, CPUSTATUS, chp->chan_caw); + } else { + /* we are loading, so keep moving */ + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_end we are loading O/S with DE & CE, keep status chsa %04x status %08x\n", + chsa, chp->chan_status); + } + /* store the status in channel FIFO to continue from cpu level */ + chp->chan_byte = BUFF_DONE; /* we are done */ + store_csw(chp); /* store the status */ + /* change chan_byte to BUFF_POST */ + chp->chan_byte = BUFF_POST; /* show done with data */ + chp->ccw_cmd = 0; /* no command anymore */ + + if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ + qp = &dibp->ioclq_ptr[unit]; /* IOCLQ pointer */ + /* we have an error, so delete all other IOCLQ entries */ + while ((dibp->ioclq_ptr != NULL) && (qp != NULL) && IOCLQ_Get(qp, &iocla) == SCPE_OK) { + sim_debug(DEBUG_EXP, &cpu_dev, + "$$ CHEND removed IOCL from IOCLQ processing chsa %04x iocla %06x\n", + chsa, iocla); + } + chp->chan_status = 0; /* no channel status yet */ + } else + /* no error, see if we have a queued IOCL to start */ + /* This causes an error for hsdp where we just finished the I/O */ + /* but the status has not been posted yet nor the interrupt */ + /* starting another I/O confuses the scan_chan code and ends up */ + /* doing an extra interrupt for UTX 05/21/2021 */ + if ((dibp->ioclq_ptr != NULL) && (qp != NULL) && IOCLQ_Get(qp, &iocla) == SCPE_OK) { + /* channel not busy and ready to go, so start a new command */ + chp->chan_status = 0; /* no channel status yet */ + chp->chan_caw = iocla; /* get iocla address in memory */ + /* added 09/25/20 to fix hangs in iocl processing */ + chp->ccw_flags = 0; /* clear flags */ + + /* set status words in memory to first IOCD information */ + sim_debug(DEBUG_CMD, &cpu_dev, + "$$ CHEND start IOCL processing from IOCLQ num %02x chsa %04x iocla %06x\n", + IOCLQ_Num(qp), chsa, iocla); + + /* We are queueing the SIO */ + /* Queue us to continue IOCL from cpu level & make busy */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */ + sim_debug(DEBUG_CMD, &cpu_dev, + "chan_end BUFF_NEXT chsa %04x from IOCLQ cnt %02x chp %p chan_byte %04x\n", + chsa, IOCLQ_Num(qp), chp, chp->chan_byte); + // FIXME - need to call iocl processing here */ + if (cont_chan(chsa)) { /* continue processing channel */ + sim_debug(DEBUG_EXP, &cpu_dev, "call cont_chan returns not OK\n"); + } + sim_debug(DEBUG_CMD, &cpu_dev, + "CHEND SIOQ queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n", + chsa, iocla, RMW(iocla), RMW(iocla+4)); + + } + } + } +goout: + sim_debug(DEBUG_CMD, &cpu_dev, + "chan_end done chsa %04x status %08x chan_byte %02x\n", + chsa, chp->chan_status, chp->chan_byte); + /* following statement required for boot to work */ + irq_pend = 1; /* flag to test for int condition */ +} + +/* post the device status from the channel FIFO into memory */ +/* the INCH command provides the status DW address in memory */ +/* rstat are the bits to remove from status */ +int16 post_csw(CHANP *chp, uint32 rstat) +{ + uint32 chsa = chp->chan_dev; /* get ch/sa information */ + uint32 incha = chp->chan_inch_addr; /* get inch status buffer address */ + uint32 sw1, sw2; /* status words */ + + irq_pend = 1; /* flag to test for int condition */ + /* check channel FIFO for status to post */ + if ((FIFO_Num(chsa)) && + ((FIFO_Get(chsa, &sw1) == 0) && (FIFO_Get(chsa, &sw2) == 0))) { + /* get chan_icb address */ + uint32 chan_icb = RMW(SPAD[0xf1] + (chp->chan_int<<2)); + + if (chan_icb == 0) { + sim_debug(DEBUG_EXP, &cpu_dev, + "post_csw %04x READ FIFO #%1x inch %06x invalid chan_icb %06x\n", + chsa, FIFO_Num(chsa), incha, chan_icb); + return 0; /* no status to post */ + } + if (chp->chan_byte != BUFF_POST) { + sim_debug(DEBUG_EXP, &cpu_dev, + "post_csw %04x CHP %p not BUFF_POST byte %04x ERROR FIFO #%1x inch %06x icb %06x\n", + chsa, chp, chp->chan_byte, FIFO_Num(chsa), incha, chan_icb); + } + /* remove user specified bits */ + sw2 &= ~rstat; /* remove bits */ + /* we have status to post, do it now */ + /* save the status double word to memory */ + /* if bit 0 of sw2 is set (STATUS_ECHO), post inch addr 0 with bit 0 set */ + if (sw2 & BIT0) { /* see if only not busy post */ + WMW(chan_icb+20, 0x80000000); /* post sw addr 0 in ICB+5w & reset CCs */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "post_csw %04x READ0 FIFO #%1x inch 0x80000000 chan_icb %06x sw1 %08x sw2 %08x\n", + chsa, FIFO_Num(chsa), chan_icb, sw1, sw2); + } else { + sim_debug(DEBUG_IRQ, &cpu_dev, + "post_csw %04x B4READ1 icb+16 %08x icb+20 %08x inch %06x chan_icb %06x\n", + chsa, RMW(chan_icb+16), RMW(chan_icb+20), incha, chan_icb); + WMW(incha, sw1); /* save sa & IOCD address in status WD 1 loc */ + WMW(incha+4, sw2); /* save status and residual cnt in status WD 2 loc */ + /* now store the status dw address into word 5 of the ICB for the channel */ + WMW(chan_icb+20, incha|BIT1); /* post sw addr in ICB+5w & set CC2 in INCH addr */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "post_csw %04x READ1 FIFO #%1x inch %06x chan_icb %06x sw1 %08x sw2 %08x\n", + chsa, FIFO_Num(chsa), incha, chan_icb, sw1, sw2); + if ((incha + 8) > chp->max_inch_addr) /* see if next inch addr OK */ + chp->chan_inch_addr = chp->base_inch_addr; /* reset to first inch addr */ + } + return 1; /* show we posted status */ + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "post_csw %04x chp %p READ FIFO #%1x inch %06x No Status chan_byte %02x\n", + chsa, chp, FIFO_Num(chsa), incha, chp->chan_byte); + return 0; /* no status to post */ +} + +/* store the device status into the status FIFO for the channel */ +void store_csw(CHANP *chp) +{ + uint32 stwd1, stwd2; /* words 1&2 of stored status */ + uint32 chsa = chp->chan_dev; /* get ch/sa information */ + + /* put sub address in byte 0 */ + stwd1 = ((chsa & 0xff) << 24) | chp->chan_caw; /* subaddress and IOCD address to SW 1 */ + + /* save 16 bit channel status and residual byte count in SW 2 */ + stwd2 = ((uint32)chp->chan_status << 16) | ((uint32)chp->ccw_count); + + if ((FIFO_Put(chsa, stwd1) == -1) || (FIFO_Put(chsa, stwd2) == -1)) { + sim_debug(DEBUG_EXP, &cpu_dev, + "store_csw FIFO Overflow ERROR on chsa %04x\n", chsa); + } + sim_debug(DEBUG_XIO, &cpu_dev, + "store_csw FIFO #%1x write chsa %04x sw1 %08x sw2 %08x incha %08x cmd %02x\n", + FIFO_Num(chsa), chsa, stwd1, stwd2, chp->chan_inch_addr, chp->ccw_cmd); + /* added 011321 */ + /* removed 112421 */ +// INTS[chp->chan_int] |= INTS_REQ; /* request an interrupt for channel */ + irq_pend = 1; /* wakeup controller */ +} + +/* store the device status into the first entry of the status FIFO for the channel */ +void push_csw(CHANP *chp) +{ + int32 stwd1, stwd2; /* words 1&2 of stored status */ + uint32 chsa = chp->chan_dev; /* get ch/sa information */ + + /* put sub address in byte 0 */ + stwd1 = ((chsa & 0xff) << 24) | chp->chan_caw; /* subaddress and IOCD address to SW 1 */ + + /* save 16 bit channel status and residual byte count in SW 2 */ + stwd2 = ((uint32)chp->chan_status << 16) | ((uint32)chp->ccw_count); + + /* Push in reverse order to allign status correctly */ + if ((FIFO_Push(chsa, stwd2) == -1) || (FIFO_Push(chsa, stwd1) == -1)) { + sim_debug(DEBUG_EXP, &cpu_dev, + "push_csw FIFO Overflow ERROR on chsa %04x\n", chsa); + } + sim_debug(DEBUG_XIO, &cpu_dev, + "push_csw FIFO #%1x write chsa %04x sw1 %08x sw2 %08x incha %08x cmd %02x\n", + FIFO_Num(chsa), chsa, stwd1, stwd2, chp->chan_inch_addr, chp->ccw_cmd); + /* added 011321 */ + /* removed 112421 */ +// INTS[chp->chan_int] |= INTS_REQ; /* request an interrupt for channel */ + irq_pend = 1; /* wakeup controller */ +} + +/* check an XIO operation */ +/* logical chan channel number 0-7f */ +/* suba unit address within channel 0-ff */ +/* Condition codes to return 0-f as specified above */ +t_stat checkxio(uint16 lchsa, uint32 *status) { + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + CHANP *chp; /* channel program pointer */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ + DEVICE *dptr; /* DEVICE pointer */ + uint32 inta; + uint32 spadent; + uint16 rchan, rchsa; /* the real channel number */ + + /* get the device entry for the logical channel in SPAD */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = (rchan << 8) | (lchsa & 0xff); /* get the read chan & suba */ + + dibp = dib_chan[rchan]; /* get DIB pointer for channel */ + if (dibp == 0) goto nothere; + + chp = dibp->chan_prg; /* find the chanp pointer */ + if (chp == 0) goto nothere; + + uptr = dibp->units; /* find pointer to 1st unit on channel */ + if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */ +nothere: + *status = CC3BIT; /* not found, so CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "checkxio lchsa %04x rchan %04x is not found, CC3 return\n", lchsa, rchan); + return SCPE_OK; /* not found, CC3 */ + } + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + dptr = get_dev(uptr); /* pointer to DEVICE structure */ + + /* is device or unit marked disabled? */ + if ((dptr->flags & DEV_DIS) || ((uptr->flags & UNIT_DIS) && + ((uptr->flags & UNIT_SUBCHAN) == 0))) { + /* is device/unit disabled? */ + /* UTX wants CC1 on "mt offline" call. If not, UTX loops forever */ + if ((dptr != NULL) && + (DEV_TYPE(dptr) == DEV_TAPE)) { /* see if this is a tape */ + *status = CC1BIT; /* CCs = 1, not busy */ + sim_debug(DEBUG_EXP, &cpu_dev, + "checkxio rchsa %04x device/unit not enabled, CC1 returned\n", + rchsa); + } else { + *status = CC3BIT; /* not attached, so error CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "checkxio rchsa %04x device/unit not enabled, CC3 returned\n", + rchsa); + } + return SCPE_OK; /* Not found CC3/CC1 */ + } + + /* try this as MFP says it returns 0 on OK */ + if (dptr->flags & DEV_CHAN) + *status = 0; /* CCs = 0, OK return */ + else + /* return CC1 for non iop/mfp devices */ + *status = 0; /* CCs = 0, OK return */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "checkxio lchsa %04x rchsa %04x done CC status %08x\n", + lchsa, rchsa, *status); + return SCPE_OK; /* No CC's all OK */ +} + +/* SIO CC status returned to caller */ +/* val condition */ +/* 0 command accepted, will echo status - no CC's */ +/* 1 channel busy - CC4 */ +/* 2 channel inop or undefined (operator intervention required) - CC3 */ +/* 3 sub channel busy CC3 + CC4 */ +/* 4 status stored - CC2 */ +/* 5 unsupported transaction CC2 + CC4 */ +/* 6 unassigned CC2 + CC3 */ +/* 7 unassigned CC2 + CC3 + CC4 */ +/* 8 command accepted/queued, no echo status - CC1 */ +/* 9 unassigned */ +/* a unassigned */ +/* b unassigned */ +/* c unassigned */ +/* d unassigned */ +/* e unassigned */ +/* f unassigned */ + +/* start an XIO operation */ +/* when we get here the cpu has verified that there is a valid channel address */ +/* and an interrupt entry in spad for the channel. The IOCL address in the ICB */ +/* has also been verified as present */ +/* chan channel number 0-7f */ +/* suba unit address within channel 0-ff */ +/* Condition codes to return 0-f as specified above */ +t_stat startxio(uint16 lchsa, uint32 *status) { + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + uint32 chan_icb; /* Interrupt level context block address */ + uint32 iocla; /* I/O channel IOCL address int ICB */ + int32 stat; /* return status 0/1 from loadccw */ + CHANP *chp; /* channel program pointer */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ + uint16 chsa; + uint32 tempa, inta, spadent, chan, incha; + uint32 word1, word2, cmd; + DEVICE *dptr; + + /* get the device entry for the logical channel in SPAD */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + inta = ((~spadent)>>16)&0x7f; /* get interrupt level */ + chan = (spadent & 0x7f00) >> 8; /* get real channel */ + chsa = (chan << 8) | (lchsa & 0xff); /* merge sa to real channel */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio entry inta %02x lchan %04x spadent %08x rchsa %04x\n", + inta, lchan, spadent, chsa); + + dibp = dib_unit[chsa & 0x7f00]; /* get the device information pointer */ + uptr = find_unit_ptr(chsa & 0x7f00); /* get unit 0 unit pointer */ + chan_icb = find_int_icb(lchsa); /* Interrupt level context block address */ + incha = RMW(chan_icb+20); /* post inch addr in ICB+5w */ + + /* check if we have a valid unit */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + if (chp == 0) goto missing; + + dibp = dib_unit[chsa]; /* get the DIB pointer */ + if (dibp == 0) goto missing; + + uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */ + + if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */ +missing: + *status = CC3BIT; /* not found, so CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio chsa %04x is not found, CC3 returned\n", chsa); + return SCPE_OK; /* not found, CC3 */ + } + + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio chsa %04x chp %p flags UNIT_ATTABLE %1x UNIT_ATT %1x UNIT_DIS %1x\n", + chsa, chp, (uptr->flags & UNIT_ATTABLE)?1:0, (uptr->flags & UNIT_ATT)?1:0, + (uptr->flags & UNIT_DIS)?1:0); + + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || ((uptr->flags & UNIT_DIS) && + ((uptr->flags & UNIT_SUBCHAN) == 0))) { + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio chsa %04x device/unit disabled, CC3 returned flags %08x\n", chsa, uptr->flags); + *status = CC3BIT; /* not attached, so error CC3 */ + return SCPE_OK; /* not found, CC3 */ + } + +#ifndef FOR_DEBUG_01172021 + if ((INTS[inta]&INTS_ACT) || (SPAD[inta+0x80]&SINT_ACT)) { /* look for level active */ + /* just output a warning */ + sim_debug(DEBUG_XIO, &cpu_dev, + "SIOT Busy INTS ACT FIFO #%1x irq %02x SPAD %08x INTS %08x chan_byte %02x\n", + FIFO_Num(SPAD[inta+0x80] & 0x7f00), inta, SPAD[inta+0x80], INTS[inta], chp->chan_byte); + } +#endif + + incha = chp->chan_inch_addr; /* get inch address */ + /* 05122021 cpu halts in diag if this code is enabled */ + /* disabling this code allows TE to be echoed at debugger prompt */ +#ifndef TEST_FOR_HSDP_PUT_BACK_05122021 + /* channel not busy and ready to go, check for any status ready */ + /* see if any status ready to post */ + if (FIFO_Num(chsa&0x7f00)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "SIOT chsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + chsa, FIFO_Num(chsa), inta, incha, chp, chan_icb, chp->chan_byte); + if (post_csw(chp, 0)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "SIOT chsa %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", + chsa, FIFO_Num(chsa), inta, incha, RMW(chan_icb+20), chp->chan_byte); + /* change status from BUFF_POST to BUFF_DONE */ + /* if not BUFF_POST we have a PPCI or channel busy interrupt */ + /* so leave the channel status alone */ + if (chp->chan_byte == BUFF_POST) { + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + } + sim_debug(DEBUG_XIO, &cpu_dev, + "SIOT END status stored incha %06x chan_icba+20 %08x chsa %04x sw1 %08x sw2 %08x\n", + incha, RMW(chan_icb+20), chsa, RMW(incha), RMW(incha+4)); + INTS[inta] &= ~INTS_REQ; /* clear level request for no status */ +// INTS[inta] |= INTS_REQ; /* set level request if no status */ + *status = CC2BIT; /* status stored from SIO, so CC2 */ + return SCPE_OK; /* No CC's all OK */ + } else { + sim_debug(DEBUG_IRQ, &cpu_dev, + "SIOT chsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + chsa, FIFO_Num(chsa), inta, incha, chan_icb, chp->chan_byte); + /* now store the status dw address into word 5 of the ICB for the channel */ + WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ + *status = 0; /* no status stored from SIO, so no CC */ + return SCPE_OK; /* No CC's all OK */ + } + } +//TRY WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "SIOT chsa %04x Nothing to post FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + chsa, FIFO_Num(chsa), inta, incha, chan_icb, chp->chan_byte); +#endif + + /* check for a Command or data chain operation in progresss */ + if ((chp->chan_byte & BUFF_BUSY) && (chp->chan_byte != BUFF_POST)) { + uint16 tstat = chp->chan_status; /* save status */ + uint16 tcnt = chp->ccw_count; /* save count */ + DEVICE *dptr = get_dev(uptr); + + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio busy return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n", + chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + /* ethernet controller wants an interrupt for busy status */ + if ((dptr != NULL) && + (DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */ + *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ + /* handle an Ethernet controller busy by sending interrupt/status */ + chp->chan_status = STATUS_BUSY|STATUS_CEND|STATUS_DEND; /* set busy status */ + chp->ccw_count = 0; /* zero count */ + push_csw(chp); /* store the status */ + chp->chan_status = tstat; /* restore status */ + chp->ccw_count = tcnt; /* restore count */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio done BUSY/INT chp %p chsa %04x ccw_flags %04x stat %04x cnt %04x\n", + chp, chsa, chp->ccw_flags, tstat, tcnt); + return SCPE_OK; /* just busy CC3&CC4 */ + } + /* see if controller has a IOCLQ defined to handle multiple SIO requests */ + /* keep processing SIO and handle busy later */ + if (dibp->ioclq_ptr == NULL) { /* see if device has IOCL queue */ + /* everyone else just gets a busy return */ + *status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio done2 BUSY chp %p chsa %04x ccw_flags %04x stat %04x cnt %04x\n", + chp, chsa, chp->ccw_flags, tstat, tcnt); + return SCPE_OK; /* just busy CC3&CC4 */ + } + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio busy ignored for IOCLQ chsa %04x chp %p cmd %02x flags %04x byte %02x\n", + chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + } + +#if 1 + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio int spad %08x icb %06x inta %02x chan %04x\n", + SPAD[inta+0x80], chan_icb, inta, chan); +#endif + + /* We have to validate all the addresses and parameters for the SIO */ + /* before calling load_ccw which does it again for each IOCL step */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + word1 = RMW(iocla & MASK24); /* get 1st IOCL word */ + word2 = RMW((iocla + 4) & MASK24); /* get 2nd IOCL word */ + cmd = (word1 >> 24) & 0xff; /* get channel cmd from IOCL */ + chp = find_chanp_ptr(chsa&0x7f00); /* find the parent chanp pointer */ + incha = chp->chan_inch_addr; /* get inch address */ + + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio do normal chsa %04x iocla %06x incha %06x IOCD1 %08x IOCD2 %08x\n", + chsa, iocla, incha, RMW(iocla), RMW(iocla+4)); + + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ +#ifdef TEST_FOR_IOCL_CHANGE + chp->new_iocla = iocla; /* save iocla */ + chp->new_iocd1 = word1; /* save iocd word 1 */ + chp->new_iocd2 = word2; /* save iocd word 2 */ +#endif + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio test chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n", + chsa, iocla, RMW(iocla), RMW(iocla+4)); + + sim_debug(DEBUG_CMD, &cpu_dev, "SIO chsa %04x cmd %02x cnt %04x ccw_flags %04x\n", + chsa, cmd, word2&MASK16, word2>>16); + + /* determine if channel DIB has a pre startio command processor */ + if (dibp->pre_io != NULL) { /* NULL if no startio function */ + DEVICE *dptr = get_dev(uptr); /* get device ptr */ + int unit = uptr-dptr->units; /* get unit number */ + + /* call the device controller to get prestart_io status */ + tempa = dibp->pre_io(uptr, chan); /* get status from device */ + /* SCPE_OK if unit not busy and IOCLQ is not full */ + /* SNS_BSY if unit IOCLQ is full */ + /* SNS_SMS if unit IOCLQ is not full, but device is busy */ + /* SNS_CTLEND if waiting for INCH command */ + if (tempa == SNS_CTLEND) { /* see if sub channel status is ready */ + /* manual says to just return OK nad do nother if inch is required */ + sim_debug(DEBUG_XIO, &cpu_dev, + "SIO pre_io call return NO INCH %04x chsa %04x cstat %02x cmd %02x cnt %02x\n", + incha, chsa, tempa, cmd, word2); + if ((cmd != 0) || ((MASK16 & word2) == 0)) { + *status = 0; /* request accepted, no status, so CC1 */ + return SCPE_OK; /* just do nothing until inch */ + } + } + if (tempa == SNS_BSY) { /* see if sub channel status is ready */ + /* The device must be busy or something, but it is not ready. Return busy */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio pre_io call return busy1 chan %04x cstat %08x\n", chan, tempa); + *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ + return SCPE_OK; /* just busy or something, CC3|CC4 */ + } + if (tempa == SNS_SMS) { /* see if sub channel status is ready */ + if (dibp->ioclq_ptr == NULL) { /* see if device has IOCL queue */ + /* The device must be busy or something, but it is not ready. Return busy */ + /* This should not happen for SNS_SMS status */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio pre_io call return busy2 chan %04x cstat %08x\n", chan, tempa); + *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ + return SCPE_OK; /* just busy or something, CC3|CC4 */ + } + /* device has IOCLQ, queue up the iocla */ + if (IOCLQ_Put(&dibp->ioclq_ptr[unit], iocla) == -1) { + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio IOCLQ_Put error return chsa %04x unit %02x\n", chsa, unit); + *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ + return SCPE_OK; /* just busy or something, CC3|CC4 */ + } + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio IOCLQ_Put call sucessful count %02x chan %04x unit %02x\n", + IOCLQ_Num(&dibp->ioclq_ptr[unit]), chan, unit); + *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ + return SCPE_OK; /* CC1 all OK */ + } + /* device is not busy */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio pre_io call return not busy chan %04x cstat %08x\n", + chan, tempa); + } /* remove else 05132021 */ + + /* check for a Command or data chain operation in progresss */ + if ((chp->chan_byte & BUFF_BUSY) && (chp->chan_byte != BUFF_POST)) { + uint16 tstat = chp->chan_status; /* save status */ + uint16 tcnt = chp->ccw_count; /* save count */ + + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio busy return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n", + chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + /* everyone else just gets a busy return */ + *status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio done BUSY chp %p chsa %04x ccw_flags %04x stat %04x cnt %04x\n", + chp, chsa, chp->ccw_flags, tstat, tcnt); + return SCPE_OK; /* just busy CC3&CC4 */ + } + + /* channel not busy and ready to go, so start a new command */ + chp->chan_int = inta; /* save interrupt level in channel */ + chp->chan_status = 0; /* no channel status yet */ + chp->chan_caw = iocla; /* get iocla address in memory */ + /* added 09/25/20 to fix hangs in iocl processing */ + chp->ccw_flags = 0; /* clear flags */ + + /* set status words in memory to first IOCD information */ + sim_debug(DEBUG_XIO, &cpu_dev, + "$$ SIO start IOCL processing chsa %04x iocla %08x incha %08x\n", + chsa, iocla, incha); + + /* We are queueing the SIO */ + /* Queue us to continue IOCL from cpu level & make busy */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + chp->chan_info |= INFO_SIOCD; /* show first IOCD in channel prog */ + chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ + + /* start processing the IOCL */ + stat = load_ccw(chp, 0); /* start the I/O operation */ + if (stat) { + /* we have an error or user requested interrupt, return status */ + sim_debug(DEBUG_EXP, &cpu_dev, "startxio store csw CC2 chan %04x status %08x\n", + chan, chp->chan_status); +/*NOTE*//* if we have an error, we would loop forever if the CC bit was set */ + /* the only way to stop was to do a kill */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + /* DIAG's want CC1 with memory access error */ + if (chp->chan_status & STATUS_PCHK) { + chp->chan_status &= ~STATUS_LENGTH; /* clear incorrect length */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio Error1 FIFO #%1x store_csw CC1 chan %04x status %08x\n", + FIFO_Num(chsa), chan, chp->chan_status); + } else { + /* other error, stop the show */ + chp->chan_status &= ~STATUS_PCI; /* remove PCI status bit */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio Error2 FIFO #%1x store_csw CC1 chan %04x status %08x\n", + FIFO_Num(chsa), chan, chp->chan_status); + } + /* we get here when the start cmd has been processed without error */ + /* go wait for the cmd to finish */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio start wait chsa %04x status %08x iocla %06x byte %02x\n", + chsa, chp->chan_status, chp->chan_caw, chp->chan_byte); + } + sim_debug(DEBUG_XIO, &cpu_dev, + "SIO started chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x incha %06x icb+20 %08x\n", + chsa, iocla, RMW(iocla), RMW(iocla+4), incha, RMW(chan_icb+20)); + + *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ + sim_debug(DEBUG_XIO, &cpu_dev, "SIO return chsa %04x status %08x iocla %08x CC's %08x byte %02x\n", + chsa, chp->chan_status, iocla, *status, chp->chan_byte); + return SCPE_OK; /* No CC's all OK */ +} + +/* TIO - I/O status */ +t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + uint32 chan_icb; /* Interrupt level context block address */ + CHANP *chp; /* Channel prog pointers */ + DEVICE *dptr; /* Device ptr */ + uint32 inta, incha, itva; + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ + uint32 spadent; + uint16 rchan, rchsa; /* the real channel number, chsa */ + + lchsa &= 0x7f00; /* use just chan and sa of 0 */ + /* get the real channel entry for the logical channel in SPAD */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchsa = (spadent & 0x7f00); /* get real channel suba of zero */ + rchan = rchsa >> 8; /* get real channel */ + + /* get the device entry for the channel in SPAD */ + dibp = dib_chan[rchan]; /* get the DIB pointer */ + chp = find_chanp_ptr(rchan << 8); /* find the device chanp pointer */ + + if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ + *status = CC3BIT; /* not found, so CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "TIO lchsa %04x rchsa %04x device not present, CC3 returned\n", lchsa, rchsa); + return SCPE_OK; /* Not found, CC3 */ + } + + uptr = chp->unitptr; /* get the unit 0 ptr */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || ((uptr->flags & UNIT_DIS) && + ((uptr->flags & UNIT_SUBCHAN) == 0))) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "TIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ + } + + /* the XIO opcode processing software has already checked for F class */ + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + itva = SPAD[0xf1] + (inta<<2); /* int vector address */ + chan_icb = RMW(itva); /* Interrupt context block addr */ + sim_debug(DEBUG_XIO, &cpu_dev, + "TIO int spad %08x icb %06x inta %04x rchsa %04x\n", + SPAD[inta+0x80], chan_icb, inta, rchsa); + + incha = chp->chan_inch_addr; /* get inch address */ + + /* see if any status ready to post */ + if (FIFO_Num(rchsa)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "TIO rchsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, chp, chan_icb, chp->chan_byte); + if (chp->chan_byte == BUFF_DONE) { + chp->chan_byte = BUFF_POST; /* if done, show post for post_csw() */ + } + if (post_csw(chp, 0)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "TIO rchsa %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, RMW(chan_icb+20), chp->chan_byte); + /* change status from BUFF_POST to BUFF_DONE */ + /* if not BUFF_POST we have a PPCI or channel busy interrupt */ + /* so leave the channel status alone */ + if (chp->chan_byte == BUFF_POST) { + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + } + sim_debug(DEBUG_XIO, &cpu_dev, + "TIO END incha %06x chan_icba+20 %08x rchsa %04x sw1 %08x sw2 %08x\n", + incha, RMW(chan_icb+20), rchsa, RMW(incha), RMW(incha+4)); + INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */ + *status = CC2BIT; /* status stored from SIO, so CC2 */ + return SCPE_OK; /* No CC's all OK */ + } else { + sim_debug(DEBUG_IRQ, &cpu_dev, + "TIO rchsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, chp->chan_inch_addr, chan_icb, chp->chan_byte); + /* now store the status dw address into word 5 of the ICB for the channel */ + WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ + *status = 0; /* no status stored from TIO, so no CC */ + return SCPE_OK; /* No CC's all OK */ + } + } + + /* nothing going on, so say all OK */ + /* now store the status dw address into word 5 of the ICB for the channel */ +#ifdef FIXES_DMDIAG_TEST_11C_TIO_BUT_BREAKS_UTX + WMW(chan_icb+20, 0x80000000); /* post CC1 & sw addr 0 in ICB+5w & reset CCs */ + *status = CC4BIT; /* FIX FOR DIAG */ /* request accepted, not busy, so CC4 */ +#else + /* MPX 1X requires CC1 to be returned instead of CC2 or CC4 */ + /* MPX 1X will hang on boot if set to CC2 */ + WMW(chan_icb+20, 0x80000000); /* post sw addr 0 in ICB+5w & reset CCs */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ +#endif +// INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */ + sim_debug(DEBUG_XIO, &cpu_dev, + "TIO END rchsa %04x rchan %04x ccw_flags %04x chan_stat %04x CCs %08x\n", + rchsa, rchan, chp->ccw_flags, chp->chan_status, *status); + return SCPE_OK; /* No CC's all OK */ +} + +/* Stop XIO */ +t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */ + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + uint32 chan_icb; /* Interrupt level context block address */ + uint32 iocla, inta, itva; /* I/O channel IOCL address int ICB */ + CHANP *chp; /* Channel prog pointers */ + DEVICE *dptr; /* Device ptr */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ + uint32 spadent; + uint16 rchan, rchsa; /* the real channel number, chsa */ + + /* get the device entry for the logical channel in SPAD */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = (rchan << 8) | (lchsa & 0xff); /* get the read chan & suba */ + + /* get the device entry for the logical channel in SPAD */ + dibp = dib_unit[rchsa]; /* get the DIB pointer */ + chp = find_chanp_ptr(rchsa); /* find the device chanp pointer */ + + if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ + *status = CC3BIT; /* not found, so CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "STPIO test 1 rchsa %04x device not present, CC3 returned\n", rchsa); + return SCPE_OK; /* not found CC3 */ + } + + uptr = chp->unitptr; /* get the unit ptr */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || ((uptr->flags & UNIT_DIS) && + ((uptr->flags & UNIT_SUBCHAN) == 0))) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "STPIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ + } + + /* the XIO opcode processing software has already checked for F class */ + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + itva = SPAD[0xf1] + (inta<<2); /* int vector address */ + chan_icb = RMW(itva); /* Interrupt context block addr */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + sim_debug(DEBUG_CMD, &cpu_dev, + "STPIO busy test rchsa %04x cmd %02x ccw_flags %04x IOCD1 %08x IOCD2 %08x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, M[iocla>>2], M[(iocla+4)>>2]); + /* reset the CC bit to force completion after current IOCD */ + chp->ccw_flags &= ~FLAG_CC; /* reset chaining bits */ + + /* see if we have a stopio device entry */ + if (dibp->stop_io != NULL) { /* NULL if no stop_io function */ + /* call the device controller to get stop_io status */ + int32 tempa = dibp->stop_io(uptr); /* get status from device */ + + /* test for SCPE_IOERR */ + /* CC's are returned in byte 0, status in bytes 2-3 */ + /* SCPR_OK is 0 */ + /* SCPR_IOERR is 2 */ + if ((tempa & RMASK) != SCPE_OK) { /* sub channel has status ready */ + /* The device I/O has been terminated and status stored. */ + sim_debug(DEBUG_XIO, &cpu_dev, + "STPIO stop_io call return ERROR FIFO #%1x rchan %04x retstat %08x cstat %08x\n", + FIFO_Num(rchsa), rchan, tempa, chp->chan_status); + + /* chan_end is called in stop device service routine */ + /* the device is no longer busy, post status */ + /* remove PPCI status. Unit check should not be set */ + if ((tempa & LMASK) == CC2BIT) { + chp->ccw_count = 0; /* zero the count */ + /* post status for UTX */ + if (post_csw(chp, ((STATUS_PCI) << 16))) { + INTS[inta] &= ~INTS_REQ; /* clear any level request */ + *status = CC2BIT; /* status stored */ + sim_debug(DEBUG_CMD, &cpu_dev, + "STPIO END2 rchsa %04x rchan %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, rchan, chp->ccw_cmd, chp->ccw_flags, *status); + /* change status from BUFF_POST to BUFF_DONE */ + if (chp->chan_byte == BUFF_POST) { + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + } + return SCPE_OK; /* CC2 & all OK */ + } + } else { + chp->ccw_count = 0; /* zero the count */ + /* The diags want the interrupt for the disk */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + sim_debug(DEBUG_CMD, &cpu_dev, + "STPIO END2 ECHO rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); + return SCPE_OK; /* CC1 & all OK */ + } + } + /* the channel is not busy, so return OK */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + sim_debug(DEBUG_CMD, &cpu_dev, + "STPIO END3 rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); + return SCPE_OK; /* No CC's all OK */ + } + if ((chp->chan_byte & BUFF_BUSY) == 0) { + /* the channel is not busy, so return OK */ + sim_debug(DEBUG_CMD, &cpu_dev, + "STPIO not busy return rchsa %04x cmd %02x ccw_flags %04x status %04x byte %02x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status, chp->chan_byte); + sim_debug(DEBUG_IRQ, &cpu_dev, + "STPIO rchsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, chp->chan_inch_addr, chan_icb, chp->chan_byte); + /* now store the status dw address into word 5 of the ICB for the channel */ + WMW(chan_icb+20, 0x80000000); /* post sw addr 0 in ICB+5w & set CC 1*/ + *status = CC1BIT; /* show not busy, post no status with CC1 */ + return SCPE_OK; /* No CC's all OK */ + } + + /* device does not have stop_io entry, so stop the I/O */ + /* check for a Command or data chain operation in progresss */ + /* set the return to CC3BIT & CC4BIT causes infinite loop in MPX1X */ + /* restore code to old CC1BIT return 12/21/2020 */ + // try using CC4 on MPX3X when still busy + if (chp->chan_byte == BUFF_POST) { + uint32 incha = chp->chan_inch_addr; /* get inch address */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + /* see if any status ready to post */ + if (FIFO_Num(rchsa)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "STPIO chsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, chp, chan_icb, chp->chan_byte); + if (post_csw(chp, 0)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "STPIO chsa %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, RMW(chan_icb+20), chp->chan_byte); + /* change status from BUFF_POST to BUFF_DONE */ + /* if not BUFF_POST we have a PPCI or channel busy interrupt */ + /* so leave the channel status alone */ + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + sim_debug(DEBUG_XIO, &cpu_dev, + "STPIO END incha %06x chan_icba+20 %08x chsa %04x sw1 %08x sw2 %08x\n", + incha, RMW(chan_icb+20), rchsa, RMW(incha), RMW(incha+4)); + INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */ + *status = CC2BIT; /* status stored from SIO, so CC2 */ + return SCPE_OK; /* No CC's all OK */ + } else { + sim_debug(DEBUG_IRQ, &cpu_dev, + "STPIOX chsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, chan_icb, chp->chan_byte); + /* now store the status dw address into word 5 of the ICB for the channel */ + WMW(chan_icb+20, 0x80000000); /* post CC1 & sw addr 0 in ICB+5w & reset CCs */ +// WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ + *status = CC1BIT; /* show not busy, post no status with CC1 */ + return SCPE_OK; /* No CC's all OK */ + } + } + } else { + /* setting this to CC4 allows MPX mstrall to boot */ + /* having it set to CC1 allows diags to work, but not MPX 3X boot! */ + // This check allows DBUG2 and DIAGS to both work + if (chp->chan_byte == BUFF_NEXT) +//BAD?? *status = CC1BIT; /* request accepted, no status, so CC1 */ + *status = CC4BIT; /* BAD FOR DIAG *//* request accepted, busy, so CC4 */ + else + *status = CC4BIT; /* BAD FOR DIAG *//* request accepted, busy, so CC4 */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "STPIO2 chsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, chp->chan_inch_addr, chan_icb, chp->chan_byte); + } + /* reset the CC bit to force completion after current IOCD */ + chp->ccw_flags &= ~FLAG_CC; /* reset chaining bits */ + sim_debug(DEBUG_CMD, &cpu_dev, + "STPIO busy return CC1/4 rchsa %04x status %08x cmd %02x flags %04x byte %02x\n", + rchsa, *status, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + return SCPE_OK; /* go wait CC1 */ +} + +/* Reset Channel XIO */ +t_stat rschnlxio(uint16 lchsa, uint32 *status) { /* reset channel XIO */ + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + CHANP *chp; /* Channel prog pointers */ + DEVICE *dptr; /* Device ptr */ + int i; + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ + uint32 inta; + uint32 spadent; + uint16 rchan, rchsa; /* the real channel number */ + + /* get the device entry for the logical channel in SPAD */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = rchan << 8; /* get the real chan & zero suba */ + + /* get the device entry for the logical channel in SPAD */ + dibp = dib_unit[rchsa]; /* get the channel device information pointer */ + chp = find_chanp_ptr(rchsa); /* find the channel chanp pointer */ + + if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ + *status = CC3BIT; /* not found, so CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "rschnlxio test 1 dibp %p chp %p lchsa %04x rchsa %04x device not present, CC3 returned\n", + dibp, chp, lchsa, rchsa); + return SCPE_OK; /* not found CC3 */ + } + + uptr = chp->unitptr; /* get the unit ptr */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || ((uptr->flags & UNIT_DIS) && + ((uptr->flags & UNIT_SUBCHAN) == 0))) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RSCHNL rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ + } + + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + + /* reset this channel */ + dibp->chan_fifo_in = 0; /* reset the FIFO pointers */ + dibp->chan_fifo_out = 0; /* reset the FIFO pointers */ + chp->chan_inch_addr = 0; /* remove inch status buffer address */ + chp->base_inch_addr = 0; /* clear the base inch addr */ + chp->max_inch_addr = 0; /* clear the last inch addr */ + INTS[inta] &= ~INTS_ACT; /* clear level active */ + SPAD[inta+0x80] &= ~SINT_ACT; /* clear in spad too */ + + /* now go through all the sa for the channel and stop any IOCLs */ + for (i=0; iunitptr; /* get the unit ptr */ + + /* see if we have a rschnl device entry */ + if (dibp->rschnl_io != NULL) { /* NULL if no rschnl_io function */ + /* call the device controller to process rschnl */ + j = dibp->rschnl_io(uptr); /* get status from device */ + sim_debug(DEBUG_EXP, &cpu_dev, + "rschnl_io returned %02x chsa %04x\n", j, rchsa); + } + chp->chan_status = 0; /* clear the channel status */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* clear buffer address */ + chp->chan_caw = 0x0; /* clear IOCD address */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* clear flags */ + chp->ccw_cmd = 0; /* read command */ + chp->chan_inch_addr = 0; /* clear inch addr */ + chp->base_inch_addr = 0; /* clear the base inch addr */ + chp->max_inch_addr = 0; /* clear the last inch addr */ + } + sim_debug(DEBUG_XIO, &cpu_dev, "rschnlxio return CC1 lchan %02x lchan %02x inta %04x\n", + lchan, rchan, inta); + *status = CC1BIT; /* request accepted, no status, so CC1 TRY THIS */ + return SCPE_OK; /* All OK */ +} + +/* HIO - Halt I/O */ +t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ + DIB *dibp; + UNIT *uptr; + uint32 chan_icb; /* Interrupt level context block address */ + uint32 iocla; /* I/O channel IOCL address int ICB */ + uint32 inta, spadent, tempa, itva; + uint16 lchan = get_chan(lchsa); + uint16 rchan, rchsa; + CHANP *chp; /* Channel prog pointers */ + DEVICE *dptr; /* DEVICE pointer */ + + /* get the device entry for the logical channel in SPAD */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = (rchan << 8) | (lchsa & 0xff); /* merge sa to real channel */ + dibp = dib_unit[rchsa]; /* get the device DIB pointer */ + chp = find_chanp_ptr(rchsa); /* find the chanp pointer */ + + if (dibp == 0 || chp == 0) { /* if no dib or chan ptr, CC3 on return */ + *status = CC3BIT; /* not found, so CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO lchsa %04x rchsa %04x device not present, CC3 returned\n", lchsa, rchsa); + return SCPE_OK; /* not found, CC3 */ + } + uptr = chp->unitptr; /* get the unit ptr */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || ((uptr->flags & UNIT_DIS) && + ((uptr->flags & UNIT_SUBCHAN) == 0))) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ + } + + /* see if interrupt is setup in SPAD and determine IVL for channel */ + sim_debug(DEBUG_EXP, &cpu_dev, "HIO dev spad %08x lchsa %04x rchsa %04x\n", spadent, lchsa, rchsa); + + /* the haltio opcode processing software has already checked for F class */ + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + sim_debug(DEBUG_EXP, &cpu_dev, "HIO int spad %08x inta %02x rchan %02x\n", spadent, inta, rchan); + + /* get the address of the interrupt IVL in main memory */ + itva = SPAD[0xf1] + (inta<<2); /* int vector address */ + chan_icb = RMW(itva); /* Interrupt context block addr */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO busy test byte %02x rchsa %04x cmd %02x ccw_flags %04x IOCD1 %08x IOCD2 %08x\n", + chp->chan_byte, rchsa, chp->ccw_cmd, chp->ccw_flags, RMW(iocla), RMW(iocla+4)); + + /* the channel is busy, so process */ + /* see if we have a haltio device entry */ + if (dibp->halt_io != NULL) { /* NULL if no haltio function */ + /* call the device controller to get halt_io status */ + tempa = dibp->halt_io(uptr); /* get status from device */ + + /* CC's are returned in bits 1-4. Bits 16-31 has SCPE code */ + /* SCPE_IOERR is 2 */ + /* SCPE_OK is 0 */ + if ((tempa & RMASK) != SCPE_OK) { /* sub channel has status ready */ + uint32 incha = chp->chan_inch_addr; /* get inch address */ + /* The device I/O has been terminated and status stored. */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO halt_io call return ERROR FIFO #%1x rchsa %04x retstat %08x cstat %08x\n", + FIFO_Num(rchsa), rchsa, tempa, chp->chan_status); + + /* chan_end is called in hio device service routine */ + /* the device is no longer busy, post status */ + /* The diags want the interrupt for the disk */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO END2X ECHO rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); +// irq_pend = 1; /* flag to test for int condition */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "HIO rchsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, chp, chan_icb, chp->chan_byte); + + /* see if user wants to have status posted and setting CC2 in return value */ + if ((tempa & LMASK) == CC2BIT) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "HIO rchsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, chp, chan_icb, chp->chan_byte); + /* post any status */ + if (post_csw(chp, 0)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "HIO rchsa %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, RMW(chan_icb+20), chp->chan_byte); + /* change status from BUFF_POST to BUFF_DONE */ + /* if not BUFF_POST we have a PPCI or channel busy interrupt */ + /* so leave the channel status alone */ + if (chp->chan_byte == BUFF_POST) { + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + } + sim_debug(DEBUG_XIO, &cpu_dev, + "HIO END incha %06x chan_icba+20 %08x rchsa %04x sw1 %08x sw2 %08x\n", + incha, RMW(chan_icb+20), rchsa, RMW(incha), RMW(incha+4)); + /*ADDED 111921 to disable int request after data posted */ + INTS[inta] &= ~INTS_REQ; /* clear any level request */ + *status = CC2BIT; /* status stored from SIO, so CC2 */ + return SCPE_OK; /* No CC's all OK */ + } + } + /* see if user wants to have status posted by setting CC4 in return value */ + if ((tempa & LMASK) == CC4BIT) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "HIO rchsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, chp, chan_icb, chp->chan_byte); + } + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO END2Y rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); + return SCPE_OK; /* CC1 & all OK */ + } + /* the device is not busy, so cmd is completed */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO BUFF_DONE1 chp %p chan_byte %04x\n", chp, chp->chan_byte); + /* the channel is not busy, so return OK */ + *status = CC1BIT; /* request accepted, post good status, so CC1 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO END3 rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); + +#ifndef GIVE_INT_ON_NOT_BUSY_121420_03082021 + chp->chan_byte = BUFF_DONE; /* we are done */ + sim_debug(DEBUG_EXP, &cpu_dev, + "haltxio BUFF_DONE2 chp %p chan_byte %04x\n", chp, chp->chan_byte); + if ((dptr != NULL) && + (DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */ + /* Ethernet does not want SNS_UNITEXP */ + chp->chan_status = (STATUS_DEND|STATUS_CEND); + } else { + chp->chan_status = (STATUS_DEND|STATUS_CEND|STATUS_EXPT); + } + push_csw(chp); /* store the status 1st in FIFO */ + /* change chan_byte to BUFF_POST */ + chp->chan_byte = BUFF_POST; /* show done with data */ + chp->chan_status = 0; /* no status anymore */ + chp->ccw_cmd = 0; /* no command anymore */ + irq_pend = 1; /* flag to test for int condition */ +#endif + return SCPE_OK; /* No CC's all OK */ + } + + /* device does not have a HIO entry, so terminate the I/O */ + if ((chp->chan_byte & BUFF_BUSY) == 0) { + /* the channel is not busy, so return OK */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO END1 not busy return rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); + chp->chan_byte = BUFF_DONE; /* we are done */ + chp->chan_status = (STATUS_DEND|STATUS_CEND|STATUS_EXPT); + store_csw(chp); /* store the status */ + /* change chan_byte to BUFF_POST */ + chp->chan_byte = BUFF_POST; /* show done with data */ + chp->chan_status = 0; /* no status anymore */ + chp->ccw_cmd = 0; /* no command anymore */ + irq_pend = 1; /* flag to test for int condition */ + return SCPE_OK; /* CC1 & all OK */ + } + + /* device does not have a HIO entry, so terminate the I/O */ + /* a haltxio entry should be provided for a device so busy can be cleared */ + /* check for a Command or data chain operation in progresss */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO device busy lchsa %04x rchsa %04x\n", lchsa, rchsa); + + /* reset the DC or CC bits to force completion */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + chp->chan_byte = BUFF_BUSY; /* wait for post_csw to be done */ + sim_cancel(uptr); /* cancel timer service */ + chp->chan_status &= ~STATUS_BUSY; /* remove BUSY status bit */ + chan_end(rchsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* show I/O complete */ + + /* post the channel status */ + chp->ccw_count = 0; /* zero the count */ + /* remove SLI, PPCI and Unit check status bits */ + if (post_csw(chp, ((STATUS_PCI) << 16))) { + INTS[inta] &= ~INTS_REQ; /* clear any level request */ + *status = CC2BIT; /* status stored from SIO, so CC2 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO END4 rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); + /* change status from BUFF_POST to BUFF_DONE */ + if (chp->chan_byte == BUFF_POST) { + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + } + return SCPE_OK; /* CC2 & all OK */ + } + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO END5 rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); + return SCPE_OK; /* No CC's all OK */ +} + +/* grab controller n/u */ +/* TODO return unimplemented function error, not busy */ +t_stat grabxio(uint16 lchsa, uint32 *status) { /* grab controller XIO n/u */ + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + CHANP *chp; + DEVICE *dptr; /* Device ptr */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ + uint32 spadent; + uint16 rchan, rchsa; /* the real channel number, chsa */ + + /* get the device entry for the logical channel in SPAD */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = (rchan << 8) | (lchsa & 0xff); /* merge sa to real channel */ + + /* get the device entry for the logical channel in SPAD */ + dibp = dib_unit[rchsa]; /* get the DIB pointer */ + chp = find_chanp_ptr(rchsa); /* find the device chanp pointer */ + + if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ + *status = CC3BIT; /* not found, so CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "GRIO test 1 rchsa %04x device not present, CC3 returned\n", rchsa); + return SCPE_OK; /* not found CC3 */ + } + + sim_debug(DEBUG_CMD, &cpu_dev, + "GRIO entry rchsa %04x status %08x cmd %02x flags %02x byte %02x\n", + rchsa, *status, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + + uptr = chp->unitptr; /* get the unit ptr */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || ((uptr->flags & UNIT_DIS) && + ((uptr->flags & UNIT_SUBCHAN) == 0))) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "GRIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ + } + + /* check for a Command or data chain operation in progresss */ + if (chp->ccw_cmd != 0 || (chp->ccw_flags & (FLAG_DC|FLAG_CC)) != 0) { + *status = CC4BIT; /* busy, so CC4 */ + sim_debug(DEBUG_CMD, &cpu_dev, + "GRIO busy return CC4 lchsa %04x rchsa %04x status %08x\n", + lchsa, rchsa, *status); + return SCPE_OK; /* CC4 all OK */ + } + +// NOW ON 05142021 */ + /* device does not have stop_io entry, so stop the I/O */ + /* check for a Command or data chain operation in progresss */ + /* set the return to CC3BIT & CC4BIT causes infinite loop in MPX1X */ + /* restore code to old CC1BIT return 12/21/2020 */ + // try using CC4 on MPX3X when still busy + if (chp->chan_byte == BUFF_POST) { + uint32 chan_icb; /* Interrupt level context block address */ + uint32 inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + /* get the address of the interrupt IVL in main memory */ + uint32 itva = SPAD[0xf1] + (inta<<2); /* int vector address */ + chan_icb = RMW(itva); /* Interrupt context block addr */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + /* see if any status ready to post */ + if (FIFO_Num(rchsa)) { + uint32 incha = chp->chan_inch_addr; /* get inch address */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "GRIO chsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, chp, chan_icb, chp->chan_byte); + if (post_csw(chp, 0)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "GRIO chsa %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, RMW(chan_icb+20), chp->chan_byte); + /* change status from BUFF_POST to BUFF_DONE */ + /* if not BUFF_POST we have a PPCI or channel busy interrupt */ + /* so leave the channel status alone */ + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + sim_debug(DEBUG_XIO, &cpu_dev, + "GRIO END incha %06x chan_icba+20 %08x chsa %04x sw1 %08x sw2 %08x\n", + incha, RMW(chan_icb+20), rchsa, RMW(incha), RMW(incha+4)); + INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */ + *status = CC2BIT; /* status stored from SIO, so CC2 */ + return SCPE_OK; /* No CC's all OK */ + } else { + sim_debug(DEBUG_IRQ, &cpu_dev, + "GRIO chsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + rchsa, FIFO_Num(rchsa), inta, incha, chan_icb, chp->chan_byte); + /* now store the status dw address into word 5 of the ICB for the channel */ + WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ + *status = 0; /* no status stored from STPIO, so no CC */ + return SCPE_OK; /* No CC's all OK */ + } + } + } + + /* If this is console, debugger wants CC3 & CC4 = 0 */ + if (rchan == 0x7e) { + /* returning No CC's causes MPX1X to loop forever */ + /* so restore returning CC1 */ + *status = 0; /* return no CC's */ + } else { + /* diags want unsupported transaction for disk */ + *status = CC2BIT|CC4BIT; /* unsupported transaction */ + } + sim_debug(DEBUG_CMD, &cpu_dev, + "GRIO lchsa %04x rchsa %04x status %08x\n", lchsa, rchsa, *status); + return SCPE_OK; /* dono */ +} + +/* reset controller XIO */ +t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */ + DIB *dibp; + UNIT *uptr; + uint32 spadent; + uint16 chsa; + CHANP *chp; + int lev, i; + uint32 chan = get_chan(lchsa); + DEVICE *dptr; /* get device ptr */ + + /* get the device entry for the logical channel in SPAD */ + spadent = SPAD[chan]; /* get spad device entry for logical channel */ + chan = spadent & 0x7f00; /* get real channel */ + chsa = chan; /* use just channel */ + dibp = dib_unit[chsa]; /* get the DIB pointer */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + uptr = chp->unitptr; /* get the unit ptr */ + + sim_debug(DEBUG_EXP, &cpu_dev, "rsctlxio 1 chan %04x SPAD %08x\n", chsa, spadent); + if (dibp == 0 || uptr == 0) { /* if no dib or unit ptr, CC3 on return */ + *status = CC3BIT; /* not found, so CC3 */ + return SCPE_OK; /* not found, CC3 */ + } + sim_debug(DEBUG_EXP, &cpu_dev, "rsctlxio 2 chan %04x spad %08x\r\n", chsa, spadent); + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); /* get device ptr */ + + /* is device/unit disabled? */ + if ((dptr->flags & DEV_DIS) || ((uptr->flags & UNIT_DIS) && + ((uptr->flags & UNIT_SUBCHAN) == 0))) { + *status = CC3BIT; /* not enabled, so error CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RSCTL rchsa %04x device/unit not enabled, CC3 returned\n", chsa); + return SCPE_OK; /* Not found, CC3 */ + } + lev = find_int_lev(chan); /* get our int level */ + INTS[lev] &= ~INTS_ACT; /* clear level active */ + SPAD[lev+0x80] &= ~SINT_ACT; /* clear spad too */ + INTS[lev] &= ~INTS_REQ; /* clear level request */ + + /* now go through all the sa for the channel and stop any IOCLs */ + for (i=0; ichan_fifo_in = 0; /* set no FIFO entries */ + dibp->chan_fifo_out = 0; /* set no FIFO entries */ + + uptr = chp->unitptr; /* get the unit ptr */ + unit = uptr - dptr->units; /* get the UNIT number */ + if (dibp->ioclq_ptr != NULL) { + qp = &dibp->ioclq_ptr[unit]; /* IOCLQ pointer */ + if (qp != NULL) { + qp->ioclq_in = 0; /* clear any entries */ + qp->ioclq_out = 0; /* clear any entries */ + } + } + + /* see if we have a rsctl device entry */ + if (dibp->rsctl_io != NULL) { /* NULL if no rsctl_io function */ + /* call the device controller to process rsctl */ + j = dibp->rsctl_io(uptr); /* get status from device */ + sim_debug(DEBUG_EXP, &cpu_dev, + "rsctl_io returned %02x chsa %04x\n", j, chsa); + } + chp->chan_status = 0; /* clear the channel status */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* clear buffer address */ + chp->chan_caw = 0x0; /* clear IOCD address */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* clear flags */ + chp->ccw_cmd = 0; /* read command */ + } + sim_debug(DEBUG_EXP, &cpu_dev, "rsctlxio return CC1 chan %04x lev %04x\n", chan, lev); + /* returning 0 for status breaks ethernet controller */ + if ((dptr != NULL) && + (DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + } else + *status = 0; /* request accepted, no status, return 0 */ + return SCPE_OK; /* All OK */ +} + +/* boot from the device (ch/sa) the caller specified */ +/* on CPU reset, the cpu has set the IOCD data at location 0-4 */ +t_stat chan_boot(uint16 chsa, DEVICE *dptr) { + int chan = get_chan(chsa); + DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to DIB for this device */ + UNIT *uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */ + CHANP *chp = 0; + + sim_debug(DEBUG_EXP, &cpu_dev, "Channel Boot chan/device addr %04x SNS %08x\n", chsa, uptr->u5); + if (dibp == 0) /* if no channel or device, error */ + return SCPE_IOERR; /* error */ + if (dibp->chan_prg == NULL) /* must have channel information for each device */ + return SCPE_IOERR; /* error */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + if (chp == 0) /* if no channel, error */ + return SCPE_IOERR; /* error */ + + /* make sure there is an IOP/MFP configured at 7e00 on system */ + if (dib_chan[0x7e] == NULL) { + sim_debug(DEBUG_CMD, dptr, + "ERROR===ERROR\nIOP/MFP device 0x7e00 not configured on system, aborting\n"); + printf("ERROR===ERROR\nIOP/MFP device 0x7e00 not configured on system, aborting\n"); + return SCPE_UNATT; /* error */ + } + + /* make sure there is an IOP/MFP console configured at 7efc/7efd on system */ + if ((dib_unit[0x7efc] == NULL) || (dib_unit[0x7efd] == NULL)) { + sim_debug(DEBUG_CMD, dptr, + "ERROR===ERROR\nCON device 0x7efc/0x7ecd not configured on system, aborting\n"); + printf("ERROR===ERROR\nCON device 0x7efc/0x7efd not configured on system, aborting\n"); + return SCPE_UNATT; /* error */ + } + + chp->chan_status = 0; /* clear the channel status */ + chp->chan_dev = chsa; /* save our address (ch/sa) */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* start loading at loc 0 */ + chp->chan_caw = 0x0; /* set IOCD address to memory location 0 */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* Command chain and supress incorrect length */ + chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */ + chp->ccw_cmd = 0; /* read command */ + /* moved here to not destry loc 0-0x14 on reset/go cmds */ + M[0] = 0x02000000; /* 0x00 IOCD 1 read into address 0 */ + M[1] = 0x60000078; /* 0x04 IOCD 1 CMD Chain, Suppress incor length, 120 bytes */ + M[2] = 0x53000000; /* 0x08 IOCD 2 BKSR or RZR to re-read boot code */ + M[3] = 0x60000001; /* 0x0C IOCD 2 CMD chain,Supress incor length, 1 byte */ + M[4] = 0x02000000; /* 0x10 IOCD 3 Read into address 0 */ + M[5] = 0x000006EC; /* 0x14 IOCD 3 Read 0x6EC bytes */ + loading = chsa; /* show we are loading from the boot device */ + + sim_debug(DEBUG_CMD, &cpu_dev, "Channel Boot calling load_ccw chan %04x status %08x\n", + chan, chp->chan_status); + + /* start processing the boot IOCL at loc 0 */ + if (load_ccw(chp, 0)) { /* load IOCL starting from location 0 */ + sim_debug(DEBUG_EXP, &cpu_dev, "Channel Boot Error return from load_ccw chan %04x status %08x\n", + chan, chp->chan_status); + chp->ccw_flags = 0; /* clear the command flags */ + chp->chan_byte = BUFF_DONE; /* done with errors */ + loading = 0; /* show we are done loading from the boot device */ + return SCPE_IOERR; /* return error */ + } + sim_debug(DEBUG_XIO, &cpu_dev, "Channel Boot OK return from load_ccw chsa %04x status %04x\n", + chsa, chp->chan_status); + return SCPE_OK; /* all OK */ +} + +/* Continue a channel program for a device */ +uint32 cont_chan(uint16 chsa) +{ + int32 stat; /* return status 0/1 from loadccw */ + CHANP *chp = find_chanp_ptr(chsa); /* channel program */ + + sim_debug(DEBUG_XIO, &cpu_dev, + "cont_chan entry chp %p chan_byte %02x chsa %04x addr %06x\n", + chp, chp->chan_byte, chsa, chp->ccw_addr); + /* we have entries, continue channel program */ + if (chp->chan_byte != BUFF_NEXT) { + /* channel program terminated already, ignore entry */ + sim_debug(DEBUG_EXP, &cpu_dev, + "cont_chan chan_byte %02x is NOT BUFF_NEXT chsa %04x addr %06x\n", + chp->chan_byte, chsa, chp->ccw_addr); + return 1; + } + if (chp->chan_byte == BUFF_NEXT) { + uint32 chan = get_chan(chsa); + sim_debug(DEBUG_XIO, &cpu_dev, + "cont_chan resume chan prog chsa %04x iocla %06x\n", + chsa, chp->chan_caw); + + /* start a channel program */ + stat = load_ccw(chp, 1); /* resume the channel program */ + /* we get status returned if there is an error on the startio cmd call */ + if (stat) { + /* we have an error or user requested interrupt, return status */ + sim_debug(DEBUG_EXP, &cpu_dev, "cont_chan error, store csw chsa %04x status %08x\n", + chsa, chp->chan_status); +/*NOTE*/ /* if we have an error, we would loop forever if the CC bit was set */ + /* the only way to stop was to do a kill */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + /* DIAG's want CC1 with memory access error */ + if (chp->chan_status & STATUS_PCHK) { + chp->chan_status &= ~STATUS_LENGTH; /* clear incorrect length */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_EXP, &cpu_dev, + "cont_chan Error1 FIFO #%1x store_csw CC1 chan %04x status %08x\n", + FIFO_Num(chsa), chan, chp->chan_status); + return SCPE_OK; /* done */ + } + /* other error, stop the show */ + chp->chan_status &= ~STATUS_PCI; /* remove PCI status bit */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_EXP, &cpu_dev, + "cont_chan Error2 FIFO #%1x store_csw CC1 chan %04x status %08x\n", + FIFO_Num(chsa), chan, chp->chan_status); + return SCPE_OK; /* done */ + } + /* we get here when the start cmd has been processed without error */ + /* go wait for the cmd to finish */ + sim_debug(DEBUG_XIO, &cpu_dev, + "cont_chan continue wait chsa %04x status %08x iocla %06x byte %02x\n", + chsa, chp->chan_status, chp->chan_caw, chp->chan_byte); + return SCPE_OK; /* done, status stored */ + } + /* must be more IOCBs, wait for them */ + sim_debug(DEBUG_XIO, &cpu_dev, + "cont_chan continue not next chsa %04x status %08x iocla %06x\n", + chsa, chp->chan_status, chp->chan_caw); + return SCPE_OK; +} + +/* Scan all channels and see if one is ready to start or has + interrupt pending. Return icb address and interrupt level +*/ +uint32 scan_chan(uint32 *ilev) { + int i; + uint32 chsa; /* No device */ + uint32 chan; /* channel num 0-7f */ + uint32 tempa; /* icb address */ + uint32 incha; /* inch address */ + uint32 chan_ivl; /* int level table address */ + uint32 chan_icba; /* Interrupt level context block address */ + CHANP *chp; /* channel prog pointer */ + DIB *dibp; /* DIB pointer */ + uint32 sw1, sw2; /* status words */ + + /* see if we are loading */ + if (loading) { + /* we are loading see if chan prog complete */ + /* get the device entry for the logical channel in SPAD */ + chan = loading & 0x7f00; /* get real channel and zero sa */ + dibp = dib_unit[chan]; /* get the IOP/MFP DIB pointer */ + if (dibp == 0) + return 0; /* skip unconfigured channel */ + /* see if status is stored in FIFO */ + /* see if the FIFO is empty */ + if ((FIFO_Num(chan)) && ((FIFO_Get(chan, &sw1) == 0) && + (FIFO_Get(chan, &sw2) == 0))) { + /* the SPAD entries are not set up, so no access to icb or ints */ + /* get the status from the FIFO and throw it away */ + /* we really should post it to the current inch address */ + /* there is really no need to post, but it might be helpfull */ + chp = find_chanp_ptr(chan); /* find the chanp pointer for channel */ + /* this address most likely will be zero here */ + tempa = chp->chan_inch_addr; /* get inch status buffer address */ + /* before overwriting memory loc 0+4, save PSD for caller in TPSD[] locations */ + TPSD[0] = M[0]; /* save PSD from loc 0&4 */ + TPSD[1] = M[1]; + /* save the status double word to memory */ + /* set BIT 1 to show status stored */ + WMW(tempa, sw1|BIT1); /* save sa & IOCD address in status WD 1 loc */ + WMW(tempa+4, sw2); /* save status and residual cnt in status WD 2 loc */ + chp->chan_byte = BUFF_DONE; /* we are done */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "LOADING %06x %04x FIFO #%1x read inch %06x sw1 %08x sw2 %08x\n", + chp->chan_caw, chan, FIFO_Num(chan), tempa, sw1|BIT1, sw2); + return loading; + } + return 0; /* not ready, return */ + } + + /* ints not blocked, so look for highest requesting interrupt */ + for (i=0; i<112; i++) { + if (SPAD[i+0x80] == 0) /* not initialize? */ + continue; /* skip this one */ + if ((SPAD[i+0x80]&MASK24) == MASK24) /* not initialize? */ + continue; /* skip this one */ + if (INTS[i] & INTS_REQ) /* if already requesting, skip */ + continue; /* skip this one */ + + /* see if there is pending status for this channel */ + /* if there is and the level is not requesting, do it */ + /* get the device entry for the logical channel in SPAD */ + chan = (SPAD[i+0x80] & 0x7f00); /* get real channel and zero sa */ + dibp = dib_chan[get_chan(chan)]; /* get the channel device information pointer */ + if (dibp == 0) /* we have a channel to check */ + continue; /* not defined, skip this one */ + + /* we have a channel to check */ + /* check for pending status */ + if (FIFO_Num(chan)) { + INTS[i] |= INTS_REQ; /* turn on channel interrupt request */ + sim_debug(DEBUG_EXP, &cpu_dev, + "scan_chan FIFO REQ FIFO #%1x irq %02x SPAD %08x INTS %08x\n", + FIFO_Num(SPAD[i+0x80] & 0x7f00), i, SPAD[i+0x80], INTS[i]); +#ifdef TRY_DEBUG_01172021 + irq_pend = 1; /* we have pending interrupt */ +#endif + continue; + } + } + + /* see if we are able to look for ints */ + if (CPUSTATUS & BIT24) /* interrupts blocked? */ + return 0; /* yes, done */ + + /* now go process the highest requesting interrupt */ + for (i=0; i<112; i++) { + if (SPAD[i+0x80] == 0) /* not initialize? */ + continue; /* skip this one */ + /* this is a bug fix for MPX 1.x restart command */ + if ((SPAD[i+0x80]&MASK24) == MASK24) /* not initialize? */ + continue; /* skip this one */ + /* stop looking if an active interrupt is found */ + if ((INTS[i]&INTS_ACT) || (SPAD[i+0x80]&SINT_ACT)) { /* look for level active */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chan INTS ACT irq %02x SPAD %08x INTS %08x\n", + i, SPAD[i+0x80], INTS[i]); + return 0; /* this level active, so stop looking */ + } + + if ((INTS[i] & INTS_ENAB) == 0) { /* ints must be enabled */ + continue; /* skip this one */ + } + + /* look for the highest requesting interrupt */ + /* that is enabled */ + if (((INTS[i] & INTS_ENAB) && (INTS[i] & INTS_REQ)) || + ((SPAD[i+0x80] & SINT_ENAB) && (INTS[i] & INTS_REQ))) { + + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chan highest int req irq %02x SPAD %08x INTS %08x\n", + i, SPAD[i+0x80], INTS[i]); + + /* requesting, make active and turn off request flag */ + INTS[i] &= ~INTS_REQ; /* turn off request */ + INTS[i] |= INTS_ACT; /* turn on active */ + SPAD[i+0x80] |= SINT_ACT; /* show active in SPAD too */ + + /* get the address of the interrupt IVL table in main memory */ + chan_ivl = SPAD[0xf1] + (i<<2); /* contents of spad f1 points to chan ivl in mem */ + chan_icba = RMW(chan_ivl); /* get the interrupt context block addr in memory */ + + /* see if there is pending status for this channel */ + /* get the device entry for the logical channel in SPAD */ + chan = (SPAD[i+0x80] & 0x7f00); /* get real channel and zero sa */ + dibp = dib_chan[get_chan(chan)]; /* get the channel device information pointer */ + if (dibp == 0) { /* see if we have a channel to check */ + /* not a channel, must be clk or ext int */ + *ilev = i; /* return interrupt level */ + irq_pend = 0; /* not pending anymore */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chan %04x POST NON FIFO irq %02x chan_icba %06x SPAD[%02x] %08x\n", + chan, i, chan_icba, i+0x80, SPAD[i+0x80]); + return(chan_icba); /* return ICB address */ + } + /* must be a device, get status ready to post */ + if (FIFO_Num(chan)) { + /* new 051020 find actual device with the channel program */ + /* not the channel, that is not correct most of the time */ + tempa = dibp->chan_fifo[dibp->chan_fifo_out]; /* get SW1 of FIFO entry */ + chsa = chan | (tempa >> 24); /* find device address for requesting chan prog */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer for channel */ + incha = chp->chan_inch_addr; /* get inch status buffer address */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chan %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + chsa, FIFO_Num(chan), i, incha, chp, chan_icba, chp->chan_byte); + if (post_csw(chp, 0)) { + /* change status from BUFF_POST to BUFF_DONE */ + /* if not BUFF_POST we have a PPCI or channel busy interrupt */ + /* so leave the channel status alone */ + if (chp->chan_byte == BUFF_POST) { + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + } + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chanx %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", + chan, FIFO_Num(chan), i, incha, RMW(chan_icba+20), chp->chan_byte); + } else { + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chanx %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + chan, FIFO_Num(chan), i, incha, chan_icba, chp->chan_byte); + } + *ilev = i; /* return interrupt level */ + irq_pend = 0; /* not pending anymore */ + return(chan_icba); /* return ICB address */ + } else { + /* we had an interrupt request, but no status is available */ + /* clear the interrupt and go on */ + /* this is a fix for MPX1X restart 092220 */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chan highest int has no stat irq %02x SPAD %08x INTS %08x\n", + i, SPAD[i+0x80], INTS[i]); + + /* requesting, make active and turn off request flag */ + INTS[i] &= ~INTS_ACT; /* turn off active int */ + SPAD[i+0x80] &= ~SINT_ACT; /* clear active in SPAD too */ + } + } + } + /* if the interrupt is not zero'd here, we get SPAD error */ + irq_pend = 0; /* not pending anymore */ + return 0; /* done */ +} + +/* part of find_dev_from_unit(UNIT *uptr) in scp.c */ +/* Find_dev pointer for a unit + Input: uptr = pointer to unit + Output: dptr = pointer to device +*/ +DEVICE *get_dev(UNIT *uptr) +{ + DEVICE *dptr = NULL; + uint32 i, j; + + if (uptr == NULL) /* must be valid unit */ + return NULL; + if (uptr->dptr) /* get device pointer from unit */ + return uptr->dptr; /* return valid pointer */ + + /* the device pointer in the unit is not set up, do it now */ + /* This should never happen as the pointer is setup in first reset call */ + for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* do all devices */ + for (j = 0; j < dptr->numunits; j++) { /* do all units for device */ + if (uptr == (dptr->units + j)) { /* match found? */ + uptr->dptr = dptr; /* set the pointer in unit */ + return dptr; /* return valid pointer */ + } + } + } + return NULL; +} + +/* set up the devices configured into the simulator */ +/* only devices with a DIB will be processed */ +t_stat chan_set_devs() { + uint32 i, j; + + for (i = 0; i < MAX_DEV; i++) { + dib_unit[i] = NULL; /* clear DIB pointer array */ + } + for (i = 0; i < MAX_CHAN; i++) { + dib_chan[i] = NULL; /* clear DIB pointer array */ + } + /* Build channel & device arrays */ + for (i = 0; sim_devices[i] != NULL; i++) { + DEVICE *dptr = sim_devices[i]; /* get pointer to next configured device */ + UNIT *uptr = dptr->units; /* get pointer to units defined for this device */ + DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to DIB for this device */ + CHANP *chp; /* channel program pointer */ + int chsa; /* addr of device chan & subaddress */ + + /* set the device back pointer in the unit structure */ + for (j = 0; j < dptr->numunits; j++) { /* loop through unit entries */ + uptr->dptr = dptr; /* set the device pointer in unit structure */ + uptr++; /* next UNIT pointer */ + } + uptr = dptr->units; /* get pointer to units again */ + + if (dibp == NULL) /* If no DIB, not channel device */ + continue; + if ((dptr->flags & DEV_DIS) || /* Skip disabled devices */ + ((dibp->chan_prg) == NULL)) { /* must have channel info for each device */ + chsa = GET_UADDR(uptr->u3); /* ch/sa value */ + continue; + } + + chp = (CHANP *)dibp->chan_prg; /* must have channel information for each device */ + /* Check if address is in unit or dev entry */ + for (j = 0; j < dptr->numunits; j++) { /* loop through unit entries */ + chsa = GET_UADDR(uptr->u3); /* ch/sa value */ + /* zero some channel data loc's for device */ + chp->unitptr = uptr; /* set the unit back pointer */ + chp->chan_status = 0; /* clear the channel status */ + chp->chan_dev = chsa; /* save our address (ch/sa) */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* start loading at loc 0 */ + chp->chan_caw = 0; /* set IOCD address to memory location 0 */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* Command chain and supress incorrect length */ + chp->ccw_cmd = 0; /* read command */ + chp->chan_inch_addr = 0; /* clear curr address of stat dw in memory */ + chp->base_inch_addr = 0; /* clear base address of stat dw in memory */ + chp->max_inch_addr = 0; /* clear last address of stat dw in memory */ + + /* is unit marked disabled? */ + if ((uptr->flags & UNIT_DIS) == 0 || (uptr->flags & UNIT_SUBCHAN) != 0) { + /* see if this is unit zero */ + if ((chsa & 0xff) == 0) { + /* we have channel mux or dev 0 of units */ + if (dptr->flags & DEV_CHAN) { + /* see if channel address already defined */ + if (dib_chan[get_chan(chsa)] != 0) { + return SCPE_IERR; /* no, arg error */ + } + /* channel mux, save dib for channel */ + dib_chan[get_chan(chsa)] = dibp; + if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */ + dibp->dev_ini(uptr, 1); /* init the channel */ + } else { + /* we have unit 0 of non-IOP/MFP device */ + if (dib_unit[chsa] != 0) { + return SCPE_IERR; /* no, arg error */ + } else { + /* channel mux, save dib for channel */ + /* for now, save any zero dev as chan */ + if (chsa) { + dib_unit[chsa] = dibp; /* no, save the dib address */ + if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */ + dibp->dev_ini(uptr, 1); /* init the channel */ + } + } + } + } else { + /* see if address already defined */ + if (dib_unit[chsa] != 0) { + return SCPE_IERR; /* no, arg error */ + } + dib_unit[chsa] = dibp; /* no, save the dib address */ + } + } + if (dibp->dev_ini != NULL) /* call channel init if defined */ + dibp->dev_ini(uptr, 1); /* init the channel */ + uptr++; /* next UNIT pointer */ + chp++; /* next CHANP pointer */ + } + } + /* now make another pass through the channels and see which integrated */ + /* channel/controllers are defined and add them to the dib_chan definitions */ + /* this will handle non-MFP/IOP channel controllers */ + for (i = 0; i < MAX_CHAN; i++) { + if (dib_chan[i] == 0) { + /* channel not defined, see if defined in dib_unit array */ + /* check device zero for suspected channel */ + if (dib_unit[i<<8]) { + /* write dibp to channel array */ + dib_chan[i] = dib_unit[i<<8]; /* save the channel dib */ + } + } else { + /* channel is defined, see if defined in dib_unit array */ + if ((dib_unit[i<<8]) == 0) { + /* write dibp to units array */ + dib_unit[i<<8] = dib_chan[i]; /* save the channel dib */ + } + } + } + return SCPE_OK; /* all is OK */ +} + +/* Validate and set the device onto a given channel */ +t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { + DEVICE *dptr; /* device pointer */ + DIB *dibp; /* dib pointer */ + UNIT *tuptr; /* temp unit pointer */ + t_value chan; /* new channel addr */ + t_stat r; /* return status */ + int i; /* temp */ + int chsa, ochsa; /* dev addr */ + + if (cptr == NULL) /* is there a UNIT name specified */ + return SCPE_ARG; /* no, arg error */ + if (uptr == NULL) /* is there a UNIT pointer */ + return SCPE_IERR; /* no, arg error */ + dptr = get_dev(uptr); /* find the device from unit pointer */ + if (dptr == NULL) { /* device not found, so error */ + fprintf(stderr, "Set dev no DEVICE cptr %s uptr %p\r\n", cptr, uptr); + return SCPE_IERR; /* error */ + } + + dibp = (DIB *)dptr->ctxt; /* get dib pointer from device struct */ + if (dibp == NULL) { /* we need a DIB */ + fprintf(stderr, "Set dev no DIB ptr %s uptr %p\r\n", cptr, uptr); + return SCPE_IERR; /* no DIB, so error */ + } + + chan = get_uint(cptr, 16, 0xffff, &r); /* get new device address */ + if (r != SCPE_OK) /* need good number */ + return r; /* number error, return error */ + + dibp->chan_addr = chan; /* set new parent channel addr */ + + /* change all the unit addresses with the new channel, but keep sub address */ + /* Clear out existing entries for all units on this device */ + tuptr = dptr->units; /* get pointer to units defined for this device */ + + /* loop through all units for this device */ + for (i = 0; i < dibp->numunits; i++) { + int mask=dibp->mask; /* sa bits that are used */ + ochsa = GET_UADDR(tuptr->u3); /* get old chsa for this unit */ + dib_unit[ochsa] = NULL; /* clear sa dib pointer */ + dib_unit[ochsa&0x7f00] = NULL; /* clear the channel dib address */ + chan &= ~mask; /* remove the unit number */ + chsa = chan | (ochsa & mask); /* put in new sa */ + if (chsa != ochsa) { + fprintf(stderr, "Set unit %x new chsa %04x old chsa %04x\r\n", i, chsa, ochsa); + } + tuptr->u3 &= ~UNIT_ADDR_MASK; /* clear old chsa for this unit */ + tuptr->u3 |= UNIT_ADDR(chsa); /* set new chsa for this unit */ + dib_unit[chan&0x7f00] = dibp; /* set the channel dib address */ + dib_unit[chsa] = dibp; /* save the dib address for new chsa */ + tuptr++; /* next unit pointer */ + } + return SCPE_OK; +} + +/* display channel/sub-address for device */ +t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc) { + DEVICE *dptr; + int chsa; + + if (uptr == NULL) /* valid unit? */ + return SCPE_IERR; /* no, error return */ + dptr = get_dev(uptr); /* get the device pointer from unit */ + if (dptr == NULL) /* valid pointer? */ + return SCPE_IERR; /* return error */ + chsa = GET_UADDR(uptr->u3); /* get the unit address */ + fprintf(st, "CHAN/SA %04x", chsa); /* display channel/subaddress */ + return SCPE_OK; /* we done */ +} + diff --git a/SEL32/sel32_clk.c b/SEL32/sel32_clk.c new file mode 100644 index 00000000..5d533bf1 --- /dev/null +++ b/SEL32/sel32_clk.c @@ -0,0 +1,714 @@ +/* sel32_clk.c: SEL 32 Class F IOP processor RTOM functions. + + Copyright (c) 2018-2021, James C. Bevier + Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers + + 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 + JAMES C. BEVIER 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. + + This module support the real-time clock and the interval timer. + These are CD/TD class 3 devices. The RTC can be programmed to + 50/100 HZ or 60/120 HZ rates and creates an interrupt at the + requested rate. The interval timer is a 32 bit register that is + loaded with a value to be down counted. An interrupt is generated + when the count reaches zero, The clock continues down counting + until read/reset by the programmer. The rate can be external or + 38.4 microseconds per count. +*/ + +#include "sel32_defs.h" + +#if NUM_DEVS_RTOM > 0 + +#define UNIT_CLK UNIT_IDLE|UNIT_DISABLE + +void rtc_setup (uint32 ss, uint32 level); +t_stat rtc_srv (UNIT *uptr); +t_stat rtc_reset (DEVICE *dptr); +t_stat rtc_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat rtc_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); +const char *rtc_desc(DEVICE *dptr); + +extern int irq_pend; /* go scan for pending int or I/O */ +extern uint32 INTS[]; /* interrupt control flags */ +extern uint32 SPAD[]; /* computer SPAD */ +extern uint32 M[]; /* system memory */ +extern uint32 outbusy; /* output waiting on timeout */ +extern uint32 inbusy; /* input waiting on timeout */ + +int32 rtc_pie = 0; /* rtc pulse ie */ +int32 rtc_tps = 60; /* rtc ticks/sec */ +int32 rtc_lvl = 0x18; /* rtc interrupt level */ + +/* Clock data structures + rtc_dev RTC device descriptor + rtc_unit RTC unit + rtc_reg RTC register list +*/ + +/* clock can be enabled / disabled */ +/* default to 60 HZ RTC */ +//718UNIT rtc_unit = { UDATA (&rtc_srv, UNIT_IDLE, 0), 16666, UNIT_ADDR(0x7F06)}; +UNIT rtc_unit = { UDATA (&rtc_srv, UNIT_CLK, 0), 16666, UNIT_ADDR(0x7F06)}; + +REG rtc_reg[] = { + { FLDATA (PIE, rtc_pie, 0) }, + { DRDATA (TIME, rtc_unit.wait, 32), REG_NZ + PV_LEFT }, + { DRDATA (TPS, rtc_tps, 8), PV_LEFT + REG_HRO }, + { NULL } + }; + +MTAB rtc_mod[] = { + { MTAB_XTD|MTAB_VDV, 50, NULL, "50HZ", + &rtc_set_freq, NULL, NULL }, + { MTAB_XTD|MTAB_VDV, 60, NULL, "60HZ", + &rtc_set_freq, NULL, NULL }, + { MTAB_XTD|MTAB_VDV, 100, NULL, "100HZ", + &rtc_set_freq, NULL, NULL }, + { MTAB_XTD|MTAB_VDV, 120, NULL, "120HZ", + &rtc_set_freq, NULL, NULL }, + { MTAB_XTD|MTAB_VDV, 0, "FREQUENCY", NULL, + NULL, &rtc_show_freq, NULL }, + { 0 } + }; + +DEVICE rtc_dev = { + "RTC", &rtc_unit, rtc_reg, rtc_mod, + 1, 8, 8, 1, 8, 8, + NULL, NULL, &rtc_reset, /* examine, deposit, reset */ + NULL, NULL, NULL, /* boot, attach, detach */ + /* dib, dev flags, debug flags, debug */ + NULL, DEV_DEBUG|DEV_DIS|DEV_DISABLE, 0, dev_debug, + NULL, NULL, &rtc_help, /* ?, ?, help */ + NULL, NULL, &rtc_desc, /* ?, ?, description */ + }; + +/* The real time clock runs continuously; therefore, it only has + a unit service routine and a reset routine. The service routine + sets an interrupt that invokes the clock counter. +*/ + +/* service clock signal from simulator */ +t_stat rtc_srv (UNIT *uptr) +{ +#ifdef STOP_CLOCK_INTS_FOR_DEXP_TEST_DEBUGGING + /* stop clock interrupts for dexp debugging */ + rtc_pie = 0; +#endif + /* if clock disabled, do not do interrupts */ + if (((rtc_dev.flags & DEV_DIS) == 0) && rtc_pie) { + int lev = 0x13; + sim_debug(DEBUG_CMD, &rtc_dev, + "RT Clock mfp INTS[%02x] %08x SPAD[%02x] %08x\n", + lev, INTS[lev], lev+0x80, SPAD[lev+0x80]); + sim_debug(DEBUG_CMD, &rtc_dev, + "RT Clock int INTS[%02x] %08x SPAD[%02x] %08x\n", + rtc_lvl, INTS[rtc_lvl], rtc_lvl+0x80, SPAD[rtc_lvl+0x80]); + if (((INTS[rtc_lvl] & INTS_ENAB) || /* make sure enabled */ + (SPAD[rtc_lvl+0x80] & SINT_ENAB)) && /* in spad too */ + (((INTS[rtc_lvl] & INTS_ACT) == 0) || /* and not active */ + ((SPAD[rtc_lvl+0x80] & SINT_ACT) == 0))) { /* in spad too */ +#if 0 + /* HACK for console I/O stopping */ + /* This reduces the number of console I/O stopping errors */ + /* need to find real cause of I/O stopping on clock interrupt */ + if ((outbusy==0) && (inbusy==0)) /* skip interrupt if con I/O in busy wait */ + INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */ + else + sim_debug(DEBUG_CMD, &rtc_dev, + "RT Clock int console busy\n"); +#else + INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */ +#endif + irq_pend = 1; /* make sure we scan for int */ + } + sim_debug(DEBUG_CMD, &rtc_dev, + "RT Clock int INTS[%02x] %08x SPAD[%02x] %08x\n", + rtc_lvl, INTS[rtc_lvl], rtc_lvl+0x80, SPAD[rtc_lvl+0x80]); + } +// temp = sim_rtcn_calb(rtc_tps, TMR_RTC); /* timer 0 for RTC */ + sim_rtcn_calb(rtc_tps, TMR_RTC); /* timer 0 for RTC */ + sim_activate_after(uptr, 1000000/rtc_tps); /* reactivate 16666 tics / sec */ + return SCPE_OK; +} + +/* Clock interrupt start/stop */ +/* ss = 1 - starting clock */ +/* ss = 0 - stopping clock */ +/* level = interrupt level */ +void rtc_setup(uint32 ss, uint32 level) +{ + uint32 addr = SPAD[0xf1] + (level<<2); /* vector address in SPAD */ + + rtc_lvl = level; /* save the interrupt level */ + addr = M[addr>>2]; /* get the interrupt context block addr */ + if (ss == 1) { /* starting? */ + INTS[level] |= INTS_ENAB; /* make sure enabled */ + SPAD[level+0x80] |= SINT_ENAB; /* in spad too */ + sim_activate(&rtc_unit, 20); /* start us off */ + sim_debug(DEBUG_CMD, &rtc_dev, + "RT Clock setup enable int %02x rtc_pie %01x ss %01x\n", + rtc_lvl, rtc_pie, ss); + } else { + INTS[level] &= ~INTS_ENAB; /* make sure disabled */ + SPAD[level+0x80] &= ~SINT_ENAB; /* in spad too */ + INTS[level] &= ~INTS_ACT; /* make sure request not active */ + SPAD[level+0x80] &= ~SINT_ACT; /* in spad too */ + sim_debug(DEBUG_CMD, &rtc_dev, + "RT Clock setup disable int %02x rtc_pie %01x ss %01x\n", + rtc_lvl, rtc_pie, ss); + } + rtc_pie = ss; /* set new state */ +} + +/* Clock reset */ +t_stat rtc_reset(DEVICE *dptr) +{ + rtc_pie = 0; /* disable pulse */ + /* initialize clock calibration */ + sim_activate (&rtc_unit, rtc_unit.wait); /* activate unit */ + return SCPE_OK; +} + +/* Set frequency */ +t_stat rtc_set_freq(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + if (cptr) /* if chars, bad */ + return SCPE_ARG; /* ARG error */ + if ((val != 50) && (val != 60) && (val != 100) && (val != 120)) + return SCPE_IERR; /* scope error */ + rtc_tps = val; /* set the new frequency */ + return SCPE_OK; /* we done */ +} + +/* Show frequency */ +t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + /* print the current frequency setting */ + if (rtc_tps < 100) + fprintf (st, (rtc_tps == 50)? "50Hz": "60Hz"); + else + fprintf (st, (rtc_tps == 100)? "100Hz": "120Hz"); + return SCPE_OK; +} + +/* sho help rtc */ +t_stat rtc_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr) +{ + fprintf(st, "SEL 32 IOP/MFP realtime clock at 0x7F06\r\n"); + fprintf(st, "Use:\r\n"); + fprintf(st, " sim> SET RTC [50][60][100][120]\r\n"); + fprintf(st, "to set clock interrupt rate in HZ\r\n"); + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + return SCPE_OK; +} + +/* device description */ +const char *rtc_desc(DEVICE *dptr) +{ + return "SEL IOP/MFP realtime clock @ address 0x7F06"; +} + +/************************************************************************/ + +/* Interval Timer support */ +int32 itm_src = 0; /* itm source freq 0=itm 1=rtc */ +int32 itm_pie = 0; /* itm pulse enable */ +int32 itm_run = 0; /* itm is running */ +int32 itm_cmd = 0; /* itm last user cmd */ +int32 itm_cnt = 0; /* itm reload pulse count */ +int32 itm_tick_size_x_100 = 3840; /* itm 26042 ticks/sec = 38.4 us per tic */ +int32 itm_lvl = 0x5f; /* itm interrupt level */ +int32 itm_strt = 0; /* clock start time in usec */ +int32 itm_load = 0; /* clock loaded */ +int32 itm_big = 26042 * 6000; /* about 100 minutes */ +t_stat itm_srv (UNIT *uptr); +t_stat itm_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat itm_reset (DEVICE *dptr); +t_stat itm_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat itm_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); +const char *itm_desc(DEVICE *dptr); + +/* Clock data structures + itm_dev Interval Timer ITM device descriptor + itm_unit Interval Timer ITM unit + itm_reg Interval Timer ITM register list +*/ + +/* Mark suggested I remove the UNIT_IDLE flag from ITM. This causes SEL32 */ +/* to use 100% of the CPU instead of waiting and running 10% cpu usage */ +//BAD Mark UNIT itm_unit = { UDATA (&itm_srv, UNIT_IDLE, 0), 26042, UNIT_ADDR(0x7F04)}; +UNIT itm_unit = { UDATA (&itm_srv, 0, 0), 26042, UNIT_ADDR(0x7F04)}; + +REG itm_reg[] = { + { FLDATA (PIE, itm_pie, 0) }, + { FLDATA (CNT, itm_cnt, 0) }, + { FLDATA (CMD, itm_cmd, 0) }, + { DRDATA (TICK_SIZE, itm_tick_size_x_100, 32), PV_LEFT + REG_HRO }, + { NULL } + }; + +MTAB itm_mod[] = { + { MTAB_XTD|MTAB_VDV, 3840, NULL, "3840us", + &itm_set_freq, NULL, NULL }, + { MTAB_XTD|MTAB_VDV, 7680, NULL, "7680us", + &itm_set_freq, NULL, NULL }, + { MTAB_XTD|MTAB_VDV, 0, "RESOLUTION", NULL, + NULL, &itm_show_freq, NULL }, + { 0 } + }; + +DEVICE itm_dev = { + "ITM", &itm_unit, itm_reg, itm_mod, + 1, 8, 8, 1, 8, 8, + NULL, NULL, &itm_reset, /* examine, deposit, reset */ + NULL, NULL, NULL, /* boot, attach, detach */ + /* dib, dev flags, debug flags, debug */ +// NULL, DEV_DEBUG|DEV_DIS|DEV_DISABLE, 0, dev_debug, + NULL, DEV_DEBUG, 0, dev_debug, /* dib, dev flags, debug flags, debug */ + NULL, NULL, &itm_help, /* ?, ?, help */ + NULL, NULL, &itm_desc, /* ?, ?, description */ + }; + +/* The interval timer downcounts the value it is loaded with and + runs continuously; therefore, it has a read/write routine, + a unit service routine and a reset routine. The service routine + sets an interrupt that invokes the clock counter. +*/ + +/* service clock expiration from simulator */ +/* cause interrupt */ +t_stat itm_srv (UNIT *uptr) +{ + if (itm_pie) { /* interrupt enabled? */ + time_t result = time(NULL); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv Timer expired status %08x lev %02x cnt %x @ time %08x\n", + INTS[itm_lvl], itm_lvl, itm_cnt, (uint32)result); + if (((INTS[itm_lvl] & INTS_ENAB) || /* make sure enabled */ + (SPAD[itm_lvl+0x80] & SINT_ENAB)) && /* in spad too */ + (((INTS[itm_lvl] & INTS_ACT) == 0) || /* and not active */ + ((SPAD[itm_lvl+0x80] & SINT_ACT) == 0))) { /* in spad too */ + INTS[itm_lvl] |= INTS_REQ; /* request the interrupt */ + irq_pend = 1; /* make sure we scan for int */ + } + sim_cancel (&itm_unit); /* cancel current timer */ + itm_run = 0; /* timer is no longer running */ + /* if cmd BIT29 is set, reload & restart */ + if ((INTS[itm_lvl] & INTS_ENAB) && (itm_cmd & 0x04) && (itm_cnt != 0)) { + sim_debug(DEBUG_CMD, &itm_dev, + "Intv Timer reload on expired int %02x value %08x src %x\n", + itm_lvl, itm_cnt, itm_src); + /* restart timer with value from user */ + if (itm_src) /* use specified src freq */ + sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*350000)/rtc_tps); +//DIAG sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*400000)/rtc_tps); +//DIAG sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*1000000)/rtc_tps); + else + sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*itm_tick_size_x_100)/100.0); + itm_run = 1; /* show timer running */ + itm_load = itm_cnt; /* save loaded value */ + itm_strt = 0; /* no negative start time */ + } else { + int32 cnt = itm_big; /* 0x65ba TRY 1,000,000/38.4 10 secs */ + itm_strt = cnt; /* get negative start time */ + sim_debug(DEBUG_CMD, &itm_dev, + "Intv Timer reload for neg cnts on expired int %02x value %08x src %x\n", + itm_lvl, cnt, itm_src); + /* restart timer with large value for negative timer value simulation */ + if (itm_src) /* use specified src freq */ + sim_activate_after_abs_d(&itm_unit, ((double)cnt*1000000)/rtc_tps); + else + sim_activate_after_abs_d(&itm_unit, ((double)cnt*itm_tick_size_x_100) / 100.0); + itm_run = 1; /* show timer running */ + itm_load = cnt; /* save loaded value */ + } + } + return SCPE_OK; +} + +/* ITM read/load function called from CD command processing */ +/* cmd bit assignments */ +/* 0x40 = BIT25 = Read ITM value into R0 at anythime */ +/* 0x20 = BIT26 = Program ITM and BIT27-BIT31 are valid */ +/* 0x10 = BIT27 = =1 start timer, =0 stop timer */ +/* 0x08 = BIT28 = =1 store R0 into ITM, =0 do not alter clock value */ +/* 0x04 = BIT29 = =1 generate multiple ints on countdown to 0, reload start value */ +/* =0 generate single int on countdown to 0, continue counting negative */ +/* 0x02 = BIT30 = BIT30 = 0 BIT31 = 0 = use jumpered clock frequency */ +/* 0x01 = BIT31 = BIT30 = 0 BIT31 = 1 = use jumpered clock frequency */ +/* = BIT30 = 1 BIT31 = 0 = use RT clock frequency 50/60/100/120 HZ */ +/* = BIT30 = 1 BIT31 = 1 = use external clock frequency */ +/* level = interrupt level */ +/* cmd = 0x20 stop timer, do not transfer any value */ +/* = 0x39 load and enable interval timer, no return value */ +/* = 0x3d load and enable interval timer, countdown to zero, interrupt and reload */ +/* = 0x40 read timer value */ +/* = 0x60 read timer value and stop timer */ +/* = 0x79 read/reload and start timer */ +/* cnt = value to write to timer */ +/* ret = return value read from timer */ +int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level) +{ + uint32 temp; + + cmd &= 0x7f; /* just need the cmd */ + itm_cmd = cmd; /* save last cmd */ + switch (cmd) { + case 0x20: /* stop timer */ + /* stop the timer and save the curr value for later */ + temp = itm_load; /* use last loaded value */ + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x kill value %08x (%08d) itm_load %08x\n", + cmd, cnt, cnt, temp); + if (itm_run) { /* if we were running save curr cnt */ + /* read timer value */ + temp = (uint32)(100.0*sim_activate_time_usecs(&itm_unit)/itm_tick_size_x_100); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x temp value %08x (%d)\n", cmd, temp, temp); + if (itm_strt) { /* see if running neg */ + /* we only get here if timer ran out and no reload value */ + /* get simulated negative start time in counts */ + temp = temp - itm_strt; /* make into a negative number */ + } + } + sim_cancel (&itm_unit); /* cancel itc */ + itm_run = 0; /* timer is not running */ + itm_cnt = 0; /* no count reset value */ + itm_load = temp; /* last loaded value */ + itm_strt = 0; /* not restarted neg */ + return 0; /* does not matter, no value returned */ + break; + + case 0x29: /* load new value and start lo rate */ + case 0x28: /* load new value and start hi rate */ + case 0x2a: /* load new value and use RTC */ + case 0x2b: /* load new value and start hi rate */ + case 0x38: /* load new value and start hi rate */ + case 0x39: /* load new value and start lo rate */ + case 0x3a: /* load new value and start hi rate */ + case 0x3b: /* load new value and start lo rate */ + if (itm_run) /* if we were running stop timer */ + sim_cancel (&itm_unit); /* cancel timer */ + itm_run = 0; /* stop timer running */ + if (cmd & 0x10) { /* clock to start? */ + /* start timer with value from user */ + /* if bits 30-31 == 20, use RTC freq */ + itm_src = (cmd>>1)&1; /* set src */ + if (itm_src) /* use specified src freq */ + /* use clock frequency */ + sim_activate_after_abs_d(&itm_unit, ((double)cnt*1000000)/rtc_tps); + else { + /* use interval timer freq */ +#ifdef MAYBE_CHANGE_FOR_MPX3X + /* tsm does not run if fake time cnt is used */ +/// if (cnt == 0) +/// cnt = 0x52f0; + /* this fixes an extra interrupt being generated on context switch */ + /* the value is load for the new task anyway */ + /* need to verify that UTX likes it too */ +/*4MPX3X*/ sim_activate_after_abs_d(&itm_unit, ((double)(cnt+1)*itm_tick_size_x_100)/100.0); +#else + sim_activate_after_abs_d(&itm_unit, ((double)cnt*itm_tick_size_x_100)/100.0); +#endif + } + itm_run = 1; /* set timer running */ + } + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%02x init value %08x (%08d)\n", cmd, cnt, cnt); + itm_cnt = 0; /* no count reset value */ + itm_load = cnt; /* now loaded */ + itm_strt = 0; /* not restarted neg */ + return 0; /* does not matter, no value returned */ + break; + + case 0x70: /* start timer with curr value*/ + case 0x71: /* start timer with curr value */ + case 0x72: /* start timer with RTC value*/ + case 0x74: /* start timer with curr value*/ + case 0x75: /* start timer with curr value */ + case 0x76: /* start timer with RTC value*/ + case 0x30: /* start timer with curr value*/ + case 0x31: /* start timer with curr value*/ + case 0x32: /* start timer with RTC value*/ + case 0x34: /* start timer with curr value*/ + case 0x35: /* start timer with curr value */ + case 0x36: /* start timer with RTC value*/ + case 0x37: /* start timer with curr value */ + temp = itm_load; /* get last loaded value */ + if (itm_run) { /* if we were running save curr cnt */ + /* read timer value */ + temp = (uint32)(100.0*sim_activate_time_usecs(&itm_unit)/itm_tick_size_x_100); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x temp value %08x (%d)\n", cmd, temp, temp); + if (itm_strt) { /* see if running neg */ + /* we only get here if timer ran out and no reload value */ + /* get simulated negative start time in counts */ + temp = temp - itm_strt; /* make into a negative number */ + } + sim_cancel (&itm_unit); /* cancel timer */ + } + /* start timer with current or user value, reload on zero time */ + cnt = temp; /* use current value */ + /* if bits 30-31 == 20, use RTC freq */ + itm_src = (cmd>>1)&1; /* set src */ + if (itm_src) /* use specified src freq */ +//DIAG sim_activate_after_abs_d(&itm_unit, ((double)cnt*400000)/rtc_tps); + sim_activate_after_abs_d(&itm_unit, ((double)cnt*1000000)/rtc_tps); + else + sim_activate_after_abs_d(&itm_unit, ((double)cnt*itm_tick_size_x_100)/100.0); + itm_run = 1; /* set timer running */ + + if (cmd & 0x04) /* do we reload on zero? */ + itm_cnt = cnt; /* count reset value */ + else + itm_cnt = 0; /* no count reset value */ + itm_strt = 0; /* not restarted neg */ + itm_load = cnt; /* now loaded */ + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%02x return value %08x (%08d)\n", cmd, temp, temp); + return temp; /* return curr count */ + break; + + case 0x3c: /* load timer with new value and start */ + case 0x3d: /* load timer with new value and start */ + /* load timer with new value and start using RTC as source */ + case 0x3e: /* load timer with new value and start RTC*/ + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x init value %08x (%d)\n", cmd, cnt, cnt); + sim_cancel (&itm_unit); /* cancel timer */ + /* if bits 30-31 == 20, use RTC freq */ + itm_src = (cmd>>1)&1; /* set src */ + if (itm_src) /* use specified src freq */ + sim_activate_after_abs_d(&itm_unit, ((double)cnt*700000)/rtc_tps); + else + sim_activate_after_abs_d(&itm_unit, ((double)cnt*itm_tick_size_x_100)/100.0); + itm_run = 1; /* set timer running */ + + if (cmd & 0x04) /* do we reload on zero? */ + itm_cnt = cnt; /* count reset value */ + itm_strt = 0; /* not restarted neg */ + itm_load = cnt; /* now loaded */ + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%02x return value %08x (%08d)\n", cmd, cnt, cnt); + return 0; /* does not matter, no value returned */ + break; + + case 0x40: /* read the current timer value */ + /* return current count value from timer */ + temp = itm_load; /* get last loaded value */ + if (itm_run) { /* if we were running save curr cnt */ + /* read timer value */ + temp = (uint32)(100.0*sim_activate_time_usecs(&itm_unit)/itm_tick_size_x_100); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x read value %08x (%d)\n", cmd, temp, temp); + if (itm_strt) { /* see if running neg */ + /* we only get here if timer ran out and no reload value */ + /* get simulated negative start time in counts */ + temp = temp - itm_strt; /* make into a negative number */ + } + } + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x40 return value %08x (%d)\n", temp, temp); + return temp; + break; + + case 0x60: /* read and stop timer */ + /* get timer value and stop timer */ + temp = itm_load; /* get last loaded value */ + if (itm_run) { /* if we were running save curr cnt */ + /* read timer value */ + temp = (uint32)(100.0*sim_activate_time_usecs(&itm_unit)/itm_tick_size_x_100); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x read value %08x (%d)\n", cmd, temp, temp); + if (itm_strt) { /* see if running neg */ + /* we only get here if timer ran out and no reload value */ + /* get simulated negative start time in counts */ + temp = temp - itm_strt; /* make into a negative number */ + } + sim_cancel (&itm_unit); /* cancel timer */ + } + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x temp value %08x (%d)\n", cmd, temp, temp); + itm_run = 0; /* stop timer running */ + itm_cnt = 0; /* no reload count value */ + itm_load = temp; /* current loaded value */ + itm_strt = 0; /* not restarted neg */ + return temp; /* return current count value */ + break; + + case 0x6a: /* read value & load new one */ + case 0x68: /* read value & load new one */ + case 0x69: /* read value & load new one */ + /* get timer value and load new value, do not start timer */ + temp = itm_load; /* get last loaded value */ + if (itm_run) { /* if we were running save curr cnt */ + /* read timer value */ + temp = (uint32)(100.0*sim_activate_time_usecs(&itm_unit)/itm_tick_size_x_100); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x read value %08x (%d)\n", cmd, temp, temp); + if (itm_strt) { /* see if running neg */ + /* we only get here if timer ran out and no reload value */ + /* get simulated negative start time in counts */ + temp = temp - itm_strt; /* make into a negative number */ + } + sim_cancel (&itm_unit); /* cancel timer */ + } + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%02x temp value %08x (%08d)\n", cmd, temp, temp); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%02x init value %08x (%08d)\n", cmd, cnt, cnt); + itm_src = (cmd>>1)&1; /* set src */ + itm_run = 0; /* stop timer running */ + itm_cnt = 0; /* no count reset value */ + itm_strt = 0; /* not restarted neg */ + itm_load = cnt; /* now loaded */ + return temp; /* return current count value */ + break; + + case 0x7d: /* read the current timer value */ + case 0x78: /* read the current timer value */ + case 0x79: /* read the current timer value */ + case 0x7a: /* read the current timer value */ + case 0x7b: /* read the current timer value */ + case 0x7c: /* read the current timer value */ + case 0x7e: /* read the current timer value */ + case 0x7f: /* read the current timer value */ + /* get timer value, load new value and start timer */ + temp = itm_load; /* get last loaded value */ + if (itm_run) { /* if we were running save curr cnt */ + /* read timer value */ + temp = (uint32)(100.0*sim_activate_time_usecs(&itm_unit)/itm_tick_size_x_100); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%2x read value %08x (%d)\n", cmd, temp, temp); + if (itm_strt) { /* see if running neg */ + /* we only get here if timer ran out and no reload value */ + /* get simulated negative start time in counts */ + temp = temp - itm_strt; /* make into a negative number */ + } +//extra sim_cancel (&itm_unit); /* cancel timer */ + } + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%02x temp value %08x (%08d)\n", cmd, temp, temp); + sim_debug(DEBUG_CMD, &itm_dev, + "Intv 0x%02x init value %08x (%08d)\n", cmd, cnt, cnt); + sim_cancel (&itm_unit); /* cancel timer */ + /* start timer to fire after cnt ticks */ + itm_src = (cmd>>1)&1; /* set src */ + if (itm_src) /* use specified src freq */ + sim_activate_after_abs_d(&itm_unit, ((double)cnt*1000000)/rtc_tps); + else + sim_activate_after_abs_d(&itm_unit, ((double)cnt*itm_tick_size_x_100)/100.0); + itm_cnt = 0; /* no count reset value */ + if (cmd & 0x04) /* reload on int? */ + itm_cnt = cnt; /* set reload count value */ + itm_run = 1; /* set timer running */ + itm_strt = 0; /* not restarted neg */ + itm_load = cnt; /* now loaded */ + return temp; /* return current count value */ + break; + default: + sim_debug(DEBUG_CMD, &itm_dev, + "Intv unknown cmd %02x level %02x\n", cmd, level); + break; + } + return 0; /* does not matter, no value returned */ +} + +/* Clock interrupt start/stop */ +/* ss = 1 - clock interrupt enabled */ +/* ss = 0 - clock interrupt disabled */ +/* level = interrupt level */ +void itm_setup(uint32 ss, uint32 level) +{ + itm_lvl = level; /* save the interrupt level */ + itm_load = 0; /* not loaded */ + itm_src = 0; /* use itm for freq */ + itm_strt = 0; /* not restarted neg */ + itm_run = 0; /* not running */ + itm_cnt = 0; /* no count reset value */ + sim_cancel (&itm_unit); /* not running yet */ + if (ss == 1) { /* starting? */ + INTS[level] |= INTS_ENAB; /* make sure enabled */ + SPAD[level+0x80] |= SINT_ENAB; /* in spad too */ + sim_debug(DEBUG_CMD, &itm_dev, + "Intv Timer setup enable int %02x value %08x itm_pie %01x ss %01x\n", + itm_lvl, itm_cnt, itm_pie, ss); + } else { + INTS[level] &= ~INTS_ENAB; /* make sure disabled */ + SPAD[level+0x80] &= ~SINT_ENAB; /* in spad too */ + sim_debug(DEBUG_CMD, &itm_dev, + "Intv Timer setup disable int %02x value %08x itm_pie %01x ss %01x\n", + itm_lvl, itm_cnt, itm_pie, ss); + } + itm_pie = ss; /* set new state */ +} + +/* Clock reset */ +t_stat itm_reset (DEVICE *dptr) +{ + itm_pie = 0; /* disable pulse */ + itm_run = 0; /* not running */ + itm_load = 0; /* not loaded */ + itm_src = 0; /* use itm for freq */ + itm_strt = 0; /* not restarted neg */ + itm_cnt = 0; /* no count reset value */ + sim_cancel (&itm_unit); /* not running yet */ + return SCPE_OK; +} + +/* Set frequency */ +t_stat itm_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + if (cptr) /* if chars, bad */ + return SCPE_ARG; /* ARG error */ + if ((val != 3840) && (val != 7680)) + return SCPE_IERR; /* scope error */ + itm_tick_size_x_100 = val; /* set the new frequency */ + return SCPE_OK; /* we done */ +} + +/* Show frequency */ +t_stat itm_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + /* print the current interval count setting */ + fprintf (st, "%0.2fus", (itm_tick_size_x_100 / 100.0)); + return SCPE_OK; +} + +/* sho help rtc */ +t_stat itm_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr) +{ + fprintf(st, "SEL 32 IOP/MFP interval timer at 0x7F04\r\n"); + fprintf(st, "Use:\r\n"); + fprintf(st, " sim> SET ITM [3840][7680]\r\n"); + fprintf(st, "to set interval timer clock rate in us x 100\r\n"); + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + return SCPE_OK; +} + +/* device description */ +const char *itm_desc(DEVICE *dptr) +{ + return "SEL IOP/MFP Interval Timer @ address 0x7F04"; +} + +#endif + diff --git a/SEL32/sel32_com.c b/SEL32/sel32_com.c new file mode 100644 index 00000000..99547523 --- /dev/null +++ b/SEL32/sel32_com.c @@ -0,0 +1,1333 @@ +/* sel32_com.c: SEL 32 8-Line IOP communications controller + + Copyright (c) 2018-2021, James C. Bevier + Portions provided by Richard Cornwell and other SIMH contributers + + 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 + JAMES C. BEVIER 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 "sel32_defs.h" +#include "sim_sock.h" +#include "sim_tmxr.h" +#include + +#if NUM_DEVS_COM > 0 + +/* Constants */ +#define COM_LINES 8 /* lines defined */ +//Change from 500 to 5000 12/02/2021 +//Change from 5000 to 4000 12/02/2021 +//#define COML_WAIT 500 +#define COML_WAIT 4000 +//Change from 1000 to 5000 12/02/2021 +//#define COM_WAIT 5000 +//#define COM_WAIT 1000 +#define COM_WAIT 5000 +#define COM_NUMLIN com_desc.lines /* curr # lines */ + +#define COMC 0 /* channel thread */ +#define COMI 1 /* input thread */ + +/* Line status */ +#define COML_XIA 0x01 /* xmt intr armed */ +#define COML_XIR 0x02 /* xmt intr req */ +#define COML_REP 0x04 /* rcv enable pend */ +#define COML_RBP 0x10 /* rcv break pend */ + +struct _com_data +{ + uint8 incnt; /* char count */ + uint8 ibuff[120]; /* Input line buffer */ +} +com_data[COM_LINES]; + +uint8 com_rbuf[COM_LINES]; /* rcv buf */ +uint8 com_xbuf[COM_LINES]; /* xmt buf */ +uint8 com_stat[COM_LINES]; /* status */ + +TMLN com_ldsc[COM_LINES] = { 0 }; /* line descrs */ +TMXR com_desc = { COM_LINES, 0, 0, com_ldsc }; /* com descr */ + +#define CMD u3 +/* Held in u3 is the device command and status */ +#define COM_INCH 0x00 /* Initialize channel command */ +#define COM_WR 0x01 /* Write terminal */ +#define COM_RD 0x02 /* Read terminal */ +#define COM_NOP 0x03 /* No op command */ +#define COM_SNS 0x04 /* Sense command */ +#define COM_WRSCM 0x05 /* Write w/Sub chan monitor */ +#define COM_RDECHO 0x06 /* Read with Echo */ +#define COM_RDFC 0x0A /* Read w/flow control */ +#define COM_DEFSC 0x0B /* Define special char */ +#define COM_WRHFC 0x0D /* Write hardware flow control */ +#define COM_RRDFLOW 0x0E /* Read w/hardware flow control only RTS */ +#define COM_RDTR 0x13 /* Reset DTR (ADVR) */ +#define COM_SDTR 0x17 /* Set DTR (ADVF) */ +#define COM_RRTS 0x1B /* Reset RTS */ +#define COM_SRTS 0x1F /* Set RTS */ +#define COM_RBRK 0x33 /* Reset BREAK */ +#define COM_SBRK 0x37 /* Set BREAK */ +#define COM_SETFLOW 0x53 /* Set transparent flow control mode */ +#define COM_RDHFC 0x8E /* Read w/hardware flow control only DTR */ +#define COM_SACE 0xFF /* Set ACE parameters */ + +#define COM_MSK 0xFF /* Command mask */ + +/* Status held in CMD (u3) */ +/* controller/unit address in upper 16 bits */ +#define COM_INPUT 0x0100 /* Input ready for unit */ +//#define COM_RDY 0x0200 /* SNS_DSRS */ /* Device is ready */ +#define COM_SCD 0x0400 /* Special char detect */ +#define COM_EKO 0x0800 /* Echo input character */ +#define COM_OUTPUT 0x1000 /* Output ready for unit */ +#define COM_READ 0x2000 /* Read mode selected */ +#define COM_ACC 0x4000 /* ASCII control char detect */ +#define COM_CONN 0x8000 /* TMXR ATT */ /* Terminal connected */ + +/* ACE data kept in u4 */ +/* ACE information in u4 */ +#define ACE u4 +#if 0 +/* ACE byte 0 Modem Control/Operation status */ +/* stored in u4 bytes 0-3 */ +#define SNS_HALFD 0x80000000 /* Half-duplix operation set */ +#define SNS_MRINGE 0x40000000 /* Modem ring enabled */ +#define SNS_ACEFP 0x20000000 /* Forced parity 0=odd, 1=even */ +#define SNS_ACEP 0x10000000 /* Parity 0=odd, 1=even */ +#define SNS_ACEPE 0x08000000 /* Parity enable 0=dis, 1=enb */ +#define SNS_ACESTOP 0x04000000 /* Stop bit 0=1, 1=1.5 or 2 */ +#define SNS_ACECLEN 0x02000000 /* Character length 00=5, 01=6, 10=7, 11=8 */ +#define SNS_ACECL2 0x01000000 /* 2nd bit for above */ + +/* ACE byte 1 Baud rate */ +#define SNS_NODCDA 0x00800000 /* Enable Delta DCD Attention Interrupt */ +#define SNS_WAITOLB 0x00400000 /* Wait on last byte enabled */ +#define SNS_RINGCR 0x00200000 /* Ring or wakeup character recognition 0=enb, 1=dis */ +#define SNS_DIAGL 0x00100000 /* Set diagnostic loopback */ +#define SNS_BAUD 0x000F0000 /* Baud rate bits 4-7 */ +#define BAUD50 0x00000000 /* 50 baud */ +#define BAUD75 0x00010000 /* 75 baud */ +#define BAUD110 0x00020000 /* 110 baud */ +#define BAUD114 0x00030000 /* 134 baud */ +#define BAUD150 0x00040000 /* 150 baud */ +#define BAUD300 0x00050000 /* 300 baud */ +#define BAUD600 0x00060000 /* 600 baud */ +#define BAUD1200 0x00070000 /* 1200 baud */ +#define BAUD1800 0x00080000 /* 1800 baud */ +#define BAUD2000 0x00090000 /* 2000 baud */ +#define BAUD2400 0x000A0000 /* 2400 baud */ +#define BAUD3600 0x000B0000 /* 3600 baud */ +#define BAUD4800 0x000C0000 /* 4800 baud */ +#define BAUD7200 0x000D0000 /* 7200 baud */ +#define BAUD9600 0x000E0000 /* 9600 baud */ +#define BAUD19200 0x000F0000 /* 19200 baud */ + +/* ACE byte 2 Wake-up character */ +#define ACE_WAKE 0x0000FF00 /* 8 bit wake-up character */ +#endif +#define ACE_WAKE 0x0000FF00 /* 8 bit wake-up character in byte 2 of ACE */ + +#define SNS u5 +/* in u5 packs sense byte 0, 1, 2 and 3 */ +/* Sense byte 0 */ +#define SNS_CMDREJ 0x80000000 /* Command reject */ +#define SNS_INTVENT 0x40000000 /* Unit intervention required (N/U) */ +#define SNS_BOCHK 0x20000000 /* Bus out check (IOP parity error */ +#define SNS_EQUIPCK 0x10000000 /* Equipment check (device error) */ +#define SNS_DATACK 0x08000000 /* Data check */ +#define SNS_OVERRN 0x04000000 /* Overrun (N/U) */ +#define SNS_NUB01 0x02000000 /* Zero (N/U) */ +#define SNS_RDY SNS_NUB01 /* SNS_RDY device ready */ +#define SNS_NUB02 0x01000000 /* Zero (N/U) */ +#define SNS_CONN SNS_NUB02 /* SNS_CONN device connected */ +/* Sense byte 1 */ +#define SNS_ASCIICD 0x00800000 /* ASCII control char detected interrupt */ +#define SNS_SPCLCD 0x00400000 /* Special char detected interrupt */ +#define SNS_ETX 0x00200000 /* ETX interrupt */ +#define SNS_BREAK 0x00100000 /* BREAK interrupt */ +#define SNS_ACEFE 0x00080000 /* ACE framing error interrupt */ +#define SNS_ACEPEI 0x00040000 /* ACE parity error interrupt */ +#define SNS_ACEOVR 0x00020000 /* ACE overrun error interrupt */ +#define SNS_RING 0x00010000 /* Ring character interrupt */ +/* Sense byte 2 Modem status */ +#define SNS_RLSDS 0x00008000 /* Received line signal detect */ +#define SNS_RINGST 0x00004000 /* Ring indicator signal detect */ +#define SNS_DSRS 0x00002000 /* DSR Data set ready line status */ +#define SNS_CTSS 0x00001000 /* CTS Clear to send line status */ +#define SNS_DELTA 0x00000800 /* Delta receive line signal detect failure interrupt */ +#define SNS_MRING 0x00000400 /* RI Modem ring interrupt */ +#define SNS_DELDSR 0x00000200 /* DSR failure interrupt */ +#define SNS_DELCTS 0x00000100 /* CLS failure interrupt */ +/* Sense byte 3 Modem Control/Operation status */ +#define SNS_HALFD 0x00000080 /* Half-duplix operation set */ +#define SNS_MRINGE 0x00000040 /* Modem ring enabled (1) */ +#define SNS_ACEDEF 0x00000020 /* ACE parameters defined */ +#define SNS_DIAGM 0x00000010 /* Diagnostic mode set */ +#define SNS_AUXOL2 0x00000008 /* Auxiliary output level 2 */ +#define SNS_AUXOL1 0x00000004 /* Auxiliary output level 1 */ +#define SNS_RTS 0x00000002 /* RTS Request to send set */ +#define SNS_DTR 0x00000001 /* DTR Data terminal ready set */ +/* Sense byte 4 ACE Parameters status */ +#define SNS_ACEDLE 0x80000000 /* Divisor latch enable 0=dis, 1=enb */ +#define SNS_ACEBS 0x40000000 /* Break set 0=reset, 1=set */ +#define SNS_ACEFP 0x20000000 /* Forced parity 0=odd, 1=even */ +#define SNS_ACEP 0x10000000 /* Parity 0=odd, 1=even */ +#define SNS_ACEPE 0x08000000 /* Parity enable 0=dis, 1=enb */ +#define SNS_ACESTOP 0x04000000 /* Stop bit 0=1, 1=1.5 or 2 */ +#define SNS_ACECLEN 0x02000000 /* Character length 00=5, 01=6, 11=7, 11=8 */ +#define SNS_ACECL2 0x01000000 /* 2nd bit for above */ +/* Sense byte 5 Baud rate */ +#define SNS_NODCDA 0x00800000 /* Enable Delta DCD Attention Interrupt */ +#define SNS_WAITOLB 0x00400000 /* Wait on last byte enabled */ +#define SNS_RINGCR 0x00200000 /* Ring or wakeup character recognition 0=enb, 1=dis */ +#define SNS_DIAGL 0x00100000 /* Set diagnostic loopback */ +#define SNS_BAUD 0x000F0000 /* Baud rate bits 4-7 */ +#define BAUD50 0x00000000 /* 50 baud */ +#define BAUD75 0x00010000 /* 75 baud */ +#define BAUD110 0x00020000 /* 110 baud */ +#define BAUD114 0x00030000 /* 134 baud */ +#define BAUD150 0x00040000 /* 150 baud */ +#define BAUD300 0x00050000 /* 300 baud */ +#define BAUD600 0x00060000 /* 600 baud */ +#define BAUD1200 0x00070000 /* 1200 baud */ +#define BAUD1800 0x00080000 /* 1800 baud */ +#define BAUD2000 0x00090000 /* 2000 baud */ +#define BAUD2400 0x000A0000 /* 2400 baud */ +#define BAUD3600 0x000B0000 /* 3600 baud */ +#define BAUD4800 0x000C0000 /* 4800 baud */ +#define BAUD7200 0x000D0000 /* 7200 baud */ +#define BAUD9600 0x000E0000 /* 9600 baud */ +#define BAUD19200 0x000F0000 /* 19200 baud */ +/* Sense byte 6 Firmware ID, Revision Level */ +#define SNS_FID 0x00006200 /* ID part 1 */ +/* Sense byte 7 Firmware ID, Revision Level */ +#define SNS_REV 0x0000004f /* ID part 2 plus 4 bit rev # */ + +/* u6 */ +#define CNT u6 + +/* forward definitions */ +t_stat coml_preio(UNIT *uptr, uint16 chan); +t_stat coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); +t_stat coml_haltio(UNIT *uptr); +void com_ini(UNIT *, t_bool); +void coml_ini(UNIT *, t_bool); +t_stat coml_rschnlio(UNIT *uptr); +t_stat com_rschnlio(UNIT *uptr); +t_stat comi_srv(UNIT *uptr); +t_stat como_srv(UNIT *uptr); +t_stat comc_srv(UNIT *uptr); +t_stat com_reset(DEVICE *dptr); +t_stat com_attach(UNIT *uptr, CONST char *cptr); +t_stat com_detach(UNIT *uptr); +void com_reset_ln(int32 ln); +const char *com_description(DEVICE *dptr); /* device description */ + +/* COM data structures + com_chp COM channel program information + com_dev COM device descriptor + com_unit COM unit descriptor + com_reg COM register list + com_mod COM modifiers list +*/ + +//#define COM_UNITS 2 +#define COM_UNITS 1 + +/* channel program information */ +CHANP com_chp[COM_UNITS] = {0}; + +/* dummy mux for 16 lines */ +MTAB com_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, &show_dev_addr, NULL}, + {MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT", &tmxr_dscln, NULL, &com_desc}, + {UNIT_ATT, UNIT_ATT, "SUMMARY", NULL, NULL, &tmxr_show_summ, (void *) &com_desc}, + {MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL, NULL, &tmxr_show_cstat,(void *)&com_desc}, + {MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL, NULL, &tmxr_show_cstat, (void *)&com_desc}, + { 0 } +}; + +UNIT com_unit[] = { + {UDATA(&comc_srv, UNIT_ATTABLE|UNIT_IDLE, 0), COM_WAIT, UNIT_ADDR(0x0000)}, /* 0 */ +}; + +DIB com_dib = { + NULL, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + NULL, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + NULL, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + com_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + com_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + com_unit, /* UNIT* units */ /* Pointer to units structure */ + com_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + COM_UNITS, /* uint8 numunits */ /* number of units defined */ + 0x0f, /* uint8 mask */ /* 16 devices - device mask */ + 0x7E00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +REG com_reg[] = { + { BRDATAD (STA, com_stat, 16, 8, COM_LINES, "status buffers, lines 0 to 7") }, + { BRDATAD (RBUF, com_rbuf, 16, 8, COM_LINES, "input buffer, lines 0 to 7") }, + { BRDATAD (XBUF, com_xbuf, 16, 8, COM_LINES, "output buffer, lines 0 to 7") }, + { NULL } + }; + +/* devices for channel 0x7ecx */ +DEVICE com_dev = { + "COMC", com_unit, com_reg, com_mod, + COM_UNITS, 8, 15, 1, 8, 8, + &tmxr_ex, &tmxr_dep, &com_reset, NULL, &com_attach, &com_detach, + /* ctxt is the DIB pointer */ + &com_dib, DEV_MUX|DEV_DISABLE|DEV_DEBUG, 0, dev_debug, + NULL, NULL, NULL, NULL, NULL, &com_description +}; + +/* COML data structures + coml_dev COM device descriptor + coml_unit COM unit descriptor + coml_reg COM register list + coml_mod COM modifiers list +*/ + +/*#define UNIT_COML UNIT_ATTABLE|UNIT_DISABLE|UNIT_IDLE */ +//#define UNIT_COML UNIT_IDLE|UNIT_DISABLE|TT_MODE_UC +//#define UNIT_COML UNIT_IDLE|UNIT_DISABLE|TT_MODE_7P +//#define UNIT_COML UNIT_IDLE|UNIT_DISABLE|TT_MODE_8B +#define UNIT_COML UNIT_IDLE|UNIT_DISABLE|TT_MODE_7B + +/* channel program information */ +CHANP coml_chp[COM_LINES*2] = {0}; + +UNIT coml_unit[] = { + /* 0-7 is input, 8-f is output */ + {UDATA(&comi_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA0)}, /* 0 */ + {UDATA(&comi_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA1)}, /* 1 */ + {UDATA(&comi_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA2)}, /* 2 */ + {UDATA(&comi_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA3)}, /* 3 */ + {UDATA(&comi_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA4)}, /* 4 */ + {UDATA(&comi_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA5)}, /* 5 */ + {UDATA(&comi_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA6)}, /* 6 */ + {UDATA(&comi_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA7)}, /* 7 */ + {UDATA(&como_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA8)}, /* 8 */ + {UDATA(&como_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EA9)}, /* 9 */ + {UDATA(&como_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EAA)}, /* A */ + {UDATA(&como_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EAB)}, /* B */ + {UDATA(&como_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EAC)}, /* C */ + {UDATA(&como_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EAD)}, /* D */ + {UDATA(&como_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EAE)}, /* E */ + {UDATA(&como_srv, UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EAF)}, /* F */ +}; + +DIB coml_dib = { + coml_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + coml_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + coml_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + coml_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + coml_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + coml_unit, /* UNIT* units */ /* Pointer to units structure */ + coml_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + COM_LINES*2, /* uint8 numunits */ /* number of units defined */ + 0x0f, /* uint8 mask */ /* 16 devices - device mask */ + 0x7E00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +REG coml_reg[] = { + { URDATA (TIME, coml_unit[0].wait, 10, 24, 0, COM_LINES, REG_NZ + PV_LEFT) }, + { NULL } +}; + +MTAB coml_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, &show_dev_addr, NULL}, + { TT_MODE, TT_MODE_UC, "UC", "UC", NULL }, + { TT_MODE, TT_MODE_7B, "7b", "7B", NULL }, + { TT_MODE, TT_MODE_8B, "8b", "8B", NULL }, + { TT_MODE, TT_MODE_7P, "7p", "7P", NULL }, + { MTAB_XTD|MTAB_VUN, 0, NULL, "DISCONNECT", + &tmxr_dscln, NULL, &com_desc }, + { MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG", + &tmxr_set_log, &tmxr_show_log, &com_desc }, + { MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG", + &tmxr_set_nolog, NULL, &com_desc }, + { 0 } + }; + +DEVICE coml_dev = { + "COML", coml_unit, coml_reg, coml_mod, + COM_LINES*2, 10, 31, 1, 8, 8, + NULL, NULL, &com_reset, + NULL, NULL, NULL, + /* ctxt is the DIB pointer */ + &coml_dib, DEV_DISABLE|DEV_DEBUG, 0, dev_debug, + NULL, NULL, NULL, NULL, NULL, &com_description +}; + +/* 8-line serial routines */ +void coml_ini(UNIT *uptr, t_bool f) +{ + /* set SNS_RLSDS SNS_DSRS SNS_CTSS SNS_RTS SNS_CTS */ + uptr->SNS = 0x0000b003; /* status is online & ready */ + uptr->CMD &= LMASK; /* leave only chsa */ + sim_cancel(uptr); /* stop any timer */ +} + +/* handle rschnlio cmds for coml */ +t_stat coml_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & COM_MSK; + + sim_debug(DEBUG_EXP, dptr, + "coml_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + coml_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +/* 8-line serial routines */ +void com_ini(UNIT *uptr, t_bool f) +{ + DEVICE *dptr = get_dev(uptr); + + sim_debug(DEBUG_CMD, dptr, + "COM init device %s controller 0x7e00\n", dptr->name); + sim_cancel(uptr); /* stop input poll */ + sim_activate(uptr, 1000); /* start input poll */ +} + +/* handle rschnlio cmds for com */ +t_stat com_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & COM_MSK; + + sim_debug(DEBUG_EXP, dptr, + "com_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + com_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +/* start a com operation */ +t_stat coml_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + uint16 chsa = GET_UADDR(uptr->CMD); /* get channel/sub-addr */ + UNIT *ruptr = &dptr->units[unit&7]; /* read uptr */ + UNIT *wuptr = &dptr->units[(unit&7)+8]; /* write uptr */ + + sim_debug(DEBUG_CMD, dptr, + "coml_preio CMD %08x unit %02x chsa %04x\n", + uptr->CMD, unit, chsa); + sim_debug(DEBUG_CMD, dptr, + "coml_preio chsa %04x ln %1x conn %x rcve %x xmte %x SNS %08x SNS %08x\n", + chsa, unit, com_ldsc[unit&7].conn, com_ldsc[unit&7].rcve, + com_ldsc[unit&7].xmte, ruptr->SNS, wuptr->SNS); + + if ((uptr->CMD & COM_MSK) != 0) { /* just return if busy */ + sim_debug(DEBUG_CMD, dptr, + "coml_preio unit %02x chsa %04x BUSY\n", unit, chsa); + return SNS_BSY; + } + + sim_debug(DEBUG_CMD, dptr, + "coml_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + +/* called from sel32_chan to start an I/O operation */ +t_stat coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); +// int unit = (uptr - dptr->units) & 0x7; /* make 0-7 */ + UNIT *ruptr = &dptr->units[unit&7]; /* read uptr */ + UNIT *wuptr = &dptr->units[(unit&7)+8]; /* write uptr */ + uint16 chsa = (((uptr->CMD & LMASK) >> 16) | (chan << 8)); + uint8 ch, fcb[3]; + + if ((uptr->CMD & COM_MSK) != 0) { /* is unit busy */ + return SNS_BSY; /* yes, return busy */ + } + + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x line %1x cmd %02x conn %x rcve %x xmte %x SNS %08x SNS %08x\n", + chsa, unit, cmd, com_ldsc[unit&7].conn, com_ldsc[unit&7].rcve, + com_ldsc[unit&7].xmte, ruptr->SNS, wuptr->SNS); + + uptr->CMD &= LMASK; /* clear any flags that are set */ + /* process the commands */ + switch (cmd & 0xFF) { + case COM_INCH: /* 00 */ /* INCH command */ + sim_debug(DEBUG_CMD, dptr, "coml_startcmd chsa %04x: CMD INCH\n", chsa); + uptr->CMD &= LMASK; /* leave only chsa */ + uptr->CMD |= (0x7f & COM_MSK); /* save 0x7f as INCH cmd command */ + uptr->SNS |= SNS_RDY; /* status is online & ready */ + sim_activate(uptr, 500); /* start us up */ + break; + + /* write commands must use address 8-f */ + case COM_WR: /* 0x01 */ /* Write command */ + case COM_WRSCM: /* 0x05 */ /* Write w/ input sub channel monitor */ + case COM_WRHFC: /* 0x0D */ /* Write w/hardware flow control only */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd WRITE %02x\n", chsa, cmd); + + /* see if DSR is set, if not give unit check error */ + if (((ruptr->SNS & SNS_DSRS) == 0) || ((ruptr->SNS & SNS_CONN) == 0)) { +//YY if ((com_ldsc[unit&7].conn == 0) || + ruptr->SNS &= ~SNS_RDY; /* status is not ready */ + wuptr->SNS &= ~SNS_RDY; /* status is not ready */ + ruptr->SNS |= SNS_CMDREJ; /* command reject */ + wuptr->SNS |= SNS_CMDREJ; /* command reject */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd WRITE %02x unit check\n", chsa, cmd); + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + uptr->CMD &= LMASK; /* leave only chsa */ + uptr->CMD |= (cmd & COM_MSK); /* save command */ + uptr->SNS |= SNS_RDY; /* status is online & ready */ + sim_activate(uptr, 250); /* TRY 08-13-18 */ + return 0; /* no status change */ + break; + + /* read commands must use address 0-7 */ + /* DSR must be set when a read command is issued, else it is unit check */ + /* bit 1-3 (ASP) of command has more definition */ + /* bit 1 A=1 ASCII control character detect (7-char mode only) */ + /* bit 2 S=1 Special character detect (7-char mode only) */ + /* bit 3 P=1 Purge input buffer */ + case COM_RD: /* 0x02 */ /* Read command */ + case 0x22: /* 0x22 */ /* Read command w/ASCII CC */ + case 0x32: /* 0x32 */ /* Read command w/ASCII CC & Purge input */ + case COM_RDECHO: /* 0x06 */ /* Read command w/ECHO */ + case 0x46: /* 0x46 */ /* Read command w/ECHO & ASCII CC*/ + case 0x56: /* 0x56 */ /* Read command w/ECHO & ASCII CC & Purge input */ + /* if bit 0 set for COM_RDFC, use DTR for flow, else use RTS for flow control */ + case COM_RDFC: /* 0x0A */ /* Read command w/flow control */ + case COM_RDHFC: /* 0x8E */ /* Read command w/hardware flow control only */ + + /* see if DSR is set, if not give unit check error */ + if (((ruptr->SNS & SNS_DSRS) == 0) || ((ruptr->SNS & SNS_CONN) == 0)) { +//XX if (com_ldsc[unit&7].conn == 0) { + ruptr->SNS &= ~SNS_RDY; /* status is not ready */ + wuptr->SNS &= ~SNS_RDY; /* status is not ready */ + ruptr->SNS |= SNS_CMDREJ; /* command reject */ + wuptr->SNS |= SNS_CMDREJ; /* command reject */ + /* SNS_DSRS will be 0 */ +/*UTX*/ ruptr->SNS |= SNS_DELDSR; /* set attention status */ +/*UTX*/ wuptr->SNS |= SNS_DELDSR; /* set attention status */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd READ %02x unit check\n", chsa, cmd); + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + unit &= 0x7; /* make unit 0-7 */ + uptr->CMD &= ~COM_EKO; /* clear echo status */ + sim_debug(DEBUG_CMD, dptr, "coml_startcmd chsa %04x: Cmd read\n", chsa); + uptr->CMD &= LMASK; /* leave only chsa */ + uptr->CMD |= (cmd & COM_MSK); /* save command */ + if ((cmd & 0x0f) == COM_RDECHO) /* echo command? */ + uptr->CMD |= COM_EKO; /* save echo status */ + if (cmd & 0x10) { /* purge input request? */ + uptr->CNT = 0; /* no input count */ + com_data[unit].incnt = 0; /* no input data */ + com_rbuf[unit&7] = 0; /* clear read buffer */ + } + uptr->CMD |= COM_READ; /* show read mode */ + uptr->SNS |= SNS_RDY; /* status is online & ready */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: input cnt = %04x\n", + chsa, coml_chp[unit].ccw_count); + sim_activate(uptr, 250); /* TRY 08-13-18 */ + return 0; + break; + + case COM_NOP: /* 0x03 */ /* NOP has do nothing */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x NOP\n", chsa, cmd); + uptr->SNS |= SNS_RDY; /* status is online & ready */ + uptr->CMD &= LMASK; /* leave only chsa */ + uptr->CMD |= (cmd & COM_MSK); /* save command */ + sim_activate(uptr, 250); /* start us up */ + break; + + case COM_SNS: /* 0x04 */ /* Sense (8 bytes) */ + unit &= 0x7; /* make unit 0-7 */ + /* status is in SNS (u5) */ + /* ACE is in ACE (u4) */ +///*MPX*/ uptr->SNS = 0x03813401; + + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd SENSE chsa %04x: unit %02x Cmd Sense SNS %08x ACE %08x\n", + chsa, unit, uptr->SNS, uptr->ACE); + + /* byte 0 device status */ + ch = (uptr->SNS >> 24) & 0xff; /* no bits in byte 0 */ + chan_write_byte(chsa, &ch); /* write status */ + + /* byte 1 line status and error conditions */ + ch = (uptr->SNS >> 16) & 0xff; /* no bits in byte 1 */ + chan_write_byte(chsa, &ch); /* write status */ + + /* byte 2 modem status */ + // SNS_DELDSR will be set if just connected, clear at end + ch = (uptr->SNS >> 8) & 0xff; /* CTS & DSR bits in byte 2 */ + chan_write_byte(chsa, &ch); /* write status */ + + /* byte 3 modem control/operation mode */ + ch = uptr->SNS & 0xff; /* maybe DTR bit in byte 3 */ + chan_write_byte(chsa, &ch); /* write status */ + + /* byte 4 ACE byte 0 parameters (parity, stop bits, char len */ + ch = (uptr->ACE >> 24) & 0xff; /* ACE byte 0 */ + chan_write_byte(chsa, &ch); /* write status */ + + /* byte 5 ACE byte 1 parameters (baud rate) */ + ch = (uptr->ACE >> 16) & 0xff; /* ACE byte 1 */ + chan_write_byte(chsa, &ch); /* write status */ + + /* byte 6 ACE parameters (Firmware ID 0x62) */ + ch = 0x62; /* ACE IOP firmware byte 0 */ +// ch = 0x19; /* ACE MFP firmware byte 0 */ + chan_write_byte(chsa, &ch); /* write status */ + + /* byte 7 ACE parameters (Revision Level 0x4?) */ +// Firmware 0x44 supports RTS flow control */ +// Firmware 0x45 supports DCD modem control */ +// ch = 0x44; /* ACE firmware byte 1 */ +// ch = 0x45; /* ACE firmware byte 1 */ + ch = 0x43; /* ACE firmware byte 1 */ +// ch = 0x40; /* ACE firmware byte 1 */ + chan_write_byte(chsa, &ch); /* write status */ + + ruptr->SNS &= ~SNS_RING; /* reset ring attention status */ + ruptr->SNS &= ~SNS_MRING; /* reset ring attention status */ + ruptr->SNS &= ~SNS_ASCIICD; /* reset ASCII attention status */ + ruptr->SNS &= ~SNS_DELDSR; /* reset attention status */ +//MPX ruptr->SNS &= ~SNS_RLSDS; /* reset rec'd line signal detect */ + ruptr->SNS &= ~SNS_CMDREJ; /* command reject */ +/*MPX*/ ruptr->SNS &= ~SNS_DELTA; /* reset attention status */ + + wuptr->SNS &= ~SNS_RING; /* reset ring attention status */ + wuptr->SNS &= ~SNS_MRING; /* reset ring attention status */ + wuptr->SNS &= ~SNS_ASCIICD; /* reset ASCII attention status */ + wuptr->SNS &= ~SNS_DELDSR; /* reset attention status */ +//1X wuptr->SNS &= ~SNS_RLSDS; /* reset rec'd line signal detect */ + wuptr->SNS &= ~SNS_CMDREJ; /* command reject */ +/*MPX*/ wuptr->SNS &= ~SNS_DELTA; /* reset attention status */ + + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd CMD SENSE return chsa %04x: unit %02x Cmd Sense SNS %08x ACE %08x\n", + chsa, unit, uptr->SNS, uptr->ACE); + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + case COM_DEFSC: /* 0x0B */ /* Define special char */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x DEFSC\n", chsa, cmd); + if (chan_read_byte(GET_UADDR(uptr->CMD), &ch)) { /* read char from memory */ + /* nothing to read, error */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + uptr->ACE &= ~ACE_WAKE; /* clear out old wake char */ + uptr->ACE |= ((uint32)ch << 8); /* insert special char */ + ruptr->ACE = uptr->ACE; /* set special char in read unit */ + wuptr->ACE = uptr->ACE; /* set special char in write unit */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x DEFSC char %02x SNS %08x ACE %08x\n", + chsa, cmd, ch, uptr->SNS, uptr->ACE); + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + case COM_RRTS: /* 0x1B */ /* Reset RTS */ + sim_debug(DEBUG_CMD, dptr, "coml_startcmd chsa %04x: Cmd %02x RRTS\n", chsa, cmd); + uptr->SNS &= ~SNS_RTS; /* Request to send not ready */ + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + case COM_SRTS: /* 0x1F */ /* Set RTS */ + sim_debug(DEBUG_CMD, dptr, "coml_startcmd chsa %04x: Cmd %02x SRTS\n", chsa, cmd); + uptr->SNS |= SNS_RTS; /* Request to send ready */ + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + case COM_RBRK: /* 0x33 */ /* Reset BREAK */ + sim_debug(DEBUG_CMD, dptr, "coml_startcmd chsa %04x: Cmd %02x RBRK\n", chsa, cmd); + uptr->SNS &= ~SNS_BREAK; /* Request to send not ready */ + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + case COM_SBRK: /* 0x37 */ /* Set BREAK */ + sim_debug(DEBUG_CMD, dptr, "coml_startcmd chsa %04x: Cmd %02x SBRK\n", chsa, cmd); + uptr->SNS |= SNS_BREAK; /* Requestd to send ready */ + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + case COM_RDTR: /* 0x13 */ /* Reset DTR (ADVR) */ + sim_debug(DEBUG_CMD, dptr, "coml_startcmd chsa %04x: Cmd %02x RDTR\n", chsa, cmd); + uptr->SNS &= ~SNS_DTR; /* Data terminal not ready */ + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + case COM_SDTR: /* 0x17 */ /* Set DTR (ADVF) */ + sim_debug(DEBUG_CMD, dptr, "coml_startcmd chsa %04x: Cmd %02x SDTR\n", chsa, cmd); + uptr->SNS |= SNS_DTR; /* Data terminal ready */ + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + case COM_SACE: /* 0xff */ /* Set ACE parameters (3 chars) */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x SACE\n", chsa, cmd); + + if (chan_read_byte(GET_UADDR(uptr->CMD), &ch)) { /* read char 0 */ + /* nothing to read, error */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + uptr->ACE = ((uint32)ch)<<24; /* byte 0 of ACE data */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x ACE byte 0 %02x\n", + chsa, cmd, ch); + + if (chan_read_byte(GET_UADDR(uptr->CMD), &ch)) { /* read char 1 */ + /* nothing to read, error */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + uptr->ACE |= ((uint32)ch)<<16; /* byte 1 of ACE data */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x ACE byte 1 %02x\n", + chsa, cmd, ch); + + if (chan_read_byte(GET_UADDR(uptr->CMD), &ch)) { /* read char 2 */ + /* nothing to read, error */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + uptr->ACE |= ((uint32)ch)<<8; /* byte 2 of ACE data */ + uptr->SNS |= SNS_ACEDEF; /* show ACE defined */ + if (uptr->SNS & SNS_CONN) { + if (!(uptr->ACE & SNS_MRINGE)) { /* see if RING enabled */ + uptr->SNS |= (SNS_DTR | SNS_RTS); /* set DTR & DSR if yes */ + } + } + ruptr->SNS |= SNS_RDY; /* status is online & ready */ + if (uptr == wuptr) { + ruptr->ACE = uptr->ACE; /* set ACE in read uptr */ + ruptr->SNS = uptr->SNS; /* set status to read uptr */ + } else { + wuptr->ACE = uptr->ACE; /* set ACE in write uptr */ + wuptr->SNS = uptr->SNS; /* set status to write uptr */ + } + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x ACE byte 2 %02x\n", + chsa, cmd, ch); + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd ACE DONE chsa %04x: Cmd %02x ACE bytes %08x\n", + chsa, cmd, uptr->ACE); + + uptr->CMD &= LMASK; /* nothing left, command complete */ + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + + /* Set transparent flow control mode */ + case COM_SETFLOW: /* 0x53 */ /* Set flow control (3 chars) */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x SETFLOW\n", chsa, cmd); + + if (chan_read_byte(GET_UADDR(uptr->CMD), &ch)) { /* read char 0 */ + /* nothing to read, error */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + fcb[0] = ch; /* byte 0 of Flow Cont data */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x SETFLOW byte 0 %02x\n", + chsa, cmd, ch); + + if (chan_read_byte(GET_UADDR(uptr->CMD), &ch)) { /* read char 1 */ + /* nothing to read, error */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + fcb[1] = ch; /* byte 1 of Flow Cont data */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x SETFLOW byte 1 %02x\n", + chsa, cmd, ch); + + if (chan_read_byte(GET_UADDR(uptr->CMD), &ch)) { /* read char 2 */ + /* nothing to read, error */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ + } + fcb[2] = ch; /* byte 2 of Flow Cont data */ + ruptr->SNS |= SNS_RDY; /* status is online & ready */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd %02x SETFLOW byte 2 %02x\n", + chsa, cmd, ch); + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd SETFLOW DONE chsa %04x: Cmd %02x FCB bytes %02x%02x%02x\n", + chsa, cmd, fcb[0], fcb[1], fcb[2]); + + uptr->CMD &= LMASK; /* nothing left, command complete */ + return SNS_CHNEND|SNS_DEVEND; /* good return */ + break; + default: /* invalid command */ + uptr->SNS |= SNS_CMDREJ; /* command rejected */ + sim_debug(DEBUG_CMD, dptr, + "coml_startcmd chsa %04x: Cmd Invalid %02x status %02x\n", + chsa, cmd, uptr->u5); + return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* program check */ + break; + } + + if (uptr->u5 & 0xff) + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; + return SNS_CHNEND|SNS_DEVEND; +} + +/* Unit service - polled input + Poll for new connections + Poll all connected lines for input +*/ +t_stat comc_srv(UNIT *uptr) +{ + uint8 ch; + DEVICE *dptr = get_dev(uptr); + int32 newln, ln, c; +// int cmd = uptr->CMD & 0xff; + uint16 chsa = GET_UADDR(coml_unit[0].CMD); /* get channel/sub-addr */ + + /* see if comc attached */ + if ((com_unit[COMC].flags & UNIT_ATT) == 0){ /* attached? */ + return SCPE_OK; + } + /* poll for any input from com lines, units 0-7 */ + newln = tmxr_poll_conn(&com_desc); /* look for connect */ + if (newln >= 0) { /* rcv enb pending? */ + uint16 chsa = GET_UADDR(coml_unit[newln].CMD); /* get read channel/sub-addr */ + uint16 wchsa = GET_UADDR(coml_unit[newln+8].CMD); /* get write channel/sub-addr */ + UNIT *nuptr = coml_unit+newln; /* get uptr for coml line */ + UNIT *wuptr = coml_unit+newln+8; /* get output uptr for coml line */ + com_ldsc[newln].rcve = 1; /* enable rcv */ + com_ldsc[newln].xmte = 1; /* enable xmt for output line */ + com_stat[newln] |= COML_RBP; /* connected */ + com_stat[newln] &= ~COML_REP; /* not pending */ + + sim_debug(DEBUG_CMD, &com_dev, + "comc_srv conn b4 wakeup on read chsa %04x line %02x SNS %08x ACE %08x\n", + chsa, newln, nuptr->SNS, nuptr->ACE); + sim_debug(DEBUG_CMD, &com_dev, + "comc_srv conn b4 wakeup on write chsa %04x line %02x SNS %08x ACE %08x\n", + wchsa, newln+8, wuptr->SNS, wuptr->ACE); + + /* send attention to OS here for this channel */ + /* set DSR, CTS and delta DSR status */ + nuptr->SNS |= SNS_CONN; /* status is now connected */ + /* UTX says this is an error if set, so do not set SNS_DELDSR */ +/*MPX*/ nuptr->SNS |= (SNS_DSRS | SNS_CTSS | SNS_RING); /* set the read bits */ + nuptr->SNS |= (SNS_RTS | SNS_DTR); /* set RTS & DTR */ +/*MPX*/ nuptr->SNS |= SNS_MRING; /* set RING interrupt */ + if (nuptr->SNS & SNS_ACEDEF) { /* ACE defined */ + /* this must be set to login for UTX after system is up */ +/*UTX*/ nuptr->SNS |= SNS_DELDSR; /* set delta dsr status */ + nuptr->SNS |= SNS_RLSDS; /* set rec'd line signal detect */ + } else { + nuptr->SNS |= SNS_DELDSR; /* set delta dsr status */ + nuptr->SNS |= SNS_RLSDS; /* set rec'd line signal detect */ + } + nuptr->SNS &= ~SNS_CMDREJ; /* no command reject */ + wuptr->SNS = nuptr->SNS; /* set write line too */ + wuptr->ACE = nuptr->ACE; /* set write line too */ + sim_debug(DEBUG_CMD, &com_dev, + "comc_srv conn wakeup on chsa %04x line %02x SNS %08x ACE %08x\n", + chsa, newln, nuptr->SNS, nuptr->ACE); + set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); /* tell user */ + } + /* poll all devices for input */ + tmxr_poll_rx(&com_desc); /* poll for input */ + for (ln = 0; ln < COM_NUMLIN; ln++) { /* loop thru lines */ + UNIT *nuptr = coml_unit+ln; /* get uptr for coml line */ + int cmd = nuptr->CMD & 0xff; /* get the active cmd */ + uint16 chsa = GET_UADDR(nuptr->CMD); /* get channel/sub-addr */ + + if (com_ldsc[ln].conn) /* connected? */ + sim_debug(DEBUG_CMD, &com_dev, + "comc_srv conn poll input chsa %04x line %02x SNS %08x ACE %08x\n", + chsa, ln, nuptr->SNS, nuptr->ACE); + + if ((com_ldsc[ln].conn) && /* connected? */ + (c = tmxr_getc_ln(&com_ldsc[ln]))) { /* get char */ + ch = c & 0x7f; + if (ch == '\n') /* convert newline */ + ch = '\r'; /* to C/R */ + sim_debug(DEBUG_CMD, &com_dev, + "comc_srv read %02x (%02x) chsa %04x line %02x SNS %08x ACE %08x CMD %08x\n", + c, ch, chsa, ln, nuptr->SNS, nuptr->ACE, nuptr->CMD); + /* tmxr says break is 0x80??, but SCPE_BREAK is 0x800000?? */ + if (c & SCPE_BREAK) { /* break? */ + nuptr->SNS |= SNS_BREAK; /* set received break bit */ + com_stat[ln] |= COML_RBP; /* set rcv brk */ + set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); + continue; + } + /* normal char */ + nuptr->SNS &= ~SNS_BREAK; /* reset received break bit */ + com_stat[ln] &= ~COML_RBP; /* clr rcv brk */ + + /* convert to user requested input */ + ch = sim_tt_inpcvt(ch, TT_GET_MODE(coml_unit[ln].flags)); + com_rbuf[ln] = ch; /* save char */ + + /* Special char detect? */ + if ((ch & 0x7f) == ((nuptr->ACE >> 8) & 0xff)) { /* is it spec char */ + nuptr->CMD |= COM_SCD; /* set special char detected */ + nuptr->SNS |= SNS_SPCLCD; /* set special char detected */ +// nuptr->SNS |= SNS_RLSDS; /* set rec'd line signal detect */ + nuptr->SNS |= SNS_RING; /* set ring attention status */ + sim_debug(DEBUG_CMD, &com_dev, + "comc_srv user ACE wakeup on chsa %04x line %02x cmd %02x SNS %08x ACE %08x\n", + chsa, ln, cmd, nuptr->SNS, nuptr->ACE); + set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); + continue; + } + + /* put char in buffer */ + com_data[ln].ibuff[com_data[ln].incnt++] = ch; + + /* see if at max, if so reset to start */ + if (com_data[ln].incnt >= sizeof(com_data[ln].ibuff)) + com_data[ln].incnt = 0; /* reset buffer cnt */ + + nuptr->CMD |= COM_INPUT; /* we have a char available */ + sim_debug(DEBUG_CMD, dptr, + "comc_srv readch ln %02x: CMD %08x read %02x CNT %02x incnt %02x c %04x\n", + ln, nuptr->CMD, ch, nuptr->CNT, com_data[ln].incnt, c); + } + else /* end if conn */ + /* if we were connected and not now, reset serial line */ + if ((nuptr->SNS & SNS_CONN) && (com_ldsc[ln].conn == 0)) { + UNIT *wuptr = coml_unit+ln+8; /* get output uptr for coml line */ + sim_debug(DEBUG_CMD, &com_dev, + "comc_srv disconnect on chsa %04x line %02x cmd %02x SNS %08x ACE %08x\n", + chsa, ln, cmd, nuptr->SNS, nuptr->ACE); + com_ldsc[ln].rcve = 0; /* disable rcv */ + com_ldsc[ln].xmte = 0; /* disable xmt for output line */ + com_stat[ln] &= ~COML_RBP; /* disconnected */ + com_stat[ln] |= COML_REP; /* set pending */ + nuptr->SNS &= ~(SNS_RTS | SNS_DTR); /* reset RTS & DTR */ + nuptr->SNS &= ~(SNS_DSRS); /* status is not connected */ + nuptr->SNS |= (SNS_DELDSR); /* status is not connected */ + nuptr->SNS |= (SNS_DELTA); /* status is not connected */ + nuptr->SNS &= ~(SNS_RDY|SNS_CONN); /* status is not connected */ + wuptr->SNS = nuptr->SNS; /* set write channel too */ + set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); + } + } /* end for */ + + sim_debug(DEBUG_DETAIL, &com_dev, + "comc_srv POLL DONE on chsa %04x\n", chsa); + /* this says to use 200, but simh really uses 50000 for cnt */ + /* changed 12/02/2021 from 200 to 5000 */ +// return sim_clock_coschedule(uptr, 200); /* continue poll */ + return sim_clock_coschedule(uptr, 5000); /* continue poll */ +// return sim_activate(uptr, 10000); /* continue poll */ +// return sim_activate(uptr, 5000); /* continue poll */ +} + +/* Unit service - input transfers */ +t_stat comi_srv(UNIT *uptr) +{ + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); /* get channel/sub-addr */ + uint32 ln = (uptr - coml_unit) & 0x7; /* use line # 0-7 for 8-15 */ + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + int cmd = uptr->CMD & 0xff; /* get active cmd */ + uint8 ch, cc; + + /* handle NOP and INCH cmds */ + sim_debug(DEBUG_CMD, dptr, + "comi_srv entry chsa %04x line %04x cmd %02x conn %x rcve %x xmte %x SNS %08x\n", + chsa, ln, cmd, com_ldsc[ln].conn, com_ldsc[ln].rcve, com_ldsc[ln].xmte, uptr->SNS); + + if (com_ldsc[ln].conn) { /* connected? */ + if ((uptr->CNT != com_data[ln].incnt) || /* input empty */ + (uptr->CMD & COM_INPUT)) { /* input waiting? */ + ch = com_data[ln].ibuff[uptr->CNT]; /* get char from read buffer */ + sim_debug(DEBUG_CMD, dptr, + "com_srvi readbuf unit %02x: CMD %08x read %02x incnt %02x CNT %02x len %02x\n", + ln, uptr->CMD, ch, com_data[ln].incnt, uptr->CNT, chp->ccw_count); + + if (uptr->CNT != com_data[ln].incnt) { /* input available */ + /* process any characters */ + /* this fixes mpx1x time entry on startup */ + if (uptr->CMD & COM_EKO) { /* ECHO requested */ + /* echo the char out */ + /* convert to user requested output */ + sim_debug(DEBUG_CMD, &com_dev, + "comi_srv echo char %02x on chsa %04x line %02x cmd %02x ACE %08x\n", + ch, chsa, ln, cmd, uptr->ACE); +// cc = sim_tt_outcvt(c, TT_GET_MODE(coml_unit[ln].flags)); + tmxr_putc_ln(&com_ldsc[ln], ch); /* output char */ + tmxr_poll_tx(&com_desc); /* poll xmt to send */ + } + if (chan_write_byte(chsa, &ch)) { /* write byte to memory */ + /* write error */ + cmd = 0; /* no cmd now */ + sim_debug(DEBUG_CMD, dptr, + "comi_srv write error ln %02x: CMD %08x read %02x CNT %02x ccw_count %02x\n", + ln, uptr->CMD, ch, uptr->CNT, chp->ccw_count); + uptr->CMD &= ~COM_MSK; /* remove old CMD */ + uptr->CMD &= ~COM_INPUT; /* input waiting? */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + return SCPE_OK; + } + /* character accepted, bump buffer pointer */ + uptr->CNT++; /* next char position */ + + sim_debug(DEBUG_CMD, dptr, + "comi_srv write to mem line %02x: CMD %08x read %02x CNT %02x incnt %02x\n", + ln, uptr->CMD, ch, uptr->CNT, com_data[ln].incnt); + + /* see if at end of buffer */ + if (uptr->CNT >= (int32)sizeof(com_data[ln].ibuff)) + uptr->CNT = 0; /* reset pointer */ + + cc = ch & 0x7f; /* clear parity bit */ + /* Special char detected? (7 bit read only) */ + if (cc == ((uptr->ACE >> 8) & 0xff)) { /* is it spec char */ +// uptr->CMD |= COM_SCD; /* set special char detected */ + uptr->SNS |= SNS_SPCLCD; /* set special char detected */ + sim_debug(DEBUG_CMD, &com_dev, + "comi_srv user ACE %02x wakeup on chsa %04x line %02x cmd %02x ACE %08x\n", + cc, chsa, ln, cmd, uptr->ACE); + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, dptr, + "comi_srv read done chsa %04x ln %04x: chnend|devend\n", chsa, ln); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; + } + + /* ASCII control char (7 bit read only) */ + /* see if control char detected */ + if (uptr->CMD & 0x40) { /* is ASCII ctrl char test bit set */ + if (((cc & 0x60) == 0) || (cc == 0x7f)) { + uptr->SNS |= SNS_ASCIICD; /* ASCII ctrl char detected */ + sim_debug(DEBUG_CMD, &com_dev, + "comi_srv user ASCII %02x wakeup on chsa %04x line %02x cmd %02x ACE %08x\n", + cc, chsa, ln, cmd, uptr->ACE); + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, dptr, + "comi_srv read CC done chsa %04x ln %04x: chnend|devend\n", chsa, ln); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; + } + } + + /* user want more data? */ + if ((test_write_byte_end(chsa)) == 0) { + sim_debug(DEBUG_CMD, dptr, + "comi_srv need more line %02x CMD %08x CNT %02x ccw_count %02x incnt %02x\n", + ln, uptr->CMD, uptr->CNT, chp->ccw_count, com_data[ln].incnt); + /* user wants more, look next time */ + if (uptr->CNT == com_data[ln].incnt) { /* input empty */ + uptr->CMD &= ~COM_INPUT; /* no input available */ + } +/* change 02DEC21*/ sim_activate(uptr, uptr->wait); /* wait */ +// change 02DEC21*/ sim_clock_coschedule(uptr, 1000); /* continue poll */ + return SCPE_OK; + } + /* command is completed */ + sim_debug(DEBUG_CMD, dptr, + "comi_srv read done line %02x CMD %08x read %02x CNT %02x ccw_count %02x incnt %02x\n", + ln, uptr->CMD, ch, uptr->CNT, chp->ccw_count, com_data[ln].incnt); + uptr->CMD &= LMASK; /* nothing left, command complete */ + if (uptr->CNT != com_data[ln].incnt) { /* input empty */ + uptr->CMD |= COM_INPUT; /* input still available */ + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + } + } +// change 02DEC21 sim_activate(uptr, uptr->wait); /* wait */ +/* change 02DEC21*/ sim_clock_coschedule(uptr, 1000); /* continue poll */ + return SCPE_OK; + } + /* not connected, so dump chars on ground */ + uptr->CNT = 0; /* no input count */ + com_data[ln].incnt = 0; /* no input data */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + uptr->SNS |= 0x00003003; /* status is online & ready */ + uptr->SNS &= SNS_DSRS; /* reset DSR */ + uptr->SNS |= SNS_DELDSR; /* give change status */ + uptr->SNS |= SNS_MRING; /* give RING status */ + sim_debug(DEBUG_CMD, dptr, + "comi_srv read dump DONE line %04x status %04x cmd %02x SNS %08x\n", + ln, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK, cmd, uptr->SNS); + /* if line active, abort cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* error return */ + return SCPE_OK; +} + +/* Unit service - output transfers */ +t_stat como_srv(UNIT *uptr) +{ + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); /* get channel/sub-addr */ + uint32 ln = (uptr - coml_unit) & 0x7; /* use line # 0-7 for 8-15 */ + UNIT *ruptr = &dptr->units[ln&7]; /* read uptr */ + uint32 done; + int cmd = uptr->CMD & 0xff; /* get active cmd */ + uint8 ch; + + sim_debug(DEBUG_CMD, dptr, + "como_srv entry chsa %04x line %04x cmd %02x conn %x rcve %x xmte %x\n", + chsa, ln, cmd, com_ldsc[ln].conn, com_ldsc[ln].rcve, com_ldsc[ln].xmte); + + if (com_dev.flags & DEV_DIS) { /* disabled */ + sim_debug(DEBUG_CMD, dptr, + "como_srv chsa %04x line %02x SNS %08x DEV_DIS set\n", chsa, ln, uptr->SNS); + sim_debug(DEBUG_CMD, dptr, + "como_srv Write forced DONE %04x status %04x\n", + ln, SNS_CHNEND|SNS_DEVEND); + uptr->CMD &= LMASK; /* nothing left, command complete */ + ruptr->SNS &= SNS_DSRS; /* reset DSR */ + ruptr->SNS |= SNS_DELDSR; /* give change status */ +// chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* error return */ + return SCPE_OK; /* return */ + } + + /* handle NOP and INCH cmds */ + if (cmd == COM_NOP || cmd == 0x7f) { /* check for NOP or INCH */ + uptr->CMD &= LMASK; /* leave only chsa */ + sim_debug(DEBUG_CMD, &com_dev, + "como_srv NOP or INCH done chsa %04x line %04x cmd %02x\n", + chsa, ln, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; /* return */ + } + + /* handle SACE, 3 char already read, so we are done */ + if (cmd == COM_SACE) { /* check for SACE 0xff */ + uptr->CMD &= LMASK; /* leave only chsa */ + sim_debug(DEBUG_CMD, &com_dev, + "como_srv SACE done chsa %04x line %02x cmd %02x ACE %08x\n", + chsa, ln, cmd, uptr->ACE); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; /* return */ + } + + if (cmd == 0) + /* all done, so stop polling */ + return SCPE_OK; + + if (com_ldsc[ln].conn == 0) { /* connected? */ + /* not connected, so dump char on ground */ + sim_debug(DEBUG_CMD, dptr, + "como_srv write dump DONE line %04x status %04x cmd %02x\n", + ln, SNS_CHNEND|SNS_DEVEND, cmd); + uptr->CMD &= LMASK; /* nothing left, command complete */ + + uptr->SNS |= 0x00003003; /* status is online & ready */ + ruptr->SNS &= SNS_DSRS; /* reset DSR */ + ruptr->SNS |= SNS_DELDSR; /* give change status */ + uptr->SNS |= SNS_MRING; /* give RING status */ + /* if line not active, abort cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* error return */ + return SCPE_OK; + } + + sim_debug(DEBUG_CMD, dptr, + "como_srv entry 1 chsa %04x line %04x cmd %02x\n", chsa, ln, cmd); + /* get a user byte from memory */ +doagain: + done = chan_read_byte(chsa, &ch); /* get byte from memory */ + if (done) { + uptr->CMD &= LMASK; /* leave only chsa */ + sim_debug(DEBUG_CMD, dptr, + "como_srv Write DONE %01x chsa %04x line %04x status %04x\n", + done, chsa, ln, SNS_CHNEND|SNS_DEVEND); + tmxr_poll_tx(&com_desc); /* send out data */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; /* return */ + } + + /* not done */ + sim_debug(DEBUG_DETAIL, dptr, + "como_srv poll chsa %04x line %02x SNS %08x ACE %08x\n", + chsa, ln, uptr->SNS, uptr->ACE); + + /* convert to user requested output */ + ch = sim_tt_outcvt(ch, TT_GET_MODE(coml_unit[ln].flags)); + /* send the next char out */ + tmxr_putc_ln(&com_ldsc[ln], ch); /* output char */ + sim_debug(DEBUG_CMD, dptr, + "como_srv writing char 0x%02x to ln %04x\n", ch, ln); + goto doagain; /* keep going */ +} + +/* haltxio routine */ +t_stat coml_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & COM_MSK; + int unit = (uptr - coml_unit); /* unit # 0 is read, 1 is write */ + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_EXP, &com_dev, "coml_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + if ((uptr->CMD & COM_MSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, &coml_dev, + "coml_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count); + /* stop any I/O and post status and return error status */ + chp->ccw_count = 0; /* zero the count */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + uptr->CMD &= LMASK; /* make non-busy */ + uptr->CNT = 0; /* no I/O yet */ + com_data[unit].incnt = 0; /* no input data */ + sim_cancel(uptr); /* stop timer */ +// uptr->SNS |= (SNS_RDY|SNS_CONN); /* status is online & ready */ + sim_debug(DEBUG_CMD, &coml_dev, + "coml_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ + return 1; /* tell chan code to post status */ + } + uptr->CNT = 0; /* no I/O yet */ + com_data[unit].incnt = 0; /* no input data */ + uptr->CMD &= LMASK; /* make non-busy */ +// uptr->SNS |= (SNS_RDY|SNS_CONN); /* status is online & ready */ + return SCPE_OK; /* not busy */ +} + +/* Reset routine */ +t_stat com_reset (DEVICE *dptr) +{ + int32 i; + + if (com_dev.flags & DEV_DIS) /* master disabled? */ + com_dev.flags |= DEV_DIS; /* disable lines */ + else + com_dev.flags &= ~DEV_DIS; + if (com_unit[COMC].flags & UNIT_ATT) /* master att? */ + sim_clock_coschedule(&com_unit[0], 200); /* activate */ + for (i = 0; i < COM_LINES; i++) /* reset lines */ + com_reset_ln(i); + return SCPE_OK; +} + + +/* attach master unit */ +t_stat com_attach(UNIT *uptr, CONST char *cptr) +{ + DEVICE *dptr = get_dev(uptr); + t_stat r; + + r = tmxr_attach(&com_desc, uptr, cptr); /* attach */ + if (r != SCPE_OK) /* error? */ + return r; /* return error */ + sim_debug(DEBUG_CMD, dptr, "com_srv comc is now attached\n"); + sim_activate(uptr, 100); /* start poll at once */ + return SCPE_OK; +} + +/* detach master unit */ +t_stat com_detach(UNIT *uptr) +{ + int32 i; + t_stat r; + + r = tmxr_detach(&com_desc, uptr); /* detach */ + for (i = 0; i < COM_LINES; i++) /* disable rcv */ + com_reset_ln(i); /* reset the line */ + sim_cancel(uptr); /* stop poll, cancel timer */ + return r; +} + +/* Reset an individual line */ +void com_reset_ln (int32 ln) +{ + sim_cancel(&coml_unit[ln]); + com_stat[ln] = 0; + com_stat[ln] |= COML_REP; /* set pending */ + com_rbuf[ln] = 0; /* clear read buffer */ + com_xbuf[ln] = 0; /* clear write buffer */ + com_ldsc[ln].rcve = 0; + com_ldsc[ln].xmte = 0; + coml_unit[ln].CNT = 0; /* no input count */ + com_data[ln].incnt = 0; /* no input data */ + return; +} + +t_stat com_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ +fprintf (st, "SEL32 8512 8-Line Async Controller Terminal Interfaces\n\n"); +fprintf (st, "Terminals perform input and output through Telnet sessions connected to a \n"); +fprintf (st, "user-specified port.\n\n"); +fprintf (st, "The ATTACH command specifies the port to be used:\n\n"); +tmxr_attach_help (st, dptr, uptr, flag, cptr); +fprintf (st, "The additional terminals can be set to one of four modes: UC, 7P, 7B, or 8B.\n\n"); +fprintf (st, " mode input characters output characters\n\n"); +fprintf (st, " UC lower case converted lower case converted to upper case,\n"); +fprintf (st, " to upper case, high-order bit cleared,\n"); +fprintf (st, " high-order bit cleared non-printing characters suppressed\n"); +fprintf (st, " 7P high-order bit cleared high-order bit cleared,\n"); +fprintf (st, " non-printing characters suppressed\n"); +fprintf (st, " 7B high-order bit cleared high-order bit cleared\n"); +fprintf (st, " 8B no changes no changes\n\n"); +fprintf (st, "The default mode is 7P. In addition, each line can be configured to\n"); +fprintf (st, "behave as though it was attached to a dataset, or hardwired to a terminal:\n\n"); +fprintf (st, " sim> SET COMLn DATASET simulate attachment to a dataset (modem)\n"); +fprintf (st, " sim> SET COMLn NODATASET simulate direct attachment to a terminal\n\n"); +fprintf (st, "Finally, each line supports output logging. The SET COMLn LOG command enables\n"); +fprintf (st, "logging on a line:\n\n"); +fprintf (st, " sim> SET COMLn LOG=filename log output of line n to filename\n\n"); +fprintf (st, "The SET COMLn NOLOG command disables logging and closes the open log file,\n"); +fprintf (st, "if any.\n\n"); +fprintf (st, "Once DCI is attached and the simulator is running, the terminals listen for\n"); +fprintf (st, "connections on the specified port. They assume that the incoming connections\n"); +fprintf (st, "are Telnet connections. The connections remain open until disconnected either\n"); +fprintf (st, "by the Telnet client, a SET DCI DISCONNECT command, or a DETACH DCI command.\n\n"); +fprintf (st, "Other special commands:\n\n"); +fprintf (st, " sim> SHOW COMC CONNECTIONS show current connections\n"); +fprintf (st, " sim> SHOW COMC STATISTICS show statistics for active connections\n"); +fprintf (st, " sim> SET COMLn DISCONNECT disconnects the specified line.\n"); +fprintf (st, "\nThe additional terminals do not support save and restore. All open connections\n"); +fprintf (st, "are lost when the simulator shuts down or DCI is detached.\n"); + fprint_set_help (st, dptr); + fprint_show_help (st, dptr); + return SCPE_OK; +} + +/* description of controller */ +const char *com_description (DEVICE *dptr) +{ + return "SEL-32 8512 8-Line async communications controller"; +} + +#endif diff --git a/SEL32/sel32_con.c b/SEL32/sel32_con.c new file mode 100644 index 00000000..5c9b3083 --- /dev/null +++ b/SEL32/sel32_con.c @@ -0,0 +1,799 @@ +/* sel32_con.c: SEL 32 Class F IOP processor console. + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers + + 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 + JAMES C. BEVIER 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. + + This is the standard console interface. It is subchannel of the IOP 7e00. + + These units each buffer one record in local memory and signal + ready when the buffer is full or empty. The channel must be + ready to recieve/transmit data when they are activated since + they will transfer their block during chan_cmd. All data is + transmitted as ASCII characters. +*/ + +#include "sel32_defs.h" +#include "sim_tmxr.h" + +#if NUM_DEVS_CON > 0 + +#define UNIT_CON UNIT_IDLE | UNIT_DISABLE + +#define CMD u3 +/* Held in u3 is the device command and status */ +#define CON_INCH 0x00 /* Initialize channel command */ +#define CON_INCH2 0xf0 /* Initialize channel command for processing */ +#define CON_WR 0x01 /* Write console */ +#define CON_RD 0x02 /* Read console */ +#define CON_NOP 0x03 /* No op command */ +#define CON_SNS 0x04 /* Sense command */ +#define CON_ECHO 0x0a /* Read with Echo */ +#define CON_RDBWD 0x0c /* Read backward */ +#define CON_CON 0x1f /* connect line */ +#define CON_DIS 0x23 /* disconnect line */ +#define CON_RWD 0x37 /* TOF and write line */ + +#define CON_MSK 0xff /* Command mask */ + +/* Status held in u3 */ +/* controller/unit address in upper 16 bits */ +#define CON_ATAT 0x4000 /* working on @@A input */ +#define CON_READ 0x2000 /* Read mode selected */ +#define CON_OUTPUT 0x1000 /* Output ready for unit */ +#define CON_EKO 0x0800 /* Echo input character */ +#define CON_REQ 0x0400 /* Request key pressed */ +#define CON_CR 0x0200 /* Output at beginning of line */ +#define CON_INPUT 0x0100 /* Input ready for unit */ + +/* Input buffer pointer held in u4 */ + +#define SNS u5 +/* in u5 packs sense byte 0,1 and 3 */ +/* Sense byte 0 */ +#define SNS_CMDREJ 0x80000000 /* Command reject */ +#define SNS_INTVENT 0x40000000 /* Unit intervention required */ +/* sense byte 3 */ +#define SNS_RDY 0x80 /* device ready */ +#define SNS_ONLN 0x40 /* device online */ +#define SNS_DSR 0x08 /* data set ready */ +#define SNS_DCD 0x04 /* data carrier detect */ + +/* std devices. data structures + con_dev Console device descriptor + con_unit Console unit descriptor + con_reg Console register list + con_mod Console modifiers list +*/ + +struct _con_data +{ + uint8 incnt; /* char count */ + uint8 ibuff[145]; /* Input line buffer */ +} +con_data[NUM_UNITS_CON]; + +uint32 atbuf=0; /* attention buffer */ +uint32 outbusy = 0; /* output waiting on timeout */ +uint32 inbusy = 0; /* input waiting on timeout */ + +/* forward definitions */ +t_stat con_preio(UNIT *uptr, uint16 chan); +t_stat con_startcmd(UNIT*, uint16, uint8); +void con_ini(UNIT*, t_bool); +t_stat con_srvi(UNIT*); +t_stat con_srvo(UNIT*); +t_stat con_haltio(UNIT *); +t_stat con_rschnlio(UNIT *uptr); /* Reset Channel */ +t_stat con_poll(UNIT *); +t_stat con_reset(DEVICE *); + +/* channel program information */ +CHANP con_chp[NUM_UNITS_CON] = {0}; + +MTAB con_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, &show_dev_addr, NULL}, + {0} +}; + +UNIT con_unit[] = { + {UDATA(&con_srvi, UNIT_CON, 0), 0, UNIT_ADDR(0x7EFC)}, /* 0 Input */ + {UDATA(&con_srvo, UNIT_CON, 0), 0, UNIT_ADDR(0x7EFD)}, /* 1 Output */ +}; + +DIB con_dib = { + con_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + con_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + con_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + con_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + con_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + con_unit, /* UNIT* units */ /* Pointer to units structure */ + con_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_CON, /* uint8 numunits */ /* number of units defined */ + 0x03, /* uint8 mask */ /* 2 devices - device mask */ + 0x7e00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE con_dev = { + "CON", con_unit, NULL, con_mod, + NUM_UNITS_CON, 8, 15, 1, 8, 8, +// NULL, NULL, &con_reset, NULL, &con_attach, &con_detach, + NULL, NULL, &con_reset, NULL, NULL, NULL, + &con_dib, DEV_DIS|DEV_DISABLE|DEV_DEBUG, 0, dev_debug +}; + +/* + * Console print routines. + */ +/* initialize the console chan/unit */ +void con_ini(UNIT *uptr, t_bool f) { + int unit = (uptr - con_unit); /* unit 0 */ + + uptr->u4 = 0; /* no input count */ + con_data[unit].incnt = 0; /* no input data */ + uptr->CMD &= LMASK; /* leave only chsa */ + uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */ + sim_cancel(uptr); /* stop input poll */ + if (unit == 0) { + sim_activate(uptr, 1000); /* start input poll */ + } +} + +/* start a console operation */ +t_stat con_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + + if ((uptr->CMD & CON_MSK) != 0) { /* just return if busy */ + sim_debug(DEBUG_CMD, dptr, "con_preio unit=%02x BUSY\n", unit); + return SNS_BSY; + } + + sim_debug(DEBUG_CMD, dptr, "con_preio unit=%02x OK\n", unit); + return SCPE_OK; /* good to go */ +} + +/* start an I/O operation */ +t_stat con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { + DEVICE *dptr = uptr->dptr; + int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */ + + if ((uptr->CMD & CON_MSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_EXP, dptr, + "con_startcmd unit %01x chan %02x cmd %02x BUSY cmd %02x uptr %p\n", + unit, chan, cmd, uptr->CMD, uptr); + return SNS_BSY; /* yes, return busy */ + } + + sim_debug(DEBUG_DETAIL, dptr, + "con_startcmd unit %01x chan %02x cmd %02x enter\n", unit, chan, cmd); + + /* substitute CON_INCH2 for CON_INCH for pprocessing */ + if (cmd == CON_INCH) + cmd = CON_INCH2; /* save INCH command as 0xf0 */ + + /* process the commands */ + switch (cmd & 0xFF) { + case CON_ECHO: /* 0x0a */ /* Read command w/ECHO */ + uptr->CMD |= CON_EKO; /* save echo status */ + case CON_RD: /* 0x02 */ /* Read command */ + atbuf = 0; /* reset attention buffer */ + uptr->CMD |= CON_READ; /* show read mode */ + /* fall through */ + case CON_INCH2: /* 0xf0 */ /* INCH command */ + case CON_RWD: /* 0x37 */ /* TOF and write line */ + case CON_WR: /* 0x01 */ /* Write command */ + case CON_NOP: /* 0x03 */ /* NOP has do nothing */ + case CON_RDBWD: /* 0x0c */ /* Read Backward */ + uptr->SNS |= (SNS_RDY|SNS_ONLN); /* status is online & ready */ + case CON_CON: /* 0x1f */ /* Connect, return Data Set ready */ + case CON_DIS: /* 0x23 */ /* Disconnect has do nothing */ + case CON_SNS: /* 0x04 */ /* Sense */ + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + uptr->CMD |= (cmd & CON_MSK); /* save command */ + if (unit == 0) { + sim_cancel(uptr); /* stop input poll */ + sim_activate(uptr, 300); /* start us off */ +// sim_activate(uptr, 1000); /* start us off */ + } + else + /* using value 500 or larger causes diag to fail on 32/27 */ +// sim_activate(uptr, 500); /* start us off */ +// sim_activate(uptr, 200); /* start us off */ + sim_activate(uptr, 30); /* start us off */ + return SCPE_OK; /* no status change */ + break; + + default: /* invalid command */ + break; + } + /* invalid command */ + uptr->SNS |= SNS_CMDREJ; /* command rejected */ + sim_debug(DEBUG_EXP, dptr, + "con_startcmd %04x: Invalid command %02x Sense %02x\n", + chan, cmd, uptr->SNS); + return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; +} + +/* Handle output transfers for console */ +t_stat con_srvo(UNIT *uptr) { + DEVICE *dptr = uptr->dptr; + uint16 chsa = GET_UADDR(uptr->CMD); + int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */ + int cmd = uptr->CMD & CON_MSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + int len = chp->ccw_count; /* INCH command count */ + uint32 mema = chp->ccw_addr; /* get inch or buffer addr */ + uint32 tstart; + uint8 ch; + static uint32 dexp; + static int cnt = 0; + + sim_debug(DEBUG_CMD, dptr, + "con_srvo enter CMD %08x chsa %04x cmd %02x iocla %06x cnt %04x\n", + uptr->CMD, chsa, cmd, chp->chan_caw, chp->ccw_count); + + switch (cmd) { + + /* if input tried from output device, error */ + case CON_RD: /* 0x02 */ /* Read command */ + case CON_ECHO: /* 0x0a */ /* Read command w/ECHO */ + case CON_RDBWD: /* 0x0c */ /* Read Backward */ + /* if input requested for output device, give error */ + uptr->SNS |= SNS_CMDREJ; /* command rejected */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo Read to output device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */ + break; + + case CON_CON: /* 0x1f */ /* Connect, return Data Set ready */ + uptr->SNS |= (SNS_DSR|SNS_DCD); /* Data set ready, Data Carrier detected */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo CON CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case CON_DIS: /* 0x23 */ /* Disconnect has do nothing */ + uptr->SNS &= ~(SNS_DSR|SNS_DCD); /* Data set not ready */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo DIS CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case CON_INCH2: /* 0xf0 */ /* INCH command */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); + + /* now call set_inch() function to write and test inch buffer addresses */ + /* 1-256 wd buffer is provided for 128 status dbl words */ + tstart = set_inch(uptr, mema, 128); /* new address & 128 entries */ + if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ; + sim_debug(DEBUG_CMD, dptr, + "con_srvo INCH Error unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + sim_debug(DEBUG_CMD, dptr, + "con_srvo INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema); + /* WARNING, if SNS_DEVEND is not set, diags fail by looping in CON diag */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case CON_NOP: /* 0x03 */ /* NOP has do nothing */ + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case CON_SNS: /* 0x04 */ /* Sense */ + /* value 4 is Data Set Ready */ + /* value 5 is Data carrier detected n/u */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo cmd %04x: Cmd Sense %02x\n", chsa, uptr->SNS); + /* value 4 is Data Set Ready */ + /* value 5 is Data carrier detected n/u */ + ch = uptr->SNS & 0xff; /* Sense byte 3 */ + if (chan_write_byte(chsa, &ch)) { /* write byte to memory */ + /* write error */ + cmd = 0; /* no cmd now */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo write error unit %02x: CMD %08x read %02x u4 %02x ccw_count %02x\n", + unit, uptr->CMD, ch, uptr->u4, chp->ccw_count); + uptr->CMD &= LMASK; /* nothing left, command complete */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + } + uptr->CMD &= LMASK; /* nothing left, command complete */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* good return */ + break; + + case CON_RWD: /* 0x37 */ /* TOF and write line */ + case CON_WR: /* 0x01 */ /* Write command */ +#ifdef DO_OLDWAY + /* see if write complete */ + if (uptr->CMD & CON_OUTPUT) { + /* write is complete, post status */ + sim_debug(DEBUG_CMD, &con_dev, + "con_srvo write CMD %08x chsa %04x cmd %02x complete\n", + uptr->CMD, chsa, cmd); + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + uptr->CMD &= ~CON_OUTPUT; /* remove output command */ +/*RTC*/ outbusy = 0; /* output done */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + break; + } +/*RTC*/ outbusy = 1; /* tell clock output waiting */ + if (chan_read_byte(chsa, &ch) == SCPE_OK) { /* get byte from memory */ + /* Write to device */ + ch &= 0x7f; /* make 7 bit w/o parity */ + dexp = dexp<<8; /* move up last chars */ + dexp |= ch; /* insert new char */ +#ifdef DO_DYNAMIC_DEBUG +// if ((cnt == 3) && (dexp == 0x4458503e)) { /* test for "DXP>" */ + if ((cnt == 13) && (dexp == 0x4E542E48)) { /* test for "NT.H" */ + cpu_dev.dctrl |= (DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */ + con_dev.dctrl |= DEBUG_XIO|DEBUG_CMD; +// sim_debug(DEBUG_INST, &cpu_dev, "|con_srvo DXP> received|\n"); + sim_debug(DEBUG_INST, &cpu_dev, "con_srvo CV.INT.H received start debug\n"); + } + if ((cnt == 13) && (dexp == 0x52502E48)) { /* test for "RP.H" */ + /* turn of debug trace because we are already hung */ + sim_debug(DEBUG_INST, &cpu_dev, "con_srvo got CV.TRP.H stopping debug\n"); + cpu_dev.dctrl &= ~(DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */ + con_dev.dctrl &= ~(DEBUG_XIO|DEBUG_CMD); + } +#endif + sim_putchar(ch); /* output next char to device */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo write wait %03x CMD %08x chsa %04x cmd %02x byte %d = %02x\n", + 1000, uptr->CMD, chsa, cmd, cnt, ch); + cnt++; /* count chars output */ +//01132022 sim_activate(uptr, 500); /* wait for a while before next write */ + sim_activate(uptr, 50); /* wait for a while before next write */ + break; + } + /* nothing left, finish up */ + cnt = 0; /* zero for next output */ + uptr->CMD |= CON_OUTPUT; /* output command complete */ + sim_debug(DEBUG_CMD, &con_dev, + "con_srvo write wait %03x CMD %08x chsa %04x cmd %02x to complete\n", + 1000, uptr->CMD, chsa, cmd); + sim_activate(uptr, 500); /* wait for a while */ + break; +#else + cnt = 0; /* zero count */ +/*RTC*/ outbusy = 1; /* tell clock output waiting */ + mema = chp->ccw_addr; /* get buffer addr */ + /* Write to device */ + while (chan_read_byte(chsa, &ch) == SCPE_OK) { /* get byte from memory */ + /* HACK HACK HACK */ + ch &= 0x7f; /* make 7 bit w/o parity */ + dexp = dexp<<8; /* move up last chars */ + dexp |= ch; /* insert new char */ +#ifdef DO_DYNAMIC_DEBUG +// if ((cnt == 3) && (dexp == 0x4458503e)) { /* test for "DXP>" */ + if ((cnt == 3) && (dexp == 0x44454641)) { /* test for "DEFA" */ +// cpu_dev.dctrl |= (DEBUG_INST|DEBUG_IRQ); /* start instruction trace */ + cpu_dev.dctrl |= (DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */ +// con_dev.dctrl |= DEBUG_CMD; +// sim_debug(DEBUG_INST, &cpu_dev, "|con_srvo DXP> received|\n"); + sim_debug(DEBUG_INST, &cpu_dev, "|con_srvo DEFA received|\n"); + } +#endif + sim_putchar(ch); /* output next char to device */ + if (isprint(ch)) + sim_debug(DEBUG_CMD, dptr, + "con_srvo write addr %06x chsa %04x cmd %02x byte %d = %02x [%c]\n", + mema, chsa, cmd, cnt, ch, ch); + else + sim_debug(DEBUG_CMD, dptr, + "con_srvo write addr %06x chsa %04x cmd %02x byte %d = %02x\n", + mema, chsa, cmd, cnt, ch); + mema = chp->ccw_addr; /* get next buffer addr */ + cnt++; /* count chars output */ + } + /* write is complete, post status */ + sim_debug(DEBUG_CMD, dptr, + "con_srvo write CMD %08x chsa %04x cmd %02x complete\n", + uptr->CMD, chsa, cmd); + uptr->CMD &= LMASK; /* nothing left, command complete */ +/*RTC*/ outbusy = 0; /* output done */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + break; +#endif + } + return SCPE_OK; +} + +/* Handle input transfers for console */ +t_stat con_srvi(UNIT *uptr) { + DEVICE *dptr = uptr->dptr; + uint16 chsa = GET_UADDR(uptr->CMD); + int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */ + int cmd = uptr->CMD & CON_MSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + int len = chp->ccw_count; /* INCH command count */ + uint32 mema = chp->ccw_addr; /* get inch or buffer addr */ + uint32 tstart; + uint8 ch; + t_stat r; + int32 wait_time=10000; + + switch (cmd) { + + /* if output tried to input device, error */ + case CON_RWD: /* 0x37 */ /* TOF and write line */ + case CON_WR: /* 0x01 */ /* Write command */ + /* if input requested for output device, give error */ + uptr->SNS |= SNS_CMDREJ; /* command rejected */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi Write to input device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */ + break; + + case CON_INCH2: /* 0xf0 */ /* INCH command */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x inch %06x\n", + unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4, mema); + + /* now call set_inch() function to write and test inch buffer addresses */ + tstart = set_inch(uptr, mema, 128); /* new address & 128 entries */ + if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ; + sim_debug(DEBUG_CMD, dptr, + "con_srvi INCH Error unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + con_data[unit].incnt = 0; /* buffer empty */ + uptr->u4 = 0; /* no I/O yet */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema); + /* WARNING, if SNS_DEVEND is not set, diags fail by looping in CON diag */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + /* drop through to poll input */ + break; + + case CON_NOP: /* 0x03 */ /* NOP has do nothing */ + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + /* drop through to poll input */ + break; + + case CON_CON: /* 0x1f */ /* Connect, return Data Set ready */ + uptr->SNS |= (SNS_DSR|SNS_DCD); /* Data set ready, Data Carrier detected */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi CON CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case CON_DIS: /* 0x23 */ /* Disconnect has do nothing */ + uptr->SNS &= ~(SNS_DSR|SNS_DCD); /* Data set not ready */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi DIS CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case CON_SNS: /* 0x04 */ /* Sense */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi cmd %04x: Cmd Sense %02x\n", chsa, uptr->SNS); + /* value 4 is Data Set Ready */ + /* value 5 is Data carrier detected n/u */ + ch = uptr->SNS & 0xff; /* Sense byte 3 */ + if (chan_write_byte(chsa, &ch)) { /* write byte to memory */ + /* write error */ + cmd = 0; /* no cmd now */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi write error unit %02x: CMD %08x read %02x u4 %02x ccw_count %02x\n", + unit, uptr->CMD, ch, uptr->u4, chp->ccw_count); + uptr->CMD &= LMASK; /* nothing left, command complete */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + } + uptr->CMD &= LMASK; /* nothing left, command complete */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + + case CON_ECHO: /* 0x0a */ /* read from device w/ECHO */ + uptr->CMD |= CON_EKO; /* save echo status */ + case CON_RD: /* 0x02 */ /* read from device */ + case CON_RDBWD: /* 0x0c */ /* Read Backward */ + + if ((uptr->u4 != con_data[unit].incnt) || /* input empty */ + (uptr->CMD & CON_INPUT)) { /* input waiting? */ + ch = con_data[unit].ibuff[uptr->u4]; /* get char from read buffer */ + if (isprint(ch)) + sim_debug(DEBUG_IRQ, dptr, + "con_srvi readbuf unit %02x: CMD %08x read %02x [%c] incnt %02x u4 %02x len %02x\n", + unit, uptr->CMD, ch, ch, con_data[unit].incnt, uptr->u4, chp->ccw_count); + else + sim_debug(DEBUG_IRQ, dptr, + "con_srvi readbuf unit %02x: CMD %08x read %02x incnt %02x u4 %02x len %02x\n", + unit, uptr->CMD, ch, con_data[unit].incnt, uptr->u4, chp->ccw_count); +#ifdef DO_DYNAMIC_DEBUG + /* turn on instruction trace */ + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ +#endif + + /* process any characters */ + if (uptr->u4 != con_data[unit].incnt) { /* input available */ + ch = con_data[unit].ibuff[uptr->u4]; /* get char from read buffer */ + /* this fixes mpx1x time entry on startup */ + if (uptr->CMD & CON_EKO) /* ECHO requested */ + sim_putchar(ch); /* ECHO the char */ + if (chan_write_byte(chsa, &ch)) { /* write byte to memory */ + /* write error */ + cmd = 0; /* no cmd now */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi write error unit %02x: CMD %08x read %02x u4 %02x ccw_count %02x\n", + unit, uptr->CMD, ch, uptr->u4, chp->ccw_count); + uptr->CMD &= ~CON_MSK; /* remove old CMD */ + uptr->CMD &= ~CON_INPUT; /* input waiting? */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + } + /* character accepted, bump buffer pointer */ + uptr->u4++; /* next char position */ + + sim_debug(DEBUG_CMD, dptr, + "con_srvi write to mem unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n", + unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt); + + /* see if at end of buffer */ + if (uptr->u4 >= (int32)sizeof(con_data[unit].ibuff)) + uptr->u4 = 0; /* reset pointer */ + + /* user want more data? */ + if ((test_write_byte_end(chsa)) == 0) { + sim_debug(DEBUG_CMD, dptr, + "con_srvi need more unit %02x CMD %08x u4 %02x ccw_count %02x incnt %02x\n", + unit, uptr->CMD, uptr->u4, chp->ccw_count, con_data[unit].incnt); + /* user wants more, look next time */ + if (uptr->u4 == con_data[unit].incnt) { /* input empty */ + uptr->CMD &= ~CON_INPUT; /* no input available */ + } +// wait_time = 200; /* process next time */ +// wait_time = 400; /* process next time */ + wait_time = 800; /* process next time */ + break; + } + /* command is completed */ + if (isprint(ch)) + sim_debug(DEBUG_CMD, dptr, + "con_srvi read done unit %02x CMD %08x read %02x [%c] u4 %02x ccw_count %02x incnt %02x\n", + unit, uptr->CMD, ch, ch, uptr->u4, chp->ccw_count, con_data[unit].incnt); + else + sim_debug(DEBUG_CMD, dptr, + "con_srvi read done unit %02x CMD %08x read %02x u4 %02x ccw_count %02x incnt %02x\n", + unit, uptr->CMD, ch, uptr->u4, chp->ccw_count, con_data[unit].incnt); +#ifdef DO_DYNAMIC_DEBUG + /* turn on instruction trace */ + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ +#endif + cmd = 0; /* no cmd now */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + if (uptr->u4 != con_data[unit].incnt) { /* input empty */ + uptr->CMD |= CON_INPUT; /* input still available */ + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + } + break; + } + default: + break; + } + + /* check for next input if reading or @@A sequence */ + r = sim_poll_kbd(); /* poll for a char */ + if (r & SCPE_KFLAG) { /* got a char */ + ch = r & 0xff; /* drop any extra bits */ + if ((uptr->CMD & CON_READ)) { /* looking for input? */ + atbuf = 0; /* reset attention buffer */ + uptr->CMD &= ~CON_ATAT; /* no @@A input */ + if (ch == '@') { /* maybe for console int */ + atbuf = (ch)<<8; /* start anew */ + uptr->CMD |= CON_ATAT; /* show getting @ */ + } +#ifndef TEST4MPX + if (ch == '\n') /* convert newline */ + ch = '\r'; /* make newline into carriage return */ +#endif + if (isprint(ch)) + sim_debug(DEBUG_CMD, dptr, + "con_srvi handle readch unit %02x: CMD %08x read %02x [%c] u4 %02x incnt %02x r %x\n", + unit, uptr->CMD, ch, ch, uptr->u4, con_data[unit].incnt, r); + else + sim_debug(DEBUG_CMD, dptr, + "con_srvi handle readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x r %x\n", + unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt, r); +#ifdef DO_DYNAMIC_DEBUG + /* turn on instruction trace */ + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ +#endif + + /* put char in buffer */ + con_data[unit].ibuff[con_data[unit].incnt++] = ch; + + /* see if count at max, if so reset to start */ + if (con_data[unit].incnt >= sizeof(con_data[unit].ibuff)) + con_data[unit].incnt = 0; /* reset buffer cnt */ + + uptr->CMD |= CON_INPUT; /* we have a char available */ + if (isprint(ch)) + sim_debug(DEBUG_CMD, dptr, + "con_srvi readch unit %02x: CMD %08x read %02x [%c] u4 %02x incnt %02x\n", + unit, uptr->CMD, ch, ch, uptr->u4, con_data[unit].incnt); + else + sim_debug(DEBUG_CMD, dptr, + "con_srvi readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n", + unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt); + sim_activate(uptr, 30); /* do this again */ +//01172021 sim_activate(uptr, 400); /* do this again */ +// sim_activate(uptr, 800); /* do this again */ + return SCPE_OK; + } + /* not looking for input, look for attn or wakeup */ + if (ch == '?') { + /* set ring bit? */ + set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); /* tell user */ + } + /* not wanting input, but we have a char, look for @@A */ + if (uptr->CMD & CON_ATAT) { /* looking for @@A */ + /* we have at least one @, look for another */ + if (ch == '@' || ch == 'A' || ch == 'a') { + uint8 cc = ch; + if (cc == 'a') + cc = 'A'; /* make uppercase */ + sim_putchar(ch); /* ECHO the char */ + atbuf = (atbuf|cc)<<8; /* merge new char */ + if (atbuf == 0x40404100) { + attention_trap = CONSOLEATN_TRAP; /* console attn (0xb4) */ + atbuf = 0; /* reset attention buffer */ + uptr->CMD &= ~CON_ATAT; /* no @@A input */ + sim_putchar('\r'); /* return char */ + sim_putchar('\n'); /* line feed char */ + sim_debug(DEBUG_CMD, dptr, + "con_srvi unit %02x: CMD %08x read @@A Console Trap\n", unit, uptr->CMD); + uptr->u4 = 0; /* no input count */ + con_data[unit].incnt = 0; /* no input data */ + } +// sim_activate(uptr, wait_time); /* do this again */ + sim_activate(uptr, 400); /* do this again */ +// sim_activate(uptr, 4000); /* do this again */ + return SCPE_OK; + } + /* char not for us, so keep looking */ + atbuf = 0; /* reset attention buffer */ + uptr->CMD &= ~CON_ATAT; /* no @@A input */ + } + /* not looking for input, look for attn or wakeup */ + if (ch == '@') { + atbuf = (atbuf|ch)<<8; /* merge in char */ + uptr->CMD |= CON_ATAT; /* show getting @ */ + sim_putchar(ch); /* ECHO the char */ + } + /* assume it is for next read request, so save it */ + /* see if count at max, if so reset to start */ + if (con_data[unit].incnt >= sizeof(con_data[unit].ibuff)) + con_data[unit].incnt = 0; /* reset buffer cnt */ + + /* put char in buffer */ + con_data[unit].ibuff[con_data[unit].incnt++] = ch; + + uptr->CMD |= CON_INPUT; /* we have a char available */ + if (isprint(ch)) + sim_debug(DEBUG_CMD, dptr, + "con_srvi readch2 unit %02x: CMD %08x read %02x [%c] u4 %02x incnt %02x r %x\n", + unit, uptr->CMD, ch, ch, uptr->u4, con_data[unit].incnt, r); + else + sim_debug(DEBUG_CMD, dptr, + "con_srvi readch2 unit %02x: CMD %08x read %02x u4 %02x incnt %02x r %x\n", + unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt, r); +#ifdef DO_DYNAMIC_DEBUG + /* turn off debug trace because we are already hung */ + sim_debug(DEBUG_INST, &cpu_dev, "con_srvi readch3 stopping debug\n"); + cpu_dev.dctrl &= ~(DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */ + con_dev.dctrl &= ~(DEBUG_XIO|DEBUG_CMD); +#endif + } + sim_activate(uptr, wait_time); /* do this again */ + return SCPE_OK; +} + +t_stat con_reset(DEVICE *dptr) { + tmxr_set_console_units (&con_unit[0], &con_unit[1]); + return SCPE_OK; +} + +/* Handle rschnlio cmds for console */ +t_stat con_rschnlio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & CON_MSK; + con_ini(uptr, 0); /* reset the unit */ + sim_debug(DEBUG_EXP, &con_dev, "con_rschnl chsa %04x cmd = %02x\n", chsa, cmd); +// cpu_dev.dctrl |= (DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */ + return SCPE_OK; +} + +/* Handle haltio transfers for console */ +t_stat con_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & CON_MSK; + int unit = (uptr - con_unit); /* unit # 0 is read, 1 is write */ + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_EXP, &con_dev, + "con_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + if ((uptr->CMD & CON_MSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, &con_dev, + "con_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + sim_cancel(uptr); /* stop timer */ + /* stop any I/O and post status and return error status */ + chp->ccw_count = 0; /* zero the count */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + uptr->CMD &= LMASK; /* make non-busy */ + uptr->u4 = 0; /* no I/O yet */ + con_data[unit].incnt = 0; /* no input data */ + uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */ + sim_debug(DEBUG_CMD, &con_dev, + "con_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ + return CC2BIT | SCPE_IOERR; /* tell chan code to post status */ + } + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */ + sim_debug(DEBUG_CMD, &con_dev, + "con_haltio HIO not busy chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + return CC1BIT | SCPE_OK; /* not busy */ +} +#endif + diff --git a/SEL32/sel32_cpu.c b/SEL32/sel32_cpu.c new file mode 100644 index 00000000..ba68f6a0 --- /dev/null +++ b/SEL32/sel32_cpu.c @@ -0,0 +1,7636 @@ +/* sel32_cpu.c: Sel 32 CPU simulator + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers + + 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 + JAMES C. BEVIER 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 "sel32_defs.h" + +/* Concept 32 PSD Mode Trap/Interrupt Priorities */ +/* Relative|Logical |Int Vect|TCW |IOCD|Description */ +/* Priority|Priority|Location|Addr|Addr */ +/* - 080 Power Fail Safe Trap */ +/* - 084 Power On Trap */ +/* - 088 Memory Parity Trap */ +/* - 08C Nonpresent Memory Trap */ +/* - 090 Undefined Instruction Trap */ +/* - 094 Privilege Violation Trap */ +/* - 098 Supervisor Call Trap (SVC) */ +/* - 09C Machine Check Trap */ +/* - 0A0 System Check Trap */ +/* - 0A4 Map Fault Trap */ +/* - 0A8 CALM or Undefined IPU Instruction Trap */ +/* - 0AC Signal CPU or Signal IPU Trap */ +/* - 0B0 Address Specification Trap */ +/* - 0B4 Console Attention Trap */ +/* - 0B8 Privlege Mode Halt Trap */ +/* - 0BC Arithmetic Exception Trap */ +/* - 0C0 Cache Error Trap (V9 Only) */ +/* - 0C4 Demand Page Fault Trap (V6&V9 Only) */ +/* */ +/* 0 00 100 External/software Interrupt 0 */ +/* 1 01 104 External/software Interrupt 1 */ +/* 2 02 108 External/software Interrupt 2 */ +/* 3 03 10C External/software Interrupt 3 */ +/* 4 04 110 704 700 I/O Channel 0 interrupt */ +/* 5 05 114 70C 708 I/O Channel 1 interrupt */ +/* 6 06 118 714 710 I/O Channel 2 interrupt */ +/* 7 07 11C 71C 718 I/O Channel 3 interrupt */ +/* 8 08 120 724 720 I/O Channel 4 interrupt */ +/* 9 09 124 72C 728 I/O Channel 5 interrupt */ +/* A 0A 128 734 730 I/O Channel 6 interrupt */ +/* B 0B 12C 73C 738 I/O Channel 7 interrupt */ +/* C 0C 130 744 740 I/O Channel 8 interrupt */ +/* D 0D 134 74C 748 I/O Channel 9 interrupt */ +/* E 0E 138 754 750 I/O Channel A interrupt */ +/* F 0F 13C 75C 758 I/O Channel B interrupt */ +/* 10 10 140 764 760 I/O Channel C interrupt */ +/* 11 11 144 76C 768 I/O Channel D interrupt */ +/* 12 12 148 774 770 I/O Channel E interrupt */ +/* 13 13 14c 77C 778 I/O Channel F interrupt */ +/* 14 14 150 External/Software Interrupt */ +/* 15 15 154 External/Software Interrupt */ +/* 16 16 158 External/Software Interrupt */ +/* 17 17 15C External/Software Interrupt */ +/* 18 18 160 Real-Time Clock Interrupt */ +/* 19 19 164 External/Software Interrupt */ +/* 1A 1A 1A8 External/Software Interrupt */ +/* 1B 1B 1AC External/Software Interrupt */ +/* 1C 1C 1B0 External/Software Interrupt */ +/* THRU THRU THRU THRU */ +/* 6C 6C 2B0 External/Software Interrupt */ +/* 6D 6D 2B4 External/Software Interrupt */ +/* 6E 6E 2B8 External/Software Interrupt */ +/* 6F 6F 2BC Interval Timer Interrupt */ + +/* IVL ------------> ICB Trap/Interrupt Vector Location points to Interrupt Context Block */ +/* Wd 0 - Old PSD Word 1 points to return location */ +/* Wd 1 - Old PSD Word 2 */ +/* Wd 2 - New PSD Word 1 points to first instruction of service routine */ +/* Wd 3 - New PSD Word 2 */ +/* Wd 4 - CPU Status word at time of interrupt/trap */ +/* Wd 5 - N/U For Traps/Interrupts */ + +/* IVL ------------> ICB XIO Interrupt Vector Location */ +/* Wd 0 - Old PSD Word 1 points to return location */ +/* Wd 1 - Old PSD Word 2 */ +/* Wd 2 - New PSD Word 1 points to first instruction of service routine */ +/* Wd 3 - New PSD Word 2 */ +/* Wd 4 - Input/Output Command List Address (IOCL) for the Class F I/O CHannel */ +/* Wd 5 - 24 bit real address of the channel status word */ + +/* CPU registers, map cache, spad, and other variables */ +int cpu_index; /* Current CPU running */ +uint32 PSD[2]; /* the PC for the instruction */ +#define PSD1 PSD[0] /* word 1 of PSD */ +#define PSD2 PSD[1] /* word 2 of PSD */ +uint32 M[MAXMEMSIZE] = { 0 }; /* Memory */ +uint32 GPR[8]; /* General Purpose Registers */ +uint32 BR[8]; /* Base registers */ +uint32 PC; /* Program counter */ +uint32 CC; /* Condition codes, bits 1-4 of PSD1 */ +uint32 CPUSTATUS; /* cpu status word */ +uint32 TRAPSTATUS; /* trap status word */ +uint32 SPAD[256]; /* Scratch pad memory */ +uint32 INTS[112]; /* Interrupt status flags */ +uint32 pad[16]; /* In case of wrong access */ +uint32 CMCR; /* Cache Memory Control Register */ +uint32 SMCR; /* Shared Memory Control Register */ +uint32 CMSMC; /* V9 Cache/Shadow Memory Configuration */ +uint32 CSMCW; /* CPU Shadow Memory Configuration Word */ +uint32 ISMCW; /* IPU Shadow Memory Configuration Word */ +uint32 CCW; /* Computer Configuration Word */ +uint32 CSW = 0; /* Console switches going to 0x780 */ +uint32 BOOTR[8] = {0}; /* Boot registers settings */ +/* CPU mapping cache entries */ +/* 32/55 has none */ +/* 32/7x has 32 8KW maps per task */ +/* Concept 32/27 has 256 2KW maps per task */ +/* Concept 32/X7 has 2048 2KW maps per task */ +uint32 MAPC[1024]; /* maps are 16bit entries on word bountries */ +uint32 dummy=0; +uint32 pfault; /* page # of fault from read/write */ +uint32 BPIX=0; /* # pages loaded for O/S */ +uint32 CPIXPL=0; /* highest page loaded for User */ +uint32 CPIX=0; /* CPIX user MPL offset */ +uint32 HIWM=0; /* max maps loaded so far */ +uint32 MODES=0; /* Operating modes, bits 0, 5, 6, 7 of PSD1 */ +uint32 TLB[2048]; /* Translated addresses for each map entry */ +/* bits 0-4 are bits 0-4 from map entry */ +/* bit 0 valid */ +/* bit 1 p1 write access if set */ +/* bit 2 p2 write access if set */ +/* bit 3 p3 write access if set MM - memory modify */ +/* bit 4 p4 write access if set MA - memory accessed */ +/* bit 5 hit bit means entry is setup, even if not valid map */ +/* if hit bit is set and entry not valid, we will do a page fault */ +/* bit 6 dirty bit, set when written to, page update required */ +/* bits 8-18 has map reg contents for this page (Map << 13) */ +/* bit 19-31 is zero for page offset of zero */ + +uint32 dummy2=0; +uint8 wait4int = 0; /* waiting for interrupt if set */ +int32 irq_auto = 0; /* auto reset interrupt processing flag */ + +/* define traps */ +uint32 TRAPME = 0; /* trap to be executed */ +uint32 attention_trap = 0; /* set when trap is requested */ + +uint32 RDYQIN; /* fifo input index */ +uint32 RDYQOUT; /* fifo output index */ +uint32 RDYQ[128]; /* channel ready queue */ +uint8 waitqcnt = 0; /* # instructions before start */ + +struct InstHistory +{ + uint32 opsd1; /* original PSD1 */ + uint32 opsd2; /* original PSD2 */ + uint32 npsd1; /* new PSD1 after instruction */ + uint32 npsd2; /* new PSD2 after instruction */ + uint32 oir; /* the instruction itself */ + uint32 modes; /* current cpu mode bits */ + uint32 reg[16]; /* regs/bregs for operation */ +}; + +/* forward definitions */ +t_stat cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr, int32 sw); +t_stat cpu_dep(t_value val, t_addr addr, UNIT * uptr, int32 sw); +t_stat cpu_reset(DEVICE * dptr); +t_stat cpu_set_size(UNIT * uptr, int32 val, CONST char *cptr, void *desc); +t_stat cpu_show_hist(FILE * st, UNIT * uptr, int32 val, CONST void *desc); +t_stat cpu_set_hist(UNIT * uptr, int32 val, CONST char *cptr, void *desc); +uint32 cpu_cmd(UNIT * uptr, uint16 cmd, uint16 dev); +t_stat cpu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *cpu_description (DEVICE *dptr); +t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access); +t_stat load_maps(uint32 thepsd[2], uint32 lmap); +t_stat read_instruction(uint32 thepsd[2], uint32 *instr); +t_stat Mem_read(uint32 addr, uint32 *data); +t_stat Mem_write(uint32 addr, uint32 *data); + +/* external definitions */ +extern t_stat checkxio(uint16 addr, uint32 *status); /* XIO check in chan.c */ +extern t_stat startxio(uint16 addr, uint32 *status); /* XIO start in chan.c */ +extern t_stat testxio(uint16 addr, uint32 *status); /* XIO test in chan.c */ +extern t_stat stopxio(uint16 addr, uint32 *status); /* XIO stop in chan.c */ +extern t_stat rschnlxio(uint16 addr, uint32 *status); /* reset channel XIO */ +extern t_stat haltxio(uint16 addr, uint32 *status); /* halt XIO */ +extern t_stat grabxio(uint16 addr, uint32 *status); /* grab XIO n/u */ +extern t_stat rsctlxio(uint16 addr, uint32 *status); /* reset controller XIO */ +extern t_stat chan_set_devs(); /* set up the defined devices on the simulator */ +extern uint32 scan_chan(uint32 *ilev); /* go scan for I/O int pending */ +extern uint32 cont_chan(uint16 chsa); /* continue channel program */ +extern uint16 loading; /* set when doing IPL */ +extern int fprint_inst(FILE *of, uint32 val, int32 sw); /* instruction print function */ +extern int irq_pend; /* go scan for pending interrupt */ +extern void rtc_setup(uint32 ss, uint32 level); /* tell rtc to start/stop */ +extern void itm_setup(uint32 ss, uint32 level); /* tell itm to start/stop */ +extern int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level); /* read/write the interval timer */ +extern int16 post_csw(CHANP *chp, uint32 rstat); +extern DIB *dib_chan[MAX_CHAN]; + +/* floating point subroutines definitions */ +extern uint32 s_fixw(uint32 val, uint32 *cc); +extern uint32 s_fltw(uint32 val, uint32 *cc); +extern t_uint64 s_fixd(t_uint64 val, uint32 *cc); +extern t_uint64 s_fltd(t_uint64 val, uint32 *cc); +extern uint32 s_nor(uint32 reg, uint32 *exp); +extern t_uint64 s_nord(t_uint64 reg, uint32 *exp); +extern uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc); +extern uint32 s_sufw(uint32 reg, uint32 mem, uint32 *cc); +extern t_uint64 s_adfd(t_uint64 reg, t_uint64 mem, uint32 *cc); +extern t_uint64 s_sufd(t_uint64 reg, t_uint64 mem, uint32 *cc); +extern uint32 s_mpfw(uint32 reg, uint32 mem, uint32 *cc); +extern uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc); +extern t_uint64 s_mpfd(t_uint64 reg, t_uint64 mem, uint32 *cc); +extern t_uint64 s_dvfd(t_uint64 reg, t_uint64 mem, uint32 *cc); +extern uint32 s_normfw(uint32 mem, uint32 *cc); +extern t_uint64 s_normfd(t_uint64 mem, uint32 *cc); + +/* History information */ +int32 hst_p = 0; /* History pointer */ +int32 hst_lnt = 0; /* History length */ +struct InstHistory *hst = NULL; /* History stack */ + +/* CPU data structures + + cpu_dev CPU device descriptor + cpu_unit CPU unit descriptor + cpu_reg CPU register list + cpu_mod CPU modifiers list +*/ + +UNIT cpu_unit = + /* Unit data layout for CPU */ +/* { UDATA(rtc_srv, UNIT_BINK | MODEL(MODEL_27) | MEMAMOUNT(0), + * MAXMEMSIZE ), 120 }; */ + { + NULL, /* UNIT *next */ /* next active */ + NULL, /* t_stat (*action) */ /* action routine */ + NULL, /* char *filename */ /* open file name */ + NULL, /* FILE *fileref */ /* file reference */ + NULL, /* void *filebuf */ /* memory buffer */ + 0, /* uint32 hwmark */ /* high water mark */ + 0, /* int32 time */ /* time out */ + UNIT_IDLE|UNIT_FIX|UNIT_BINK|MODEL(MODEL_27)|MEMAMOUNT(4), /* flags */ + 0, /* uint32 dynflags */ /* dynamic flags */ + 0x800000, /* t_addr capac */ /* capacity */ + 0, /* t_addr pos */ /* file position */ + 0, /* void (*io_flush) */ /* io flush routine */ + 0, /* uint32 iostarttime */ /* I/O start time */ + 0, /* int32 buf */ /* buffer */ + 80, /* int32 wait */ /* wait */ +}; + +REG cpu_reg[] = { + {HRDATAD(PC, PC, 24, "Program Counter"), REG_FIT}, + {BRDATAD(PSD, PSD, 16, 32, 2, "Program Status Doubleword"), REG_FIT}, + {BRDATAD(GPR, GPR, 16, 32, 8, "Index registers"), REG_FIT}, + {BRDATAD(BR, BR, 16, 32, 8, "Base registers"), REG_FIT}, + {BRDATAD(BOOTR, BOOTR, 16, 32, 8, "Boot registers"), REG_FIT}, + {BRDATAD(SPAD, SPAD, 16, 32, 256, "CPU Scratchpad memory"), REG_FIT}, + {BRDATAD(MAPC, MAPC, 16, 32, 1024, "CPU map cache"), REG_FIT}, + {BRDATAD(TLB, TLB, 16, 32, 2048, "CPU Translation Lookaside Buffer"), REG_FIT}, + {HRDATAD(HIWM, HIWM, 32, "Max Maps Loaded"), REG_FIT}, + {HRDATAD(BPIX, BPIX, 32, "# Maps Loaded for O/S"), REG_FIT}, + {HRDATAD(CPIXPL, CPIXPL, 32, "Maximum Map # Loaded for User"), REG_FIT}, + {HRDATAD(CPIX, CPIX, 32, "Current CPIX user MPL offset"), REG_FIT}, + {HRDATAD(CPUSTATUS, CPUSTATUS, 32, "CPU Status Word"), REG_FIT}, + {HRDATAD(TRAPSTATUS, TRAPSTATUS, 32, "TRAP Status Word"), REG_FIT}, + {HRDATAD(CC, CC, 32, "Condition Codes"), REG_FIT}, + {HRDATAD(MODES, MODES, 32, "Mode bits"), REG_FIT}, + {BRDATAD(INTS, INTS, 16, 32, 112, "Interrupt Status"), REG_FIT}, + {HRDATAD(CMCR, CMCR, 32, "Cache Memory Control Register"), REG_FIT}, + {HRDATAD(SMCR, SMCR, 32, "Shared Memory Control Register"), REG_FIT}, + {HRDATAD(CMSMC, CMSMC, 32, "V9 Cache/Shadow Memory Configuration Word"), REG_FIT}, + {HRDATAD(CSMCW, CSMCW, 32, "V9 CPU Shadow Memory Configuration Word"), REG_FIT}, + {HRDATAD(ISMCW, ISMCW, 32, "V9 IPU Shadow Memory Configuration Word"), REG_FIT}, + {HRDATAD(CCW, CCW, 32, "Computer Configuration Word"), REG_FIT}, + {HRDATAD(CSW, CSW, 32, "Console Switches"), REG_FIT}, + {BRDATAD(RDYQ, RDYQ, 16, 32, 128, "Channel Program Completon Status"), REG_FIT}, + {HRDATAD(RDYQIN, RDYQIN, 32, "RDYQ input index"), REG_FIT}, + {HRDATAD(RDYQOUT, RDYQOUT, 32, "RDYQ output index"), REG_FIT}, + {NULL} +}; + +/* Modifier table layout (MTAB) - only extended entries have disp, reg, or flags */ +MTAB cpu_mod[] = { + { + /* MTAB table layout for cpu type */ + /* {UNIT_MODEL, MODEL(MODEL_55), "32/55", "32/55", NULL, NULL, NULL, "Concept 32/55"}, */ + UNIT_MODEL, /* uint32 mask */ /* mask */ + MODEL(MODEL_55), /* uint32 match */ /* match */ + "32/55", /* cchar *pstring */ /* print string */ + "32/55", /* cchar *mstring */ /* match string */ + NULL, /* t_stat (*valid) */ /* validation routine */ + NULL, /* t_stat (*disp) */ /* display routine */ + NULL, /* void *desc */ /* value desc, REG* if MTAB_VAL, int* if not */ + "Concept 32/55", /* cchar *help */ /* help string */ + }, + {UNIT_MODEL, MODEL(MODEL_75), "32/75", "32/75", NULL, NULL, NULL, "Concept 32/75"}, + {UNIT_MODEL, MODEL(MODEL_27), "32/27", "32/27", NULL, NULL, NULL, "Concept 32/27"}, + {UNIT_MODEL, MODEL(MODEL_67), "32/67", "32/67", NULL, NULL, NULL, "Concept 32/67"}, + {UNIT_MODEL, MODEL(MODEL_87), "32/87", "32/87", NULL, NULL, NULL, "Concept 32/87"}, + {UNIT_MODEL, MODEL(MODEL_97), "32/97", "32/97", NULL, NULL, NULL, "Concept 32/97"}, + {UNIT_MODEL, MODEL(MODEL_V6), "V6", "V6", NULL, NULL, NULL, "Concept V6"}, + {UNIT_MODEL, MODEL(MODEL_V9), "V9", "V9", NULL, NULL, NULL, "Concept V9"}, + { + /* MTAB table layout for cpu memory size */ + /* {UNIT_MSIZE, MEMAMOUNT(0), "128K", "128K", &cpu_set_size}, */ + UNIT_MSIZE, /* uint32 mask */ /* mask */ + MEMAMOUNT(0), /* uint32 match */ /* match */ + NULL, /* cchar *pstring */ /* print string */ + "128K", /* cchar *mstring */ /* match string */ + &cpu_set_size, /* t_stat (*valid) */ /* validation routine */ + NULL, /* t_stat (*disp) */ /* display routine */ + NULL, /* void *desc */ /* value desc, REG* if MTAB_VAL, int* if not */ + NULL, /* cchar *help */ /* help string */ + }, + {UNIT_MSIZE, MEMAMOUNT(1), NULL, "256K", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(2), NULL, "512K", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(3), NULL, "1M", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(4), NULL, "2M", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(5), NULL, "3M", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(6), NULL, "4M", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(7), NULL, "6M", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(8), NULL, "8M", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(9), NULL, "12M", &cpu_set_size}, + {UNIT_MSIZE, MEMAMOUNT(10), NULL, "16M", &cpu_set_size}, + {MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle}, + {MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL}, + {MTAB_XTD | MTAB_VDV | MTAB_NMO | MTAB_SHP, 0, "HISTORY", "HISTORY", + &cpu_set_hist, &cpu_show_hist}, + {0} +}; + +/* CPU device descriptor */ +DEVICE cpu_dev = { + /* "CPU", &cpu_unit, cpu_reg, cpu_mod, + 1, 8, 24, 1, 8, 32, + &cpu_ex, &cpu_dep, &cpu_reset, NULL, NULL, NULL, + NULL, DEV_DEBUG, 0, dev_debug, + NULL, NULL, &cpu_help, NULL, NULL, &cpu_description */ + "CPU", /* cchar *name */ /* device name */ + &cpu_unit, /* UNIT *units */ /* unit array */ + cpu_reg, /* REG *registers */ /* register array */ + cpu_mod, /* MTAB *modifiers */ /* modifier array */ + 1, /* uint32 numunits */ /* number of units */ + 16, /* uint32 aradix */ /* address radix */ + 32, /* uint32 awidth */ /* address width */ + 1, /* uint32 aincr */ /* address increment */ + 16, /* uint32 dradix */ /* data radix */ + 8, /* uint32 dwidth */ /* data width */ + &cpu_ex, /* t_stat (*examine) */ /* examine routine */ + &cpu_dep, /* t_stat (*deposit) */ /* deposit routine */ + &cpu_reset, /* t_stat (*reset) */ /* reset routine */ + NULL, /* t_stat (*boot) */ /* boot routine */ + NULL, /* t_stat (*attach) */ /* attach routine */ + NULL, /* t_stat (*detach) */ /* detach routine */ + NULL, /* void *ctxt */ /* (context) device information block pointer */ + DEV_DEBUG, /* uint32 flags */ /* device flags */ + 0, /* uint32 dctrl */ /* debug control flags */ + dev_debug, /* DEBTAB *debflags */ /* debug flag name array */ + NULL, /* t_stat (*msize) */ /* memory size change routine */ + NULL, /* char *lname */ /* logical device name */ + &cpu_help, /* t_stat (*help) */ /* help function */ + NULL, /* t_stat (*attach_help) *//* attach help function */ + NULL, /* void *help_ctx */ /* Context available to help routines */ + &cpu_description, /* cchar *(*description) *//* Device description */ + NULL, /* BRKTYPTB *brk_types */ /* Breakpoint types */ +}; + +/* CPU Instruction decode flags */ +#define INV 0x0000 /* Instruction is invalid */ +#define HLF 0x0001 /* Half word instruction */ +#define ADR 0x0002 /* Normal addressing mode */ +#define IMM 0x0004 /* Immediate mode */ +#define WRD 0x0008 /* Word addressing, no index */ +#define SCC 0x0010 /* Sets CC */ +#define RR 0x0020 /* Read source register */ +#define R1 0x0040 /* Read destination register */ +#define RB 0x0080 /* Read base register into dest */ +#define SD 0x0100 /* Stores into destination register */ +#define RNX 0x0200 /* Reads memory without sign extend */ +#define RM 0x0400 /* Reads memory */ +#define SM 0x0800 /* Stores memory */ +#define DBL 0x1000 /* Double word operation */ +#define SB 0x2000 /* Store Base register */ +#define BT 0x4000 /* Branch taken, no PC incr */ +#define SF 0x8000 /* Special flag */ + +int nobase_mode[] = { + /* 00 04 08 0C */ + /* 00 ANR, ORR, EOR */ + HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF, + + /* 10 14 18 1C */ + /* CAR, CMR, SBR ZBR */ + HLF, HLF, HLF, HLF, + + /* 20 24 28 2C */ + /* ABR TBR REG TRR */ + HLF, HLF, HLF, HLF, + + /* 30 34 38 3C */ + /* CALM LA ADR SUR */ + HLF, SD|ADR, HLF, HLF, + + /* 40 44 48 4C */ + /* MPR DVR */ + SCC|SD|HLF, HLF, HLF|INV, HLF|INV, + + /* 50 54 58 5C */ + /* */ + HLF|INV, HLF|INV, HLF|INV, HLF|INV, + + /* 60 64 68 6C */ + /* NOR NORD SCZ SRA */ + HLF, HLF, HLF, HLF, + + /* 70 74 78 7C */ + /* SRL SRC SRAD SRLD */ + HLF, HLF, HLF, HLF, + + /* 80 84 88 8C */ + /* LEAR ANM ORM EOM */ + SD|ADR, SD|RR|RNX|ADR, SD|RR|RNX|ADR, SD|RR|RNX|ADR, + + /* 90 94 98 9C */ + /* CAM CMM SBM ZBM */ + SCC|RR|RM|ADR, RR|RM|ADR, ADR, ADR, + + /* A0 A4 A8 AC */ + /* ABM TBM EXM L */ + ADR, ADR, ADR, SCC|SD|RM|ADR, + + /* B0 B4 B8 BC */ + /* LM LN ADM SUM */ + SCC|SD|RM|ADR, SCC|SD|RM|ADR, SD|RR|RM|ADR, SD|RR|RM|ADR, + + /* C0 C4 C8 CC */ + /* MPM DVM IMM LF */ + SCC|SD|RM|ADR, RM|ADR, IMM, ADR, + + /* D0 D4 D8 DC */ + /* LEA ST STM STF */ + SD|ADR, RR|SM|ADR, RR|SM|ADR, ADR, + + /* E0 E4 E8 EC */ + /* ADF MPF ARM BCT */ + ADR, ADR, SM|RR|RNX|ADR, ADR, + + /* F0 F4 F8 FC */ + /* BCF BI MISC IO */ + ADR, RR|SD|WRD, ADR, IMM, +}; + +int base_mode[] = { + /* 00 04 08 0C */ + /* 00 AND, OR, EOR */ + HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF, + + /* 10 14 18 1C */ + /* SACZ CMR xBR SRx */ + HLF, HLF, HLF, HLF, + + /* 20 24 28 2C */ + /* SRxD SRC REG TRR */ + HLF, HLF, HLF, HLF, + + /* 30 34 38 3C */ + /* LA FLRop SUR */ + INV, INV, HLF, HLF, + + /* 40 44 48 4C */ + /* */ + INV, INV, INV, INV, + + /* 50 54 58 5C */ + /* LA BASE BASE CALLM */ + SD|ADR, SM|ADR, SB|ADR, RM|ADR, + + /* 60 64 68 6C */ + /* */ + INV, INV, INV, INV, + + /* 70 74 78 7C */ + /* */ + INV, INV, INV, INV, + + /* LEAR ANM ORM EOM */ + /* 80 84 88 8C */ + SD|ADR, SD|RR|RNX|ADR, SD|RR|RNX|ADR, SD|RR|RNX|ADR, + + /* CAM CMM SBM ZBM */ + /* 90 94 98 9C */ + SCC|RR|RM|ADR, RR|RM|ADR, ADR, ADR, + + /* A0 A4 A8 AC */ + /* ABM TBM EXM L */ + ADR, ADR, ADR, SCC|SD|RM|ADR, + + /* B0 B4 B8 BC */ + /* LM LN ADM SUM */ + SCC|SD|RM|ADR, SCC|SD|RM|ADR, SD|RR|RM|ADR, SD|RR|RM|ADR, + + /* C0 C4 C8 CC */ + /* MPM DVM IMM LF */ + SCC|SD|RM|ADR, RM|ADR, IMM, ADR, + + /* D0 D4 D8 DC */ + /* LEA ST STM STFBR */ + INV, RR|SM|ADR, RR|SM|ADR, ADR, + + /* E0 E4 E8 EC */ + /* ADF MPF ARM BCT */ + ADR, ADR, SM|RR|RNX|ADR, ADR, + + /* F0 F4 F8 FC */ + /* BCF BI MISC IO */ + ADR, RR|SD|WRD, ADR, IMM, +}; + +/* Map image descriptor 32/77 */ +/* |--------------------------------------| */ +/* |0|1|2|3 4 5 6|7 8 9 10 11 12 13 14 15| */ +/* |N|V|P| n/u | 9 bit map block entry | */ +/* |U| | | | 32kb/block | */ +/* | | 32 8kb maps per task | */ +/* | | 1 mb address space | */ +/* |--------------------------------------| */ + +/* Map image descriptor 32/27 */ +/* |--------------------------------------| */ +/* |0|1|2|3|4|5 6 7 8 9 10 11 12 13 14 15| */ +/* |V|P|P|P|P| 11 bit map block entry | */ +/* | |1|2|3|4| 8kb/block | */ +/* | | 256 8kb maps per task | */ +/* | | 2 mb address space | */ +/* |--------------------------------------| */ + +/* Map image descriptor 32/67, 32/87, 32/97 */ +/* |--------------------------------------| */ +/* |0|1|2|3|4|5 6 7 8 9 10 11 12 13 14 15| */ +/* |V|P|P|P|P| 11 bit map block entry | */ +/* | |1|2|3|4| 2kb/block | */ +/* | | 2048 8kb maps per task | */ +/* | | 16 mb address space | */ +/* |--------------------------------------| */ +/* BIT 0 = 0 Invalid map block (page) entry */ +/* = 1 Valid map block (page) entry */ +/* 1 = 0 000-7ff of 8kb page is not write protected */ +/* = 1 000-7ff of 8kb page is write protected */ +/* 2 = 0 800-fff of 8kb page is not write protected */ +/* = 1 800-fff of 8kb page is write protected */ +/* 3 = 0 1000-17ff of 8kb page is not write protected */ +/* = 1 1000-17ff of 8kb page is write protected */ +/* 4 = 0 1800-1fff of 8kb page is not write protected */ +/* = 1 1800-1fff of 8kb page is write protected */ +/* 5-15 = 11 most significant bits of the 24 bit real address for page */ + +/* Map image descriptor V6 & V9 */ +/* |--------------------------------------| */ +/* |0|1|2|3|4|5 6 7 8 9 10 11 12 13 14 15| */ +/* |V|P|P|M|M| 11 bit map block entry | */ +/* | |1|2|M|A| 2kb/map | */ +/* | | 2048 8kb maps per task | */ +/* | | 16 mb address space | */ +/* |--------------------------------------| */ +/* BIT 0 = 0 Invalid map block (page) entry */ +/* = 1 Valid map block (page) entry */ +/* */ +/* PSD 1 BIT 0 - Map Bit 1 - Map Bit 2 - Access state */ +/* Priv Bits with ECO for Access Protection change */ +/* 0 0 0 No access allowed to page */ +/* 0 0 1 No access allowed to page */ +/* 0 1 0 Read/Write/Execute access */ +/* 0 1 1 Read/Execute access only */ +/*O/S*/ +/* 1 0 0 Read/Write/Execute access */ +/* 1 0 1 Read/Execute access only */ +/* 1 1 0 Read/Write/Execute access */ +/* 1 1 1 Read/Execute access only */ +/* Priv Bits without ECO for Access Protection change */ +/* 0 0 0 No access allowed to page */ +/* 0 0 1 Read/Execute access only */ +/* 0 1 0 Read//Execute access only */ +/* 0 1 1 Read/Write/Execute access */ +/*O/S*/ +/* 1 0 0 Read/Write/Execute only */ +/* 1 0 1 Read/Execute access only */ +/* 1 1 0 Read/Write/Execute access */ +/* 1 1 1 Read/Write/Execute access */ +/* */ +/* BIT 3 = 0 (MM) A first write (modify) to the map block (page) has not occurred */ +/* = 1 (MM) A first write (modify) to the map block (page) has occurred */ +/* BIT 4 = 0 (MA) A first read or write (access) to the map block (page) has not occurred */ +/* = 1 (MA) A first read or write (access) to the map block (page) has occurred */ +/* 5-15 = 11 most significant bits of the 24 bit real address for page */ + +/* Note */ +/* If a map is valid, a MAP (page) hit occurs and logical to physical translation occures */ +/* If the map is not valid, a demand MAP (page) fault occures and the faulting page is provided */ +/* P1 and P2 are used with Bit 0 of PSD to define the access rights */ +/* A privilege violation trap occurres if access it denied */ +/* Bits 5-15 contain the 11 most-significant bits of the physical address */ +/* MSD 0 page limit is used to verify access to O/S pages */ +/* CPIXPL page limit is used to verify access to user pages and page faults */ +/* CPIX CPIX of user MPL offset */ +/* Access to pages outside the limit registers results in a map fault */ + +#define MAX32 32 /* 32/77 map limit */ +#define MAX256 256 /* 32/27 and 32/87 map limit */ +#define MAX2048 2048 /* 32/67, V6, and V9 map limit */ + +/* set up the map registers for the current task in the cpu */ +/* the PSD bpix and cpix are used to setup the maps */ +/* return non-zero if mapping error */ +/* if lmap set, always load maps on 67, 97, V6, and V7 */ +/* The RMW and WMW macros are used to read/write memory words */ +/* RMW(addr) or WMW(addr, data) where addr is a byte alligned word address */ +/* The RMR and WMR macros are used to read/write the MAPC cache registers */ +/* RMR(addr) or WMR(addr, data) where addr is a half word alligned address */ +/* We will only get here if the retain maps bit is not set in PSD word 2 */ +t_stat load_maps(uint32 thepsd[2], uint32 lmap) +{ + uint32 num, sdc, spc, onlyos=0; + uint32 mpl, cpixmsdl, bpixmsdl, msdl, midl; + uint32 cpix, bpix, i, j, map, osmsdl, osmidl; + uint32 MAXMAP = MAX2048; /* default to 2048 maps */ + + sim_debug(DEBUG_TRAP, &cpu_dev, + "Load Maps Entry PSD %08x %08x STATUS %08x lmap %1x CPU Mode %2x\n", + thepsd[0], thepsd[1], CPUSTATUS, lmap, CPU_MODEL); + + /* process 32/7X computers */ + if (CPU_MODEL < MODEL_27) { + MAXMAP = MAX32; /* 32 maps for 32/77 */ + /* 32/7x machine, 8KW maps 32 maps total */ + MODES &= ~BASEBIT; /* no basemode on 7x */ + if ((thepsd[1] & 0xc0000000) == 0) /* mapped mode? */ + return ALLOK; /* no, all OK, no mapping required */ + + /* we are mapped, so load the maps for this task into the cpu map cache */ + cpix = (thepsd[1]) & 0x3ff8; /* get cpix 12 bit offset from psd wd 2 */ + bpix = (thepsd[1] >> 16) & 0x3ff8; /* get bpix 12 bit offset from psd wd 2 */ + num = 0; /* working map number */ + + /* master process list is in 0x83 of spad for 7x */ + mpl = SPAD[0x83]; /* get mpl from spad address */ + + /* diags want the mpl entries checked to make sure valid dbl wowrd address */ + if (mpl & 0x7) { /* test for double word address */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MPL not on double word boundry %06x\n", mpl); + TRAPSTATUS |= BIT20; /* set bit 20 of trap status */ + return MAPFLT; /* not dbl bound, map fault error */ + } + + /* check if valid real address */ + if ((mpl == 0) || !MEM_ADDR_OK(mpl & MASK24)) { /* see if in memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE7 %06x mpl %06x invalid\n", + MEMSIZE, mpl); + TRAPSTATUS |= BIT18; /* set bit 18 of trap status */ + return MAPFLT; /* no, map fault error */ + } + + /* mpl is ok, get the msdl for given cpix */ + cpixmsdl = RMW(mpl+cpix); /* get msdl from mpl for given cpix */ + + /* if bit zero of mpl entry is set, use bpix first to load maps */ + if (cpixmsdl & BIT0) { + + /* load bpix maps first */ + bpixmsdl = RMW(mpl+bpix); /* get bpix msdl word address */ + + /* check for valid bpix msdl addr */ + if (!MEM_ADDR_OK(bpixmsdl & MASK24)) { /* see if in memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE8 %06x bpix msdl %08x invalid\n", + MEMSIZE, bpixmsdl); + return NPMEM; /* no, none present memory error */ + } + + sdc = (bpixmsdl >> 24) & 0x3f; /* get 6 bit segment description count */ + msdl = bpixmsdl & MASK24; /* get 24 bit real address of msdl */ + /* check for valid msdl addr */ + if (!MEM_ADDR_OK(msdl & MASK24)) { /* see if in memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE9 %06x msdl %08x invalid\n", MEMSIZE, msdl); + return NPMEM; /* no, none present memory error */ + } + + /* process all of the msdl's */ + for (i = 0; i < sdc; i++) { /* loop through the msd's */ + spc = (RMW(msdl+i) >> 24) & 0xff; /* get segment page count from msdl */ + midl = RMW(msdl+i) & MASK24; /* get 24 bit real word address of midl */ + + /* check for valid midl addr */ + if (!MEM_ADDR_OK(midl & MASK24)) { /* see if in memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZEa %06x midl %08x invalid\n", MEMSIZE, midl); + return NPMEM; /* no, none present memory error */ + } + + for (j = 0; j < spc; j++, num++) { /* loop throught the midl's */ + uint32 pad = RMW(midl+(j<<1)); /* get page descriptor address */ + if (num >= MAXMAP) { + TRAPSTATUS |= BIT5; /* set bit 5 of trap status */ + return MAPFLT; /* map loading overflow, map fault error */ + } + /* load 16 bit map descriptors */ + map = RMH(pad); /* get 16 bit map entries */ + WMR((num<<1), map); /* store the map reg contents into cache */ + } + } + } + + /* now load cpix maps */ + /* check for valid cpix msdl addr */ + if (MEM_ADDR_OK(cpixmsdl & MASK24)) { /* see if in memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZEb %06x cpix msdl %08x invalid\n", MEMSIZE, cpixmsdl); + return NPMEM; /* no, none present memory error */ + } + + sdc = (cpixmsdl >> 24) & 0x3f; /* get 6 bit segment description count */ + msdl = cpixmsdl & 0xffffff; /* get 24 bit real address of msdl */ + /* check for valid msdl addr */ + if (!MEM_ADDR_OK(msdl & MASK24)) { /* see if in memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZEc %06x msdl %08x invalid\n", MEMSIZE, msdl); + return NPMEM; /* no, none present memory error */ + } + + /* process all of the msdl's */ + for (i = 0; i < sdc; i++) { + spc = (RMW(msdl+i) >> 24) & 0xff; /* get segment page count from msdl */ + midl = RMW(msdl+i) & MASK24; /* get 24 bit real word address of midl */ + + /* check for valid midl addr */ + if (!MEM_ADDR_OK(midl & MASK24)) { /* see if in memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZEd %06x midl %08x invalid\n", MEMSIZE, midl); + return NPMEM; /* no, none present memory error */ + } + + for (j = 0; j < spc; j++, num++) { /* loop through the midl's */ + uint32 pad = RMW(midl+(j<<1)); /* get page descriptor address */ + if (num >= MAXMAP) { + TRAPSTATUS |= (BIT16|BIT9); /* set bit 5 of trap status */ + return MAPFLT; /* map loading overflow, map fault error */ + } + /* load 16 bit map descriptors */ + map = RMH(pad); /* get 16 bit map entries */ + WMR((num<<1), map); /* store the map reg unmodified into cache */ + } + } + /* if none loaded, map fault */ + if (num == 0) { + TRAPSTATUS |= (BIT16|BIT9); /* set bit 5 of trap status */ + return MAPFLT; /* attempt to load 0 maps, map fault error */ + } + /* clear the rest of the previously used maps */ + for (i = num; i < HIWM; i++) /* zero any remaining entries */ + WMR((i<<1), 0); /* clear the map entry to make not valid */ + HIWM = num; /* set new high water mark */ + return ALLOK; /* all cache is loaded, return OK */ + } + /****************** END-OF-32/7X-MAPPING ********************/ + + /* process a 32/27, 32/67, 32/87, 32/97, V6, or V9 here with 2KW (8kb) maps */ + /* 32/27 & 32/87 have 256 maps. Others have 2048 maps */ + /* 32/27 & 32/87 must have all maps preallocated and loaded */ + /* 32/67 & 32/97 must load O/S maps and have user preallocated maps loaded on access */ + /* V6 and V9 must load O/S maps and have user maps allocated and loaded on access */ + + /* See if any mapping to take place */ + if ((MODES & MAPMODE) == 0) /* mapped mode? */ + return ALLOK; /* no, all OK, no mapping required */ + + /* set maximum maps for 32/27 and 32/87 processors */ + if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_87)) + MAXMAP = MAX256; /* only 256 2KW (8kb) maps */ + + /* we are mapped, so load the map definitions */ + cpix = thepsd[1] & 0x3ff8; /* get cpix 11 bit offset from psd wd 2 */ + num = 0; /* no maps loaded yet */ + + /* master process list is in 0xf3 of spad for concept machines */ + mpl = SPAD[0xf3]; /* get mpl from spad address */ + + /* diags want the mpl entries checked to make sure valid dbl word address */ + if (mpl & 0x7) { /* test for double word address */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MPL not on double word boundry %06x\n", mpl); + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT6; /* set bit 6 of trap status */ + else + TRAPSTATUS |= BIT20; /* set bit 20 of trap status */ + return MAPFLT; /* no, map fault error */ + } + + /* check if valid real address */ + mpl &= MASK24; /* clean mpl address */ + if (!MEM_ADDR_OK(mpl)) { /* see if in our real memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE1 %06x mpl %06x invalid\n", MEMSIZE, mpl); +npmem: + BPIX = 0; /* no os maps loaded */ + CPIXPL = 0; /* no user pages */ + CPIX = cpix; /* save user CPIX */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + } else + TRAPSTATUS |= BIT10; /* set bit 8 of trap status */ + return NPMEM; /* non present memory error */ + } + + /* output O/S and User MPL entries */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "#MEMORY %06x MPL %06x MPL[0] %08x %06x MPL[%04x] %08x %06x\n", + MEMSIZE, mpl, RMW(mpl), RMW(mpl+4), cpix, + RMW(cpix+mpl), RMW(cpix+mpl+4)); + sim_debug(DEBUG_DETAIL, &cpu_dev, + "MEMORY2 %06x BPIX %04x cpix %04x CPIX %04x CPIXPL %04x HIWM %04x\n", + MEMSIZE, BPIX, cpix, CPIX, CPIXPL, HIWM); + + /* load the users regs first or the O/S. Verify the User MPL entry too. */ + /* If bit zero of cpix mpl entry is set, use msd entry 0 first to load maps */ + /* Then load the user maps after the O/S */ + /* If the cpix is zero, then only load the O/S. */ + /* This test must be made to allow sysgen to run with a zero cpix */ + /* If bit 0 of MPL[0] is 0, load the O/S maps. */ + /* Do not load O/S if bit 0 of O/S MPL[0] is set. It is set by the */ + /* swapper on MPX startup */ + + /* mpl is valid, get msdls for O/S and User */ + osmidl = RMW(mpl); /* get O/S map count & retain flag from MPL[0] */ + osmsdl = RMW(mpl+4); /* get msdl pointer for OS from MPL[1] */ + midl = RMW(mpl+cpix); /* get midl entry for given user cpix */ + msdl = RMW(mpl+cpix+4); /* get mpl entry wd 1 for given cpix */ + spc = osmidl & MASK16; /* get 16 bit O/S segment description count */ + + /* see if we are to only load the O/S */ + if (cpix == 0) { + CPIX = cpix; /* save CPIX */ + onlyos = 1; /* flag to only load O/S, nothing else */ + if (osmidl & BIT0) { /* see if the O/S retain bit 0 is on */ + return ALLOK; /* O/S retain bit is set, no mapping required */ + } + +loados: /* merge point for loading O/S first */ + /* to be followed by user maps */ + /* the retain bit is not set so load the O/S */ + if (spc > MAXMAP) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps bad O/S page count %04x, map fault\n", spc); +nomaps: + /* Bad map load count specified. */ + BPIX = 0; /* no os maps loaded */ + CPIXPL = 0; /* no user pages */ + CPIX = cpix; /* save CPIX */ + HIWM = 0; /* reset high water mark */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= (BIT5|BIT9); /* set bit 5/9 of trap status */ + else + TRAPSTATUS |= BIT16; /* set bit 16 of trap status */ + return MAPFLT; /* map loading overflow, map fault error */ + } + + /* we have a valid count, load the O/S map list address */ + osmsdl &= MASK24; /* get 24 bit real address from mpl 0 wd2 */ + if (!MEM_ADDR_OK(osmsdl)) { /* see if address is within our memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE2 %06x os page list address %06x invalid\n", + MEMSIZE, osmsdl); + goto npmem; /* non present memory trap */ + } + + /* load the O/S maps */ + for (j = 0; j < spc; j++, num++) { /* copy maps from msdl to map cache */ + uint32 pad = osmsdl+(j<<1); /* get page descriptor address */ + + /* see if map overflow */ + if (num >= MAXMAP) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps O/S page count overflow %04x, map fault\n", num); + goto nomaps; /* map overflow, map fault trap */ + } + if (!MEM_ADDR_OK(pad)) { /* see if address is within our memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE3 %06x os page address %06x invalid\n", + MEMSIZE, pad); + goto npmem; /* non present memeory trap */ + } + /* load 16 bit map descriptors */ + map = RMH(pad); /* get page descriptor from memory */ + + /* for valid maps translate the map number to a real address */ + /* put this address in the TLB for later translation */ + /* copy the map status bits too and set hit bit in the TLB */ + if (map & 0x8000) { /* see if map is valid */ + TLB[num] = (((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000)); + TLB[num] |= 0x04000000; /* set HIT bit for non lmap */ + WMR((num<<1), map); /* store the map unmodified into cache */ + } else { + TLB[num] = 0; /* clear the TLB for non valid maps */ + } + } + BPIX = num; /* save the # maps loaded in O/S */ + CPIXPL = 0; /* no user pages */ + + if (!onlyos) /* see if only O/S to be loaded */ + goto loaduser; /* no, go load the user maps */ + + for (i = BPIX; i < MAXMAP; i++) /* zero any remaining entries */ + TLB[i] = 0; /* clear look aside buffer */ + + /* Only the O/S is to be loaded, finish up & return */ + HIWM = num; /* set new high water mark */ + return ALLOK; /* all cache is loaded, return OK */ + } + + /* The csect is not zero here, so see what we have to do */ + /* See if O/S is to be loaded first because user MPL entry has BIT 0 set */ + if (midl & BIT0) { + /* the user wants the O/S to load first, if the O/S retain bit set? */ + if (osmidl & BIT0) { /* see if the O/S retain bit 0 is on */ + num = spc; /* yes, set the number of O/S maps loaded */ + BPIX = spc; /* save the # maps in O/S */ + goto loaduser; /* load user map only or after O/S */ + } + + /* no retain bit, load user maps only, or after O/S */ + /* validate O/S map count */ + if (spc > MAXMAP) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps bad O/S page count %04x, map fault\n", spc); + goto nomaps; /* we have error, make way out */ + } + + /* see if any O/S maps to load */ + if (spc == 0) { + BPIX = 0; /* no os maps loaded */ + /* O/S page count is zero, so just load the user */ + goto loaduser; /* load user map only or after O/S */ + } + /* user wants to have O/S loaded first */ + onlyos = 0; /* return to loaduser after loading O/S */ + goto loados; /* go load the O/S */ + } + + /* the user wants to only load the user maps, no O/S maps are to be retained */ + BPIX = 0; /* clear O/S loaded page count */ + num = 0; /* nothing loaded yet */ + /****************** END-OF-O/S-MAPPING ********************/ + +loaduser: + spc = midl & MASK16; /* get 16 bit User page count */ + + /* see if O/S has already loaded the MAXMAPS */ + /* if borrow bit is on and cpix count is zero, return ok */ + /* if borrow bit is on and cpix count not zero, map overflow error */ + if (BPIX == MAXMAP) { + HIWM = num; /* set new high water mark */ + CPIXPL = 0; /* no user pages */ + if ((midl & BIT0) && (spc == 0)) { /* see if the user had borrow bit on */ + sim_debug(DEBUG_CMD, &cpu_dev, + "load_maps @loaduser num %04x BPIX loaded %04x load done\n", num, BPIX); + return ALLOK; /* all cache is loaded, return OK */ + } + else { + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps map overflow BPIX %04x count %04x, map fault\n", BPIX, spc); + goto nomaps; /* we have error, make way out */ + } + } + + /* the O/S has been loaded if requested or retained, so now load the user */ + msdl &= MASK24; /* get 24 bit real word address of msdl */ + + /* This test fails cn.mmm diag at test 46, subtest 2 with unexpected error */ + /* Do this test if we are a LMAP instruction and not a 32/27 or 32/87 */ + if (lmap && !MEM_ADDR_OK(msdl)) { /* see if address is within our memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE4 %06x user page list address %06x invalid\n", + MEMSIZE, msdl); + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + } else + TRAPSTATUS |= BIT28; /* set bit 28 of trap status */ + return NPMEM; /* non present memory error */ + } + + /* We have a valid user MPL[cpix] address, msdl */ + spc = midl & MASK16; /* get 16 bit User page count */ + + /* it is OK here to have no O/S maps loaded, num can be 0 */ + if ((spc > MAXMAP) || ((spc+BPIX) > MAXMAP)) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps bad User page count %04x num %04x bpix %04x, map fault\n", + spc, num, BPIX); + /* Bad map load count specified. */ + BPIX = 0; /* no os maps loaded */ + CPIXPL = 0; /* no user pages */ + CPIX = cpix; /* save CPIX */ + HIWM = 0; /* reset high water mark */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= (BIT5|BIT9); /* set bit 5/9 of trap status */ + else + TRAPSTATUS |= BIT16; /* set bit 16 of trap status */ + return MAPFLT; /* map overflow fault error */ + } + CPIX = cpix; /* save user MPL offset (cpix) */ + CPIXPL = spc; /* save user map load count */ + + /* Load maps for 32/27 aand 32/87 */ + if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_87)) { + + sim_debug(DEBUG_CMD, &cpu_dev, + "load_maps Processing 32/27 & 32/87 Model# %02x\n", CPU_MODEL); + + /* handle non virtual page loading or diag LMAP instruction */ + /* do 32/27 and 32/87 that force load all maps */ + /* now load user maps specified by the cpix value */ + for (j = 0; j < spc; j++, num++) { /* copy maps from midl to map cache */ + uint32 pad = msdl+(j<<1); /* get page descriptor address */ + + /* see if map overflow */ + if (num >= MAXMAP) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps User page count overflow %04x, map fault\n", num); + TRAPSTATUS |= BIT16; /* set bit 16 of trap status */ + TRAPSTATUS |= (BIT5|BIT9); /* set bit 5 of trap status */ + goto nomaps; /* map overflow, map fault trap */ + } + if (!MEM_ADDR_OK(pad)) { /* see if address is within our memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE5 %06x User page address %06x invalid\n", + MEMSIZE, pad); + goto npmem; /* non present memeory trap */ + } + /* load 16 bit map descriptors */ + map = RMH(pad); /* get page descriptor from memory */ + + /* for valid maps translate the map number to a real address */ + /* put this address in the TLB for later translation */ + /* copy the map status bits too and set hit bit in the TLB */ + /* leaving out diags in next statment fails test3/1 of vm.mmm */ + if ((map & 0x8000)) { /* see if map is valid */ + TLB[num] = (((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000)); + TLB[num] |= 0x04000000; /* set HIT bit on */ + } else + TLB[num] = 0; /* clear the TLB for non valid maps */ + WMR((num<<1), map); /* store map unmodified into cache */ + } + if (num == 0) { /* see if any maps loaded */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps1 No maps loaded %04x, map fault\n", num); + goto nomaps; /* return map fault error */ + } + + /* All maps are now loaded, finish up & return */ + for (i = num; i < MAXMAP; i++) /* zero any remaining TLB entries */ + TLB[i] = 0; /* clear look aside buffer */ + + HIWM = num; /* set new high water mark */ + return ALLOK; /* all cache is loaded, return OK */ + } + /**************END-OF-NON-VIRTUAL-USER-MAPPING-FOR-27-87************/ + + sim_debug(DEBUG_CMD, &cpu_dev, + "load_maps Processing 32/67 & 32/97 Model# %02x\n", CPU_MODEL); + + /* handle load on memory access case for 67, 97, V6 & V9 */ + /* now clear TLB & maps specified by the cpix value */ + for (j = 0; j < spc; j++, num++) { /* clear maps in map cache */ + uint32 pad = msdl+(j<<1); /* get page descriptor address */ + + /* if this is a LPSDCM instruction, just clear the TLB entry */ + if (!lmap) { + /* load 16 bit map descriptors */ + map = RMH(pad); /* get page descriptor from memory */ + TLB[num] = 0; /* clear the TLB for non valid maps */ + if ((num < 0x20) || (num > (spc+BPIX) - 0x10)) + sim_debug(DEBUG_DETAIL, &cpu_dev, + "UserV pad %06x=%04x map #%4x, %04x, map2 %08x, TLB %08x, MAPC %08x\n", + pad, map, num, map, (((map << 16) & 0xf8000000)|(map & 0x7ff)<<13)|0x04000000, + TLB[num], MAPC[num/2]); + continue; /* just clear the TLBs */ + } + + /* only do the following tests for LMAP instruction, not LPSDCM */ + /* see if map overflow */ + if (num >= MAXMAP) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps User page count overflow %04x, map fault\n", num); + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= (BIT5|BIT9); /* set bit 5/9 of trap status */ + else + TRAPSTATUS |= BIT16; /* set bit 16 of trap status */ + goto nomaps; /* map overflow, map fault trap */ + } + + if (!MEM_ADDR_OK(pad)) { /* see if address is within our memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps MEM SIZE6 %06x User page address %06x non present\n", + MEMSIZE, pad); + goto npmem; /* non present memeory trap */ + } + + /* load 16 bit map descriptors */ + map = RMH(pad); /* get page descriptor from memory */ + + if (lmap) { + TLB[num] = (((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000)); + TLB[num] |= 0x04000000; /* set HIT bit for lmap */ + /* removing this store of map fails test 2 on 97 */ + WMR((num<<1), map); /* store the map unmodified into cache */ + } + + if ((num < 0x20) || (num > (spc+BPIX) - 0x10)) + sim_debug(DEBUG_DETAIL, &cpu_dev, + "UserV2 pad %06x=%04x map #%4x, %04x, map2 %08x, TLB %08x, MAPC %08x\n", + pad, map, num, map, (((map << 16) & 0xf8000000)|(map & 0x7ff)<<13)|0x04000000, + TLB[num], MAPC[num/2]); + } + + if (num == 0) { /* see if any maps loaded */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "load_maps2 No maps loaded %04x, map fault\n", num); + goto nomaps; + } + + /* All maps are now loaded, finish up & return */ + /* removing this code causes diag to stop at 17/0 for 97 in cn.mmm */ + for (i = num; i < MAXMAP; i++) /* zero any remaining entries */ + TLB[i] = 0; /* clear look aside buffer */ + + HIWM = num; /* set new high water mark */ + return ALLOK; /* all cache is loaded, return OK */ + /****************** END-OF-VIRTUAL-USER-MAP-LOADING ********************/ +} + +/* + * Return the real memory address from the logical address + * Also return the protection status, 1 if write protected address. + * For 67, 97, V6, & V9 return all protection bits. + * Addr is a byte address. + */ +t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access) +{ + uint32 word, index, map, raddr, mpl, offset; + uint32 nix, msdl, mix; + + *prot = 0; /* show unprotected memory as default */ + /* unmapped mode is unprotected */ + + /*****************START-7X-ADDRESS-PROCESSING****************/ + /* see what machine we have */ + if (CPU_MODEL < MODEL_27) { + /* 32/7x machine with 8KW maps */ + if (MODES & EXTDBIT) + word = addr & 0xfffff; /* get 20 bit logical word address */ + else + word = addr & 0x7ffff; /* get 19 bit logical word address */ + if ((MODES & MAPMODE) == 0) { + /* check if valid real address */ + if (!MEM_ADDR_OK(word)) { /* see if address is within our memory */ + return NPMEM; /* no, none present memory error */ + } + *realaddr = word; /* return the real address */ + return ALLOK; /* all OK, return instruction */ + } + + /* we are mapped, so calculate real address from map information */ + /* 32/7x machine, 8KW maps */ + index = word >> 15; /* get 4 or 5 bit value */ + map = RMR((index<<1)); /* read the map reg cache contents */ + + /* see if map is valid */ + if ((map & 0x4000) == 0) + /* map is invalid, so return map fault error */ + return MAPFLT; /* map fault error */ + + /* required map is valid, get 9 bit address and merge with 15 bit page offset */ + word = ((map & 0x1ff) << 15) | (word & 0x7fff); + /* check if valid real address */ + if (!MEM_ADDR_OK(word)) /* see if address is within our memory */ + return NPMEM; /* no, none present memory error */ + if ((MODES & PRIVBIT) == 0) { /* see if we are in unprivileged mode */ + if (map & 0x2000) /* check if protect bit is set in map entry */ + *prot = 1; /* return memory write protection status */ + } + *realaddr = word; /* return the real address */ + return ALLOK; /* all OK, return instruction */ + } + /*****************END-OF-7X-ADDRESS-PROCESSING****************/ + + /* Everyone else has 2KW maps */ + /* do common processing */ + /* diag wants the address to be 19 or 24 bit, use masked address */ + if (MODES & (BASEBIT | EXTDBIT)) + word = addr & 0xffffff; /* get 24 bit address */ + else + word = addr & 0x7ffff; /* get 19 bit address */ + + if ((MODES & MAPMODE) == 0) { + /* we are in unmapped mode, check if valid real address */ + if (!MEM_ADDR_OK(word)) { /* see if address is within our memory */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + if (access == MEM_RD) + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + if (access == MEM_WR) + TRAPSTATUS |= BIT2; /* set bit 2 of trap status */ + } else { + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + } + return NPMEM; /* no, none present memory error */ + } + *realaddr = word; /* return the real address */ + return ALLOK; /* all OK, return instruction */ + } + + mpl = SPAD[0xf3] & MASK24; /* get 24 bit dbl wd mpl from spad address */ + + /* did not get expected machine check trap for */ + /* 27, 87, 67 in test 37/0 if code removed */ + /* unexpected machine check trap for 67 in test 37/0 cn.mmm */ + /* now check the O/S midl pointer for being valid */ + /* we may want to delay checking until we actually use it */ + if (!MEM_ADDR_OK((RMW(mpl+4) & MASK24))) { /* check OS midl */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "RealAddr Non Present Memory O/S msdl MPL %06x MPL[1] %06x\n", + mpl, RMW(mpl+4)); + + if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_87)) { + // 32/27, 32/87 want MACHINECHK for test 37/1 in CN.MMM + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + return MACHINECHK_TRAP; /* diags want machine check error */ + } else + if ((CPU_MODEL == MODEL_67) || (CPU_MODEL == MODEL_V6)) { + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + return MAPFLT; /* map fault error */ + } + else + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + // V9 & 32/97 wants MACHINECHK for test 37/1 in CN.MMM & VM.MMM + TRAPSTATUS |= (BIT7|BIT9); /* set bit 7 of trap status */ + TRAPSTATUS |= BIT28; /* set bit 28 of trap status */ + return MACHINECHK_TRAP; /* diags want machine check error */ + } + } + + /* we are mapped, so calculate real address from map information */ + /* get 11 bit page number from address bits 8-18 */ + index = (word >> 13) & 0x7ff; /* get 11 bit page value */ + offset = word & 0x1fff; /* get 13 bit page offset */ + + /* make sure map index is valid */ + if (index >= (BPIX + CPIXPL)) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "RealAddr %06x word %06x loadmap gets mapfault index %04x B(%x)+C(%x) %04x\n", + word, addr, index, BPIX, CPIXPL, BPIX+CPIXPL); + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= (BIT5|BIT9); /* set bit 5/9 of trap status */ + else + TRAPSTATUS |= BIT16; /* set bit 16 of trap status */ + return MAPFLT; /* map fault error */ + } + + /* continue processing non virtual machines here 32/27 & 32/87 */ + /* at this point all maps have been force loaded in load_maps */ + /* just do the conversion from logical to real address */ + if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_87)) { + map = RMR((index<<1)); /* read the map reg cache contents */ + raddr = TLB[index]; /* get the base address & bits */ + + if (!MEM_ADDR_OK(RMW(mpl+CPIX+4) & MASK24)) { /* check user midl */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "RealAddr 27 & 87 map fault index %04x B+C %04x map %04x TLB %08x\n", + index, BPIX+CPIXPL, map, TLB[index]); + // 32/27 & 32/87 want MACHINECHK for test 37/1 in CN.MMM + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + return MACHINECHK_TRAP; /* diags want machine check error */ + } + + if (((map & 0x8000) == 0) || ((raddr & BIT0) == 0)) { /* see if valid map */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "RealAddr loadmap 0a map fault index %04x B+C %04x map %04x TLB %08x\n", + index, BPIX+CPIXPL, map, TLB[index]); + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + return MAPFLT; /* no, map fault error */ + } + + // needed for 32/27 & 32/87 + /* check if valid real address */ + if (!MEM_ADDR_OK(raddr & MASK24)) { /* see if address is within our memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "RealAddr loadmap 0c non present memory fault addr %06x raddr %08x index %04x\n", + word, raddr, index); + TRAPSTATUS |= BIT28; /* set bit 28 of trap status */ + return NPMEM; /* no, none present memory error */ + } + word = (raddr & 0xffe000) | offset; /* combine real addr and offset */ + *realaddr = word; /* return the real address */ + if (MODES & PRIVBIT) /* all OK if privledged */ + return ALLOK; /* all OK, return instruction */ + + /* get user protection status of map */ + offset = (word >> 11) & 0x3; /* see which 1/4 page we are in */ + if ((BIT1 >> offset) & raddr) { /* is 1/4 page write protected */ + *prot = 1; /* return memory write protection status */ + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "RealAddrRa address %08x, TLB %08x MAPC[%03x] %08x wprot %02x prot %02x\n", + word, TLB[index], index/2, MAPC[index/2], (word>>11)&3, *prot); + return ALLOK; /* all OK, return instruction */ + } + /*****************END-OF-27-87-ADDRESS-PROCESSING****************/ + + /* handle 32/67, 32/97 and V6 & V9 here */ + /* Concept 32 machine, 2KW maps */ + /* the index is less than B+C, so setup to get a map */ + if (TLB[index] & 0x04000000) { /* is HIT bit on in TLB */ + /* handle HIT bit already on in TLB here */ + /* diags wants a NPMEM error if physical addr is exceeded */ + index &= 0x7ff; /* map # */ + raddr = TLB[index]; /* get the base address & bits */ + /* check if valid real address */ + if (!MEM_ADDR_OK(raddr & MASK24)) { /* see if address is within our memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "RealAddr loadmap 2a non present memory fault addr %08x raddr %08x index %04x\n", + addr, raddr, index); + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + if (access == MEM_RD) + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + else + if (access == MEM_WR) + TRAPSTATUS |= BIT2; /* set bit 2 of trap status */ + } else + TRAPSTATUS |= BIT28; /* set bit 28 of trap status */ + return NPMEM; /* none present memory error */ + } + map = RMR((index<<1)); /* read the map reg contents */ + word = (raddr & 0xffe000) | offset; /* combine map and offset */ + *realaddr = word; /* return the real address */ + + /* handle 32/67 & 32/97 protection here */ + if (CPU_MODEL < MODEL_V6) { + /* process 32/67 & 32/97 load map on access */ + /* handle 32/67 & 32/97 */ + if (MODES & PRIVBIT) /* all OK if privledged */ + return ALLOK; /* all OK, return instruction */ + + /* get protection status of map */ + offset = (word >> 11) & 0x3; /* see which 1/4 page we are in */ + if ((BIT1 >> offset) & raddr) { /* is 1/4 page write protected */ + *prot = 1; /* return memory write protection status */ + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "RealAddrR address %08x, TLB %08x MAPC[%03x] %08x wprot %02x prot %02x\n", + word, TLB[index], index/2, MAPC[index/2], (word>>11)&3, *prot); + return ALLOK; /* all OK, return instruction */ + } + + /* handle valid V6 & V9 HIT bit on */ + /* get protection status of map */ + offset = ((map >> 12) & 0x6); /* get bits p1 & p2 from map into bits 13 & 14 */ + if (MODES & PRIVBIT) /* all access if privledged */ + *prot = offset | 0x8; /* set priv bit */ + else + *prot = offset; /* return memory write protection status */ + + sim_debug(DEBUG_DETAIL, &cpu_dev, + "RealAddrX address %06x, TLB %06x MAPC[%03x] %08x wprot %02x prot %02x\n", + word, TLB[index], index/2, MAPC[index/2], (word>>11)&3, *prot); + return ALLOK; /* all OK, return instruction */ + } + + /* Hit bit is off in TLB, so lets go get some maps */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "$MEMORY %06x HIT MPL %06x MPL[0] %08x %06x MPL[%04x] %08x %06x\n", + MEMSIZE, mpl, RMW(mpl), RMW(mpl+4), CPIX, RMW(CPIX+mpl), RMW(CPIX+mpl+4)); + + /* check user msdl address now that we are going to access it */ + msdl = RMW(mpl+CPIX+4); /* get msdl entry for given CPIX */ + if (!MEM_ADDR_OK(msdl & MASK24)) { /* check user midl */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "RealAddr User CPIX Non Present Memory User msdl %06x CPIX %04x\n", + msdl, CPIX); + + if (CPU_MODEL == MODEL_67) { + /* test 37/0 wants MAPFLT trap for 67 */ + TRAPSTATUS |= BIT28; /* set bit 28 of trap status */ + return MAPFLT; /* map fault error on memory access */ + } else + if (CPU_MODEL == MODEL_97) { + // 32/97 wants MAPFLT for test 37/1 in CN.MMM + TRAPSTATUS |= BIT12; /* set bit 12 of trap status */ + TRAPSTATUS |= (BIT7|BIT9); /* set bit 7/9 of trap status */ + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + return MAPFLT; /* no, map fault error */ + } else + if (CPU_MODEL == MODEL_V6) { + // V6 wants MAPFLT for test 37/1 in CN.MMM & VM.MMM */ + TRAPSTATUS |= BIT28; /* set bit 28 of trap status */ + /* OK for V6 */ + return MAPFLT; /* map fault error */ + } + else + if (CPU_MODEL == MODEL_V9) { + /* V9 wants MAPFLT for test 37/1 in CN.MMM & VM.MMM */ + /* V9 fails test 46/subtest 2 with "did not get expected map trap */ + TRAPSTATUS |= BIT12; /* set bit 12 of trap status */ + TRAPSTATUS |= (BIT7|BIT9); /* set bit 7 of trap status */ + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + return MAPFLT; /* map fault error */ + } + } + + /* get os or user msdl, index < BPIX; os, else user */ + if (index < BPIX) + msdl = RMW(mpl+4); /* get mpl entry wd 1 for os */ + else + /* check user msdl address now that we are going to access it */ + msdl = RMW(mpl+CPIX+4); /* get mpl entry wd 1 for given cpix */ + + /* HIT bit is off, we must load the map entries from memory */ + /* turn on the map hit flag if valid and set maps real base addr */ + nix = index & 0x7ff; /* map # or mapc index */ + word = (TLB[nix] & 0xffe000) | offset; /* combine map and offset */ + if (index < BPIX) + mix = nix; /* get map index in memory */ + else + mix = nix-BPIX; /* get map index in memory */ + map = RMH(msdl+(mix<<1)); /* map content from memory */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Addr %06x RealAddr %06x Map0[%04x] HIT %04x TLB[%3x] %08x MAPC[%03x] %08x\n", + addr, word, mix, map, nix, TLB[nix], nix/2, MAPC[nix/2]); + + /* process HIT bit off V6 & V9 here */ + if ((map & 0x8000) == 0) { + *realaddr = word; /* return the real address */ + /* for V6 & V9 handle demand paging */ + if (CPU_MODEL >= MODEL_V6) { + /* map is not valid, so we have map fault */ + sim_debug(DEBUG_EXP, &cpu_dev, + "AddrMa %06x RealAddr %06x Map0 MISS %04x, TLB[%3x] %08x MAPC[%03x] %08x\n", + addr, word, map, nix, TLB[nix], nix/2, MAPC[nix/2]); + /* do a demand page request for the required page */ + pfault = nix; /* save page number */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_write Daddr2 %06x page %04x demand page bits set TLB %08x map %04x\n", + addr, nix, TLB[nix], map); + return DMDPG; /* demand page request */ + } + /* handle 67 & 97 map invalid here */ + if (CPU_MODEL == MODEL_97) { + if (access == MEM_RD) + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + else + if (access == MEM_WR) + TRAPSTATUS |= BIT2; /* set bit 2 of trap status */ + } else + TRAPSTATUS |= BIT28; /* set bit 28 of trap status */ + return MAPFLT; /* map fault error */ + } + + /* map is valid, process it */ + TLB[nix] = ((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000) | 0x04000000; + word = (TLB[nix] & 0xffe000) | offset; /* combine map and offset */ + WMR((nix<<1), map); /* store the map reg contents into MAPC cache */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "RealAddrm RMH %04x mix %04x TLB[%04x] %08x B+C %04x RMR[nix] %04x\n", + map, mix, nix, TLB[nix], BPIX+CPIXPL, RMR(nix<<1)); + + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Addr1c %06x RealAddr %06x Map1[%04x] HIT %04x, TLB[%3x] %08x MAPC[%03x] %08x RMR %04x\n", + addr, word, mix, map, nix, TLB[nix], nix/2, MAPC[nix/2], RMR(nix<<1)); + + *realaddr = word; /* return the real address */ + raddr = TLB[nix]; /* get the base address & bits */ + + if ((CPU_MODEL == MODEL_67) || (CPU_MODEL == MODEL_97)) { + /* get protection status of map */ + if ((MODES & PRIVBIT) == 0) { /* OK if privledged */ + /* otherwise check protection bit */ + offset = (word >> 11) & 0x3; /* see which 1/4 page we are in */ + if ((BIT1 >> offset) & raddr) /* is 1/4 page write protected */ + *prot = 1; /* return memory write protection status */ + } + } else { + /* get protection status of map */ + offset = ((map >> 12) & 0x6); /* get bits p1 & p2 from map into bits 13 & 14 */ + if (MODES & PRIVBIT) /* all access if privledged */ + *prot = offset | 0x8; /* set priv bit */ + else + *prot = offset; /* return memory write protection status */ + } + + /* now do the other halfword of the memory map pair */ + /* calc index of previous or next halfword */ + if ((mix & 1) == 0) { + mix += 1; /* we are at lf hw, so do next hw */ + nix += 1; /* point to next map in MAPC */ + /* This is really a firmware error where the CPU loads the */ + /* right halfword map information even though it exceeds */ + /* the allowed map count. It does not hurt anything, so OK */ + /* 32/67 & V6 allow loading the extra rt hw map entry */ + if ((nix == BPIX) || (nix > (BPIX+CPIXPL))) + return ALLOK; /* no other map is valid, we are done */ + } else + if ((mix & 1) == 1) { + if (nix == BPIX) + return ALLOK; /* no other map is valid, we are done */ + mix -= 1; /* we are at rt hw, so backup hw */ + nix -= 1; /* point to last map in MAPC */ + } + + sim_debug(DEBUG_DETAIL, &cpu_dev, + "RealAddrp mix %04x nix %04x TLB[%04x] %08x B+C %04x RMR[nix] %04x\n", + mix, nix, nix, TLB[nix], BPIX+CPIXPL, RMR(nix<<1)); + + /* allow the excess map entry to be loaded, even though bad */ + if (nix <= (BPIX+CPIXPL)) { /* needs to be a mapped reg */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Addr1d BPIX %03x CPIXPL %03x RealAddr %06x TLB[%3x] %08x MAPC[%03x] %08x RMR %04x\n", + BPIX, CPIXPL, word, nix, TLB[nix], nix/2, MAPC[nix/2], RMR(nix<<1)); + + /* mix & nix has other map correct index */ + if ((TLB[nix] & 0x04000000) == 0) { /* is HIT bit already on */ + /* hit not on, so load the map */ + /* allow the excess map entry to be loaded, even though bad */ + if (nix <= (BPIX+CPIXPL)) { /* needs to be a mapped reg */ + map = RMH(msdl+(mix<<1)); /* map content from memory */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Addr2a %06x MapX[%04x] HIT %04x, TLB[%3x] %08x MAPC[%03x] %08x\n", + addr, mix, map, nix, TLB[nix], nix/2, MAPC[nix/2]); + + if (map & 0x8000) { /* must be valid to load */ + /* setting access bit fails test 15/0 in vm.mmm diag */ + TLB[nix] = ((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000) | 0x04000000; + word = (TLB[nix] & 0xffe000); /* combine map and offset */ + WMR((nix<<1), map); /* store the map reg contents into MAPC cache */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Addr2b %06x RealAddr %06x Map2[%04x] HIT %04x, TLB[%3x] %08x MAPC[%03x] %08x\n", + addr, word, mix, map, nix, TLB[nix], nix/2, MAPC[nix/2]); + } + } + } + } + /*****************END-OF-V6-V9-ADDRESS-HIT-PROCESSING****************/ + /*****************END-OF-67-97-ADDRESS-HIT-PROCESSING****************/ + return ALLOK; /* all OK, return instruction */ +} + +/* fetch the current instruction from the PC address */ +t_stat read_instruction(uint32 thepsd[2], uint32 *instr) +{ + uint32 status, addr; + + if (CPU_MODEL < MODEL_27) { + /* 32/7x machine with 8KW maps */ + /* instruction must be in first 512KB of address space */ + addr = thepsd[0] & 0x7fffc; /* get 19 bit logical word address */ + } else { + /* 32/27, 32/67, 32/87, 32/97 2KW maps */ + /* Concept 32 machine, 2KW maps */ + if (thepsd[0] & BASEBIT) { /* bit 6 is base mode? */ + addr = thepsd[0] & 0xfffffc; /* get 24 bit address */ + } + else + addr = thepsd[0] & 0x7fffc; /* get 19 bit address */ + } + + /* go read the memory location */ + status = Mem_read(addr, instr); + if ((status == MAPFLT) && (TRAPSTATUS == BIT1)) { + /* if map fault on read, change code to read instruction */ + TRAPSTATUS &= ~BIT1; /* clear error on read memory */ + TRAPSTATUS |= BIT0; /* set error on instruction read */ + } else + if (status == DMDPG) + pfault |= 0x80000000; /* set instruction fetch paging error */ + sim_debug(DEBUG_DETAIL, &cpu_dev, "read_instr status %02x @ %06x\n", status, addr); + return status; /* return ALLOK or ERROR status */ +} + +/* + * Read a full word from memory + * Return error type if failure, ALLOK if + * success. Addr is logical byte address. + */ +t_stat Mem_read(uint32 addr, uint32 *data) +{ + uint32 status, realaddr, prot, page, map, mix, nix, msdl, mpl, nmap; + + status = RealAddr(addr, &realaddr, &prot, MEM_RD); /* convert address to real physical address */ + + if (status == ALLOK) { + *data = RMW(realaddr); /* valid address, get physical address contents */ + if (((CPU_MODEL >= MODEL_V6) || (CPU_MODEL == MODEL_97) || + (CPU_MODEL == MODEL_67)) && (MODES & MAPMODE)) { + + page = (addr >> 13) & 0x7ff; /* get 11 bit value */ + if (CPU_MODEL >= MODEL_V6) { + /* check for v6 & v9 if we have read access */ + switch (prot & 0x0e) { + case 0x0: case 0x2: + /* O/S or user has no read/execute access, do protection violation */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_readA protect error @ %06x prot %02x modes %08x page %04x\n", + addr, prot, MODES, page); + if (CPU_MODEL == MODEL_V9) + TRAPSTATUS |= BIT2; /* set bit 2 of trap status */ + else + TRAPSTATUS &= ~BIT12; /* clear bit 12 of trap status */ + return MPVIOL; /* return memory protection violation */ + case 0x4: case 0x6: case 0x8: case 0xa: case 0xc: case 0xe: + /* O/S or user has read/execute access, no protection violation */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Mem_readB protect is ok @ %06x prot %02x modes %08x page %04x\n", + addr, prot, MODES, page); + } + mpl = SPAD[0xf3]; /* get mpl from spad address */ + nix = page & 0x7ff; /* map # or mapc index */ + if (page < BPIX) { + mix = nix; /* get map index in memory */ + msdl = RMW(mpl+4); /* get mpl entry for o/s */ + } else { + mix = nix-BPIX; /* get map index in memory */ + msdl = RMW(mpl+CPIX+4); /* get mpl entry for given cpix */ + } + nmap = RMH(msdl+(mix<<1)); /* map content from memory */ + map = RMR((page<<1)); /* read the map reg contents */ + /* if I remove this test, we fail at test 14/0 */ + if (((map & 0x800) == 0)) { + map |= 0x800; /* set the accessed bit in the map cache entry */ + WMR((page<<1), map); /* store the map reg contents into cache */ + TLB[page] |= 0x0c000000; /* set the accessed bit in TLB too */ + WMH(msdl+(mix<<1), map); /* save modified map with access bit set */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Mem_read Yaddr %06x page %04x set access bit TLB %08x map %04x nmap %04x\n", + addr, page, TLB[page], map, nmap); + } + } + /* everybody else has read access */ + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Mem_read addr %06x realaddr %06x data %08x prot %02x\n", + addr, realaddr, *data, prot); + } else { + /* RealAddr returned an error */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_read error addr %06x realaddr %06x data %08x prot %02x status %04x\n", + addr, realaddr, *data, prot, status); + if (status == NPMEM) { /* operand nonpresent memory error */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + } else + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + } + if (status == MAPFLT) { + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= (BIT12|BIT16); /* set bit 12 of trap status */ + else + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + } + sim_debug(DEBUG_EXP, &cpu_dev, "Mem_read MISS %02x @ %06x TRAPSTATUS %08x\n", + status, addr, TRAPSTATUS); + } + return status; /* return ALLOK or ERROR status */ +} + +/* + * Write a full word to memory, checking protection + * and alignment restrictions. Return 1 if failure, 0 if + * success. Addr is logical byte address, data is 32bit word + */ +t_stat Mem_write(uint32 addr, uint32 *data) +{ + uint32 status, realaddr=0, prot=0, raddr, page, nmap, msdl, mpl, map, nix, mix; + + status = RealAddr(addr, &realaddr, &prot, MEM_WR); /* convert address to real physical address */ + + if (prot) { + sim_debug(DEBUG_DETAIL, &cpu_dev, "Mem_write addr %.8x realaddr %.8x data %.8x prot %02x\n", + addr, realaddr, *data, prot); + } + + if (status == ALLOK) { + if (((CPU_MODEL >= MODEL_V6) || (CPU_MODEL == MODEL_97) || + (CPU_MODEL == MODEL_67)) && (MODES & MAPMODE)) { + page = (addr >> 13) & 0x7ff; /* get 11 bit value */ + if (CPU_MODEL >= MODEL_V6) { + /* check for v6 & v9 if we have write access */ + switch (prot &0x0e) { + case 0x0: case 0x2: case 0x6: case 0xa: case 0xe: + /* O/S or user has read/execute access, do protection violation */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Mem_writeA protect error @ %06x prot %02x modes %08x\n", + addr, prot, MODES); + if (CPU_MODEL == MODEL_V9) + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + else + TRAPSTATUS |= BIT12; /* set bit 12 of trap status */ + return MPVIOL; /* return memory protection violation */ + case 0x4: case 0x8: case 0xc: + /* O/S or user has write access, no protection violation */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Mem_writeB protect is ok @ %06x prot %02x modes %08x\n", + addr, prot, MODES); + } + map = RMR((page<<1)); /* read the map reg contents */ + raddr = TLB[page]; /* get the base address & bits */ + nix = page & 0x7ff; /* map # or mapc index */ + mpl = SPAD[0xf3]; /* get mpl from spad address */ + if (page < BPIX) { + mix = nix; /* get map index in memory */ + msdl = RMW(mpl+4); /* get mpl entry for o/s */ + } else { + mix = nix-BPIX; /* get map index in memory */ + msdl = RMW(mpl+CPIX+4); /* get mpl entry for given cpix */ + } + nmap = RMH(msdl+(mix<<1)); /* map content from memory */ + if ((nmap & 0x1000) == 0) { + nmap |= 0x1800; /* set the modify/accessed bit in the map cache entry */ + WMR((page<<1), nmap); /* store the map reg contents into cache */ + TLB[page] |= 0x18000000; /* set the modify/accessed bits in TLB too */ + WMH((msdl+(mix << 1)), nmap); /* save modified map with access bit set */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Mem_write Waddr %06x page %04x set access bit TLB %08x map %04x nmap %04x raddr %08x\n", + addr, page, TLB[page], map, nmap, raddr); + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Mem_write Xaddr %06x page %04x MA bits set TLB %08x map %04x prot %04x modes %04x\n", + addr, page, TLB[page], map, prot, MODES); + } else { + if (prot) { /* check for write protected memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_writeB 32/67 protect error @ %06x prot %02x page %04x\n", + addr, prot, page); + if (CPU_MODEL == MODEL_97) + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + else + TRAPSTATUS |= BIT12; /* set bit 12 of trap status */ + return MPVIOL; /* return memory protection violation */ + } + } + /* everything else has write access */ + } else { + if (prot) { /* check for write protected memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "Mem_writeC protect error @ %06x prot %02x\n", addr, prot); + TRAPSTATUS |= BIT12; /* set bit 12 of trap status */ + return MPVIOL; /* return memory protection violation */ + } + } + WMW(realaddr, *data); /* valid address, put physical address contents */ + } else { + /* RealAddr returned an error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "Mem_write error addr %.8x realaddr %.8x data %.8x prot %02x status %04x\n", + addr, realaddr, *data, prot, status); + if (status == NPMEM) { /* operand nonpresent memory error */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + TRAPSTATUS |= BIT2; /* set bit 2 of trap status */ + } else + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + } + if (status == MAPFLT) { + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= (BIT12|BIT16); /* set bit 12 of trap status */ + else + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + } + sim_debug(DEBUG_TRAP, &cpu_dev, + "Mem_write error %02x @ %06x TRAPSTATUS %08x pfaualt %04x\n", + status, addr, TRAPSTATUS, pfault); + } + return status; /* return ALLOK or ERROR */ +} + +/* function to set the CCs in PSD1 */ +/* ovr is setting for CC1 */ +void set_CCs(uint32 value, int ovr) +{ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + if (ovr) + CC = CC1BIT; /* CC1 value */ + else + CC = 0; /* CC1 off */ + if (value & FSIGN) + CC |= CC3BIT; /* CC3 for neg */ + else if (value == 0) + CC |= CC4BIT; /* CC4 for zero */ + else + CC |= CC2BIT; /* CC2 for greater than zero */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ +} + +/* retain these values across calls to sim_instr */ +uint32 skipinstr = 0; /* Skip test for interrupt on this instruction */ +uint32 drop_nop = 0; /* Set if right hw instruction is a nop */ +uint32 OIR=0; /* Original Instruction register */ +uint32 OPSD1=0; /* Original PSD1 */ +uint32 OPSD2=0; /* Original PSD2 */ +uint32 TPSD[2]; /* Temp PSD */ + +/* Opcode definitions */ +/* called from simulator */ +t_stat sim_instr(void) { + t_stat reason = 0; /* reason for stopping */ + t_uint64 dest = 0; /* Holds destination/source register */ + t_uint64 source = 0; /* Holds source or memory data */ + t_uint64 td; /* Temporary */ + t_int64 int64a; /* temp int */ + t_int64 int64b; /* temp int */ + t_int64 int64c; /* temp int */ + uint32 addr; /* Holds address of last access */ + uint32 temp; /* General holding place for stuff */ + uint32 IR; /* Instruction register */ + uint32 i_flags=0; /* Instruction description flags from table */ + uint32 t; /* Temporary */ + uint32 temp2; /* Temporary */ + uint32 bc=0; /* Temporary bit count */ + uint16 opr; /* Top half of Instruction register */ + uint16 OP; /* Six bit instruction opcode */ + uint16 chan; /* I/O channel address */ + uint16 lchan; /* Logical I/O channel address */ + uint16 suba; /* I/O subaddress */ + uint16 lchsa; /* logical I/O channel & subaddress */ + uint16 rchsa; /* real I/O channel & subaddress */ + uint8 FC; /* Current F&C bits */ + uint8 EXM_EXR=0; /* PC Increment for EXM/EXR instructions */ + uint8 BM, MM, BK; /* basemode, mapped mode, blocked mode */ + uint32 reg; /* GPR or Base register bits 6-8 */ + uint32 sreg; /* Source reg in from bits 9-11 reg-reg instructions */ + uint32 ix = 0; /* index register */ + uint32 dbl; /* Double word */ + uint32 ovr=0; /* Overflow flag */ +//FORSTEP uint32 stopnext = 0; /* Stop on next instruction */ + uint32 int_icb; /* interrupt context block address */ + uint32 rstatus; /* temp return status */ + int32 int32a; /* temp int */ + int32 int32b; /* temp int */ + int32 int32c; /* temp int */ +// uint32 uint32a; /* temp uint */ +// uint32 uint32b; /* temp uint */ +// uint32 uint32c; /* temp uint */ + +//#define MPXTEST +//#define LOOK_MAP_05272021 +#ifdef MPXTEST + int32 ii; /* temp int */ +#endif + +wait_loop: + while (reason == 0) { /* loop until halted */ + + // wait_loop: + if (sim_interval <= 0) { /* event queue? */ + reason = sim_process_event(); /* process */ + if (reason != SCPE_OK) { + if (reason == SCPE_STEP) { + sim_debug(DEBUG_EXP, &cpu_dev, + "Process Event step reason %08x interval %08x\n", + reason, sim_interval); + return reason; + break; + } + else { + sim_debug(DEBUG_EXP, &cpu_dev, + "Process Event other reason %08x interval %08x\n", + reason, sim_interval); + return reason; + break; /* process */ + } + } + } + + if (sim_brk_summ) + sim_debug(DEBUG_EXP, &cpu_dev, "Process Event sim_brk_summ = %08x\n", + sim_brk_summ); + PC = PSD1 & 0xfffffe; /* get 24 bit addr from PSD1 */ + /* stop simulator if user break requested */ + if (sim_brk_summ && sim_brk_test(PC, SWMASK('E'))) { + reason = STOP_IBKPT; +// reason = SCPE_STEP; + sim_debug(DEBUG_EXP, &cpu_dev, "Process Event test reason %08x interval %08x\n", + reason, sim_interval); + sim_interval= 0; /* count down */ + break; + } + + sim_interval--; /* count down */ + + if (drop_nop) { /* need to drop a nop? */ + drop_nop = 0; /* we dropped the nop */ + sim_debug(DEBUG_EXP, &cpu_dev, + "CPU Drop NOP PSD1 %08x\n", PSD1); + } + + if (skipinstr) { /* need to skip interrupt test? */ + skipinstr = 0; /* skip only once */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "CPU Skip instruction PSD %08x %08x irq_pend %d wait4int %d irq_auto %x\n", + PSD1, PSD2, irq_pend, wait4int, irq_auto); + goto skipi; /* skip int test */ + } + + if (waitqcnt > 0) { /* test for UTX delay */ + waitqcnt--; /* wait b4 ints */ + if (waitqcnt == 0) + irq_pend = 1; /* start scanning interrupts again */ + } + + /* we are booting the system, so see if boot channel prog is completed */ + if (loading) { + uint32 il; + uint32 chsa = scan_chan(&il); /* go scan for load complete pending */ + if (chsa != 0) { /* see if a boot channel/subaddress were returned */ + /* take interrupt, store the PSD, fetch new PSD */ + PSD1 = TPSD[0]; /* PSD1 from location 0 */ + PSD2 = TPSD[1]; /* PSD2 from location 4 */ + CC = PSD1 & 0x78000000; /* extract bits 1-4 from PSD1 */ + MODES = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ + CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */ + CPUSTATUS |= MODES; /* now insert into CPUSTATUS */ + sim_debug(DEBUG_IRQ, &cpu_dev, "Boot Loading PSD1 %.8x PSD2 %.8x\n", PSD1, PSD2); + + /* set interrupt blocking state in CPUSTATUS */ + CPUSTATUS |= BIT24; /* set blocked state in cpu status, bit 24 too */ + MODES |= BLKMODE; /* set blocked in mode to0 */ + PSD2 &= ~RETMBIT; /* turn off retain map bit in PSD2 */ + PSD2 &= ~RETBBIT; /* turn off retain block mode bit in PSD2 */ + + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + loading = 0; /* we are done loading */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "Load Skipinstr %1x set loading PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", + skipinstr, PSD1, PSD2, CPUSTATUS); + goto skipi; /* skip int test */ + } + goto wait_loop; /* continue waiting */ + } + + /* we get here when not booting */ + /* process any pending interrupts */ + if ((irq_pend || wait4int) && (irq_auto == 0)) { + /* see if ints are pending */ + uint32 ilev; + uint32 oldstatus = CPUSTATUS; /* keep for retain blocking state */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + + int_icb = scan_chan(&ilev); /* no, go scan for I/O int pending */ + if (int_icb != 0) { /* was ICB returned for an I/O or interrupt */ + uint32 il = ilev; /* get the interrupt level */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>Normal int return icb %06x level %02x irq_pend %1x wait4int %1x\n", + int_icb, il, irq_pend, wait4int); + + /* take interrupt, store the PSD, fetch new PSD */ + bc = PSD2 & 0x3ff8; /* get copy of cpix */ + M[int_icb>>2] = PSD1&0xfffffffe; /* store PSD 1 */ + M[(int_icb>>2)+1] = PSD2; /* store PSD 2 */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>Normal int cpix %04x OPSD1 %08x OPSD2 %08x\n", + bc, PSD1, PSD2); +#ifdef DUMP_REGS + for (ix=0; ix<8; ix+=2) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|> GPR[%d] %.8x GPR[%d] %.8x\n", ix, GPR[ix], ix+1, GPR[ix+1]); + } +#endif + PSD1 = M[(int_icb>>2)+2]; /* get new PSD 1 */ + PSD2 = (M[(int_icb>>2)+3] & ~0x3fff) | bc; /* get new PSD 2 w/old cpix */ + + /* I/O status DW address will be in WD 6 */ + /* set new map mode and interrupt blocking state in CPUSTATUS */ + CC = PSD1 & 0x78000000; /* extract bits 1-4 from PSD1 */ + MODES = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ + CPUSTATUS &= ~0x87000080; /* reset bits in CPUSTATUS */ + CPUSTATUS |= MODES; /* now insert into CPUSTATUS */ + if (PSD2 & MAPBIT) { + CPUSTATUS |= BIT8; /* set bit 8 of cpu status to mapped */ + MODES |= MAPMODE; /* set mapped mode */ + } else { + CPUSTATUS &= ~BIT8; /* reset bit 8 of cpu status */ + MODES &= ~MAPMODE; /* reset set mapped mode */ + } + + if ((PSD2 & RETBBIT) == 0) { /* is it retain blocking state, bit 48 set */ + /* retain blocking state is off, use bit 49 to set new blocking state */ + if (PSD2 & SETBBIT) { /* no, is it set blocking state bit 49 set*/ + /* new blocking state is blocked when bits 48=0 & bit 49=1 */ + CPUSTATUS |= BIT24; /* yes, set blk state in cpu status bit 24 */ + MODES |= BLKMODE; /* set blocked mode */ + + /* This test fixed the hangs on terminal input for diags & UTX! */ + t = SPAD[il+0x80]; /* get spad entry for interrupt */ + /* Class F I/O spec says to reset active interrupt if user's */ + /* interrupt service routine runs with interrupts blocked */ + if (((t & 0x0f800000) == 0x0f000000) || /* if class F clear interrupt */ + ((t & 0x0000ffff) == 0x00007f06) || /* RT Clock */ + ((t & 0x0f00ffff) == 0x03007f04)) { /* Interval timer */ + /* if this is F class I/O interrupt, clear the active level */ + /* SPAD entries for interrupts begin at 0x80 */ + if ((irq_auto) != 0) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>Auto-reset irq_auto NOT zero %x INTS[%02x] %08x SPAD[%02x] %08x\n", + irq_auto, il, INTS[il], il+0x80, SPAD[il+0x80]); + } + irq_auto = il; /* show processing in blocked mode */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>Auto-reset interrupt INTS[%02x] %08x SPAD[%02x] %08x simi %02x\n", + il, INTS[il], il+0x80, SPAD[il+0x80], sim_interval); +#define LEAVE_ACTIVE +#ifndef LEAVE_ACTIVE +/*AIR*/ INTS[irq_auto] &= ~INTS_ACT; /* deactivate specified int level */ +/*AIR*/ SPAD[irq_auto+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ + irq_auto = 0; +#endif + } + } else { + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>RUN ACTIVE interrupt INTS[%02x] %08x SPAD[%02x] %08x\n", + il, INTS[il], il+0x80, SPAD[il+0x80]); + CPUSTATUS &= ~BIT24; /* no, reset blk state in cpu status bit 24 */ + MODES &= ~BLKMODE; /* reset blocked mode */ + } + } else { + /* handle retain blocking state */ + PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ + /* set new blocking state in PSD2 */ + PSD2 &= ~(SETBBIT|RETBBIT); /* clear bit 48 & 49 to be unblocked */ + MODES &= ~(BLKMODE|RETBLKM); /* reset blocked & retain mode bits */ + if (oldstatus & BIT24) { /* see if old mode is blocked */ + PSD2 |= SETBBIT; /* set to blocked state */ + MODES |= BLKMODE; /* set blocked mode */ + } + } + + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>Int %02x OPSD1 %08x OPSD2 %08x NPSD1 %08x NPSD2 %08x\n", + il, RMW(int_icb), RMW(int_icb+4), PSD1, PSD2); + bc = RMW(int_icb+20) & 0xffffff; + if (RMW(int_icb+16) == 0) + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>Int2 %02x ICBA %06x ICBA %06x IOCLA %06x\n", il, int_icb, + RMW(int_icb+16), RMW(int_icb+20)); + else + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>Int2 %02x ICBA %06x IOCLA %06x STAT %08x SW1 %08x SW2 %08x\n", + il, int_icb, RMW(int_icb+16), RMW(int_icb+20), RMW(bc), RMW(bc+4)); +#ifdef DYNAMIC_DEBUG_01172021 + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ +#endif + wait4int = 0; /* wait is over for int */ + drop_nop = 0; /* no nop skipping */ + goto skipi; /* skip int test */ + } + } + + /* see if in wait instruction */ + if (wait4int) { /* keep waiting */ + /* tell simh we will be waiting */ + sim_idle(TMR_RTC, 1); /* wait for clock tick */ + irq_pend = 1; /* start scanning interrupts again */ + goto wait_loop; /* continue waiting */ + } + + /* Check for external interrupt here */ + /* see if we have an attention request from console */ + if (!skipinstr && attention_trap) { + TRAPME = attention_trap; /* get trap number */ + attention_trap = 0; /* clear flag */ + sim_debug(DEBUG_XIO, &cpu_dev, "Attention TRAP %04x\n", TRAPME); + goto newpsd; /* got process trap */ + } + +skipi: + i_flags = 0; /* do not update pc if MF or NPM */ + TRAPSTATUS = CPUSTATUS & 0x57; /* clear all trap status except cpu type */ + + /* check for breakpoint request */ + if (sim_brk_summ && sim_brk_test(PC, SWMASK('E'))) { + reason = STOP_IBKPT; + break; + } + + /* fill IR from logical memory address */ + if ((TRAPME = read_instruction(PSD, &IR))) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "read_instr TRAPME %04x PSD %08x %08x i_flags %04x drop_nop %1x\n", + TRAPME, PSD1, PSD2, i_flags, drop_nop); + if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_67) || + (CPU_MODEL == MODEL_87) || (CPU_MODEL == MODEL_97)) { + if ((TRAPME == MAPFLT) || (TRAPME == NPMEM)) { + i_flags |= HLF; /* assume half word instr */ + PSD1 &= ~BIT31; /* force off last right */ + // fix for 32/67 test 32/3 in MMM diag + if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_67)) + i_flags |= BT; /* do not update pc if MF or NPM */ + else + i_flags &= ~BT; /* do not update pc if MF or NPM */ + } + } else { + if ((TRAPME == PRIVVIOL_TRAP) && (CPU_MODEL == MODEL_V9)) { + i_flags |= HLF; /* assume half word instr */ + drop_nop = 0; + i_flags &= ~BT; /* no branch taken */ + PSD1 &= ~BIT31; /* force off last right */ + } + } + sim_debug(DEBUG_TRAP, &cpu_dev, + "read_instr2 TRAPME %04x PSD %08x %08x i_flags %04x drop_nop %1x\n", + TRAPME, PSD1, PSD2, i_flags, drop_nop); + goto newpsd; /* got process trap */ + } + + if (PSD1 & 2) { /* see if executing right half */ + /* we have a rt hw instruction */ + IR <<= 16; /* put instruction in left hw */ + if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_87) || + (CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + drop_nop = 0; /* not dropping nop for these machines */ + goto exec; /* machine does not drop nop instructions */ + } + /* We have 67 or V6 and have a rt hw instruction */ + if (IR == 0x00020000) { /* is this a NOP from rt hw? */ + PSD1 = (PSD1 + 2) | (((PSD1 & 2) >> 1) & 1); /* skip this instruction */ + if (skipinstr) + sim_debug(DEBUG_IRQ, &cpu_dev, + "2Rt HW instruction skipinstr %1x is set PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", + skipinstr, PSD1, PSD2, CPUSTATUS); + goto skipi; /* go read next instruction */ + } + if (skipinstr) + sim_debug(DEBUG_IRQ, &cpu_dev, + "3Rt HW instruction skipinstr %1x is set PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", + skipinstr, PSD1, PSD2, CPUSTATUS); + } else { + /* we have a left hw or fullword instruction */ + /* see if we can drop a rt hw nop instruction */ + OP = (IR >> 24) & 0xFC; /* this is a 32/67 or above, get OP */ + if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_87) || + (CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + goto exec; /* old machines did not drop nop instructions */ + if (PSD1 & BASEBIT) + i_flags = base_mode[OP>>2]; /* set the BM instruction processing flags */ + else + i_flags = nobase_mode[OP>>2]; /* set the NBM instruction processing flags */ + if ((i_flags & 0xf) == HLF) { /* this is left HW instruction */ + if ((IR & 0xffff) == 0x0002) { /* see if rt hw is a nop */ + /* treat this as a fw instruction */ + drop_nop = 1; /* we need to skip nop next time */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "CPU setting Drop NOP PSD1 %08x IR %08x\n", PSD1, IR); + } + } + } + +exec: + /* temp saves for debugging */ + OIR = IR; /* save the instruction */ + OPSD1 = PSD1; /* save the old PSD1 */ + OPSD2 = PSD2; /* save the old PSD2 */ + TRAPSTATUS = CPUSTATUS & 0x57; /* clear all trap status except cpu type */ + + /* Split instruction into pieces */ + PC = PSD1 & 0xfffffe; /* get 24 bit addr from PSD1 */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "-----Instr @ PC %08x PSD1 %08x PSD2 %08x IR %08x drop_nop %x\n", + PC, PSD1, PSD2, IR, drop_nop); + + /* Update history for this instruction */ + if (hst_lnt) { + hst_p += 1; /* next history location */ + if (hst_p >= hst_lnt) /* check for wrap */ + hst_p = 0; /* start over at beginning */ + hst[hst_p].opsd1 = OPSD1; /* set original psd1 */ + hst[hst_p].opsd2 = OPSD2; /* set original psd2 */ + hst[hst_p].oir = OIR; /* set original instruction */ + } + + opr = (IR >> 16) & MASK16; /* use upper half of instruction */ + OP = (opr >> 8) & 0xFC; /* Get opcode (bits 0-5) left justified */ + FC = ((IR & F_BIT) ? 0x4 : 0) | (IR & 3); /* get F & C bits for addressing */ + reg = (opr >> 7) & 0x7; /* dest reg or xr on base mode */ + sreg = (opr >> 4) & 0x7; /* src reg for reg-reg instructions or BR instr */ + dbl = 0; /* no doubleword instruction */ + ovr = 0; /* no overflow or arithmetic exception either */ + dest = (t_uint64)IR; /* assume memory address specified */ + CC = PSD1 & 0x78000000; /* save CC's if any */ + MODES = PSD1 & 0x87000000; /* insert bits 0, 5, 6, 7 from PSD 1 */ + CPUSTATUS &= ~0x87000000; /* reset those bits in CPUSTATUS */ + CPUSTATUS |= MODES; /* now insert them into CPUSTATUS */ + if (PSD2 & MAPBIT) { + CPUSTATUS |= BIT8; /* set bit 8 of cpu status to mapped */ + MODES |= MAPMODE; /* set mapped mode */ + } else { + CPUSTATUS &= ~BIT8; /* reset bit 8 of cpu status */ + MODES &= ~MAPMODE; /* reset mapped mode */ + } + + if (MODES & BASEBIT) { + i_flags = base_mode[OP>>2]; /* set the instruction processing flags */ + addr = IR & RMASK; /* get address offset from instruction */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Base OP %04x i_flags %04x addr %08x\n", OP, i_flags, addr); + switch(i_flags & 0xf) { + case HLF: + source = GPR[sreg]; /* get the src reg from instruction */ + break; + case IMM: + if (PC & 02) { /* if pc is on HW boundry, bad address */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC1 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + break; + case ADR: + ix = (IR >> 20) & 7; /* get index reg from instruction */ + if (ix != 0) + addr += (GPR[ix] & MASK24); /* if not zero, add in reg contents */ + case WRD: + if (PC & 02) { /* if pc is on HW boundry, bad address */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC2 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + ix = (IR >> 16) & 7; /* get base reg from instruction */ + if (ix != 0) + addr += (BR[ix] & MASK24); /* if not zero, add to base reg contents */ + FC = ((IR & F_BIT) ? 4 : 0); /* get F bit from original instruction */ + FC |= addr & 3; /* set new C bits to address from orig or regs */ + addr &= MASK24; /* make pure 24 bit addr */ + break; + case INV: + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + break; + } + } else { + i_flags = nobase_mode[OP>>2]; /* set the instruction processing flags */ + addr = IR & 0x7ffff; /* get 19 bit address from instruction */ + if (PC >= 0x80000) { + TRAPME = MAPFAULT_TRAP; /* Map Fault Trap */ + // DIAG add 97 for correct PSD address CN.MMM test 32, subtest 1 fails + if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_67) || + (CPU_MODEL == MODEL_87) || (CPU_MODEL == MODEL_97)) { + // DIAG fix for 32/87 test 33/2, clear psd bit 31 + if ((CPU_MODEL == MODEL_87)) + PSD1 &= ~BIT31; /* force off last right */ + // DIAG fix 32/27 32/67 for diag MMM test 33/2 + if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_67)) + i_flags |= BT; /* do not update pc if MAPFAULT on 27 */ + else + i_flags &= ~BT; /* do not update pc if MF or NPM */ + i_flags |= HLF; /* assume half word instr */ + } + if ((CPU_MODEL <= MODEL_27)) { + /* 77, 27 rolls to zero, not 80000 */ + PSD1 &= 0xff07ffff; /* remove overflow bits */ + } else { + PSD1 &= 0xff0fffff; /* leave overflow bit for trap addr */ + } + sim_debug(DEBUG_TRAP, &cpu_dev, + "PC over 80000 PC %08x Base OP %02x i_flags %04x addr %06x PSD %08x %08x\n", + PC, OP, i_flags, addr, PSD1, PSD2); + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* handle trap */ + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Non Based i_flags %04x addr %08x\n", i_flags, addr); + /* non base mode instructions have bit 0 of the instruction set */ + /* for word length instructions and zero for halfword instructions */ + /* the LA (op=0x34) is the only exception. So test for PC on a halfword */ + /* address and trap if word opcode is in right hw */ + /* if pc is on HW boundry, addr trap if bit zero set */ + if (PC & 02) { + if ((OP == 0x34) || (OP & 0x80)) { + i_flags |= HLF; /* diags treats these as hw instructions */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + goto newpsd; /* go execute the trap now */ + } + } + switch(i_flags & 0xf) { + case HLF: /* halfword instruction */ + source = GPR[sreg]; /* get the src reg contents */ + break; + + case IMM: /* Immediate mode */ + if (PC & 02) { /* if pc is on HW boundry, bad address */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC3 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + break; + + case ADR: /* Normal addressing mode */ + ix = (IR >> 21) & 3; /* get the index reg if specified */ + if (ix != 0) { + addr += GPR[ix]; /* if not zero, add in reg contents */ + FC = ((IR & F_BIT) ? 4 : 0); /* get F bit from original instruction */ + FC |= addr & 3; /* set new C bits to address from orig or regs */ + } + + /* wart alert! */ + /* the lea instruction requires special handling for indirection. */ + /* Bits 0,1 are set to 1 in result addr if indirect bit is zero in */ + /* instruction. Bits 0 & 1 are set to the last word */ + /* or instruction in the chain bits 0 & 1 if indirect bit set */ + /* if IX == 00 => dest = IR */ + /* if IX == 0x => dest = IR + reg */ + /* if IX == Ix => dest = ind + reg */ + + /* fall through */ + case WRD: /* Word addressing, no index */ + bc = 0xC0000000; /* set bits 0, 1 for instruction if not indirect */ + t = IR; /* get current IR */ + addr &= MASK24; /* make pure 24 bit addr */ + while ((t & IND) != 0) { /* process indirection */ + if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "case WRD Mem_read status %02x @ %08x OP %04x\n", TRAPME, addr, OP); + if (CPU_MODEL == MODEL_V9) /* V9 wants bit0 set in pfault */ + if (TRAPME == DMDPG) /* demand page request */ + pfault |= 0x80000000; /* set instruction fetch paging error */ + goto newpsd; /* memory read error or map fault */ + } + bc = temp & 0xC0000000; /* save new bits 0, 1 from indirect location */ + CC = (temp & 0x78000000); /* save CC's from the last indirect word */ + /* process new X, I, ADDR fields */ + addr = temp & MASK19; /* get just the addr */ + ix = (temp >> 21) & 3; /* get the index reg from indirect word */ + if (ix != 0) + addr += (GPR[ix] & MASK19); /* add the register to the address */ + /* if no F or C bits set, use original, else new */ + if ((temp & F_BIT) || (addr & 3)) + FC = ((temp & F_BIT) ? 0x4 : 0) | (addr & 3); + else { + addr |= (IR & F_BIT); /* copy F bit from instruction */ + addr |= (FC & 3); /* copy in last C bits */ + } + t = temp; /* go process next indirect location */ + temp &= MASK19; /* go process next indirect location */ + addr &= ~F_BIT; /* turn off F bit */ + } + dest = (t_uint64)addr; /* make into 64 bit variable */ + break; + + case INV: /* Invalid instruction */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + break; + } + } + + /* Read memory operand */ + if (i_flags & RM) { + if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "case RM Mem_read status %02x @ %08x\n", TRAPME, addr); + // DIAG add 97 for correct PSD address CN.MMM test 32, subtest 1 fails + if ((TRAPME == MAPFLT) || (TRAPME == NPMEM) || (TRAPME == MPVIOL)) + PSD1 &= ~BIT31; /* force off last right */ + goto newpsd; /* memory read error or map fault */ + } + source = (t_uint64)temp; /* make into 64 bit value */ + switch(FC) { + case 0: /* word address, extend sign */ + source |= (source & MSIGN) ? D32LMASK : 0; + break; + case 1: /* left hw */ + source >>= 16; /* move left hw to right hw*/ + /* Fall through */ + case 3: /* right hw or right shifted left hw */ + source &= RMASK; /* use just the right hw */ + if (source & 0x8000) { /* check sign of 16 bit value */ + /* sign extend the value to leftmost 48 bits */ + source = LMASK | (source & RMASK); /* extend low 32 bits */ + source |= (D32LMASK); /* extend hi bits */ + } + break; + case 2: /* double word address */ + if ((addr & 7) != 2) { /* must be double word adddress */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC4 case RM wd 1/3 Mem_read DW status %02x @ %08x src %08x\n", + TRAPME, addr, (uint32)source); + goto newpsd; /* go execute the trap now */ + } + if ((TRAPME = Mem_read(addr+4, &temp))) { /* get the 2nd word from memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "case RM wd 2 Mem_read status %02x @ %08x\n", TRAPME, addr+4); + goto newpsd; /* memory read error or map fault */ + } + source = (source << 32) | (t_uint64)temp; /* merge in the low order 32 bits */ + dbl = 1; /* double word instruction */ + break; + case 4: /* byte mode, byte 0 */ + case 5: /* byte mode, byte 1 */ + case 6: /* byte mode, byte 2 */ + case 7: /* byte mode, byte 3 */ + source = (source >> (8*(7-FC))) & 0xff; /* right justify addressed byte */ + break; + } + } + + /* Read memory operand without doing sign extend for EOMX/ANMX/ORMX/ARMX */ + if (i_flags & RNX) { + if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "case RNX 2 Mem_read status %02x @ %08x\n", TRAPME, addr); + goto newpsd; /* memory read error or map fault */ + } + source = (t_uint64)temp; /* make into 64 bit value */ + switch(FC) { + case 0: /* word address and no sign extend */ + source &= D32RMASK; /* just l/o 32 bits */ + break; + case 1: /* left hw */ + source >>= 16; /* move left hw to right hw*/ + /* Fall through */ + case 3: /* right hw or right shifted left hw */ + source &= RMASK; /* use just the right hw */ + break; + case 2: /* double word address */ + if ((addr & 7) != 2) { /* must be double word adddress */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC5 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + if ((TRAPME = Mem_read(addr+4, &temp))) { /* get the 2nd word from memory */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "case RNX wd 2 Mem_read status %02x @ %08x\n", TRAPME, addr+4); + goto newpsd; /* memory read error or map fault */ + } + source = (source << 32) | (t_uint64)temp; /* merge in the low order 32 bits */ + dbl = 1; /* double word instruction */ + break; + case 4: /* byte mode, byte 0 */ + case 5: /* byte mode, byte 1 */ + case 6: /* byte mode, byte 2 */ + case 7: /* byte mode, byte 3 */ + source = (source >> (8*(7-FC))) & 0xff; /* right justify addressed byte */ + break; + } + } + + /* Read in if from register */ + if (i_flags & RR) { + if (FC == 2 && (i_flags & HLF) == 0) /* double dest? */ + dbl = 1; /* src must be dbl for dbl dest */ + dest = (t_uint64)GPR[reg]; /* get the register content */ + if (dbl) { /* is it double regs */ + if (reg & 1) { /* check for odd reg load */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC6 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + /* merge the regs into the 64bit value */ + dest = (((t_uint64)dest) << 32) | ((t_uint64)GPR[reg+1]); + } else { + /* sign extend the data value */ + dest |= (dest & MSIGN) ? D32LMASK : 0; + } + } + + /* For Base mode */ + if (i_flags & RB) { + dest = (t_uint64)BR[reg]; /* get base reg contents */ + } + + /* For register instructions */ + if (i_flags & R1) { + source = (t_uint64)GPR[sreg]; + if (dbl) { + if (sreg & 1) { + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC7 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + /* merge the regs into the 64bit value */ + source = (source << 32) | ((t_uint64)GPR[reg+1]); + } else { + /* sign extend the data value */ + source |= (source & MSIGN) ? ((t_uint64)MASK32) << 32: 0; + } + } + + /* process instruction op code */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "PSD %08x %08x SW OP %04x IR %08x addr %08x\n", + PSD1, PSD2, OP, IR, addr); + + /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + /* start processing the opcodes */ + /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + switch (OP>>2) { + /* + * For op-codes=00,04,08,0c,10,14,28,2c,38,3c,40,44,60,64,68 + */ + /* Reg - Reg instruction Format (16 bit) */ + /* |--------------------------------------| */ + /* |0 1 2 3 4 5|6 7 8 |9 10 11|12 13 14 15| */ + /* | Op Code | DReg | SReg | Aug Code | */ + /* |--------------------------------------| */ + case 0x00>>2: /* HLF - HLF */ /* CPU General operations */ + switch(opr & 0xF) { /* switch on aug code */ + case 0x0: /* HALT */ +#ifndef TEMP4DEBUG + if ((MODES & PRIVBIT) == 0) { /* must be privileged to halt */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* Privlege violation trap */ + } + if (CPUSTATUS & BIT23) { /* Priv mode halt must be enabled */ + TRAPME = PRIVHALT_TRAP; /* set the trap to take */ + goto newpsd; /* Privlege mode halt trap */ + } +#endif + sim_debug(DEBUG_EXP, &cpu_dev, + "\n[][][][][][][][][][] HALT [][][][][][][][][][]\n"); + sim_debug(DEBUG_EXP, &cpu_dev, + "PSD1 %.8x PSD2 %.8x TRAPME %.4x CPUSTATUS %08x\n", + PSD1, PSD2, TRAPME, CPUSTATUS); + for (ix=0; ix<8; ix+=2) { + sim_debug(DEBUG_EXP, &cpu_dev, + "GPR[%d] %.8x GPR[%d] %.8x\n", ix, GPR[ix], ix+1, GPR[ix+1]); + } + sim_debug(DEBUG_EXP, &cpu_dev, + "[][][][][][][][][][] HALT [][][][][][][][][][]\n"); + + fprintf(stdout, "\r\n[][][][][][][][][][] HALT [][][][][][][][][][]\r\n"); + fprintf(stdout, "PSD1 %.8x PSD2 %.8x TRAPME %.4x CPUSTATUS %08x\r\n", + PSD1, PSD2, TRAPME, CPUSTATUS); + for (ix=0; ix<8; ix+=2) { + fprintf(stdout, "GPR[%d] %.8x GPR[%d] %.8x\r\n", + ix, GPR[ix], ix+1, GPR[ix+1]); + } + if (MODES & BASEBIT) { /* see if based */ + for (ix=0; ix<8; ix+=2) { + fprintf(stdout, "BR[%d] %.8x BR[%d] %.8x\r\n", + ix, BR[ix], ix+1, BR[ix+1]); + } + } + fprintf(stdout, "[][][][][][][][][][] HALT [][][][][][][][][][]\r\n"); +/*TEST DIAG*/reason = STOP_HALT; /* do halt for now */ + break; + + case 0x1: /* WAIT */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged to wait */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* Privlege violation trap */ + } + /* if interrupts are blocked, system check trap */ + if (CPUSTATUS & BIT24) { /* status word bit 24 says blocked */ + TRAPME = SYSTEMCHK_TRAP; /* trap condition if F class */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT12; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT20; /* set bit 20 of trap status */ + goto newpsd; /* system check trap */ + } + if (wait4int == 0) { + time_t result = time(NULL); + sim_debug(DEBUG_DETAIL, &cpu_dev, + "Starting WAIT mode %08x\n", (uint32)result); + } + wait4int = 1; /* show we are waiting for interrupt */ + /* tell simh we will be waiting */ + sim_idle(TMR_RTC, 0); /* wait for next pending device event */ + irq_pend = 1; /* start scanning interrupts again */ + i_flags |= BT; /* keep PC from being incremented while waiting */ + break; + case 0x2: /* NOP */ + break; + case 0x3: /* LCS */ + /* get console switches from memory loc 0x780 */ + if ((TRAPME = Mem_read(0x780, &GPR[reg]))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + set_CCs(GPR[reg], 0); /* set the CC's, CC1 = 0 */ + break; + case 0x4: /* ES */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + /* reg is reg to extend sign into from reg+1 */ + GPR[reg] = (GPR[reg+1] & FSIGN) ? FMASK : 0; + set_CCs(GPR[reg], 0); /* set CCs, CC2 & CC3 */ + break; + case 0x5: /* RND */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + temp = GPR[reg]; /* save the current contents of specified reg */ + t = (temp & FSIGN) != 0; /* set flag for sign bit not set in temp value */ + bc = 1; + t |= ((bc & FSIGN) != 0) ? 2 : 0; /* ditto for the bit value */ + if (GPR[reg+1] & FSIGN) { /* if sign of R+1 is set, incr R by 1 */ + temp += bc; /* add the bit value to the reg */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if ((t == 3 && (temp & FSIGN) == 0) || + (t == 0 && (temp & FSIGN) != 0)) { + ovr = 1; /* we have an overflow */ + } + GPR[reg] = temp; /* update the R value */ + } else + ovr = 0; + set_CCs(temp, ovr); /* set the CC's, CC1 = ovr */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* handle trap */ + } + break; + case 0x6: /* BEI */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged to BEI */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* Privlege violation trap */ + } +#ifdef DYNAMIC_DEBUG +TPSD[0] = PSD1; +TPSD[1] = PSD2; +#endif + CPUSTATUS |= BIT24; /* into status word bit 24 too */ + PSD2 &= ~(SETBBIT|RETBBIT); /* clear bit 48 & 49 */ + MODES &= ~(BLKMODE|RETBLKM); /* reset blocked & retain mode bits */ + PSD2 |= SETBBIT; /* set to blocked state */ + MODES |= BLKMODE; /* set blocked mode */ + + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ +#ifdef DYNAMIC_DEBUG +sim_debug(DEBUG_IRQ, &cpu_dev, + "BEI OPSD %.8x %.8x NPSD %.8x %.8x SPDF5 %.8x CPUSTATUS %08x\n", + TPSD[0], TPSD[1], PSD1, PSD2, SPAD[0xf5], CPUSTATUS); +#endif + break; + + case 0x7: /* UEI */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged to UEI */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* Privlege violation trap */ + } +#ifdef DYNAMIC_DEBUG +TPSD[0] = PSD1; +TPSD[1] = PSD2; +#endif + if (CPUSTATUS & BIT24) { /* see if old mode is blocked */ + irq_pend = 1; /* start scanning interrupts again */ +#ifdef LEAVE_ACTIVE + if (irq_auto) { +/*AIR*/ INTS[irq_auto] &= ~INTS_ACT; /* deactivate specified int level */ +/*AIR*/ SPAD[irq_auto+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>IntX deactivate level %02x at UEI PSD1 %08x PSD2 %08x\n", + irq_auto, PSD1, PSD2); +/*AIR*/ irq_auto = 0; /* show done processing in blocked mode */ + } +#endif + } + CPUSTATUS &= ~BIT24; /* clear status word bit 24 */ + MODES &= ~(BLKMODE|RETBLKM); /* reset blocked & retain mode bits */ + PSD2 &= ~(SETBBIT|RETBBIT); /* clear bits 48 & 49 to be unblocked */ + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ +#ifdef DYNAMIC_DEBUG +sim_debug(DEBUG_IRQ, &cpu_dev, + "UEI OPSD %.8x %.8x NPSD %.8x %.8x SPDF5 %.8x CPUSTATUS %08x\n", + TPSD[0], TPSD[1], PSD1, PSD2, SPAD[0xf5], CPUSTATUS); +#endif + break; + case 0x8: /* EAE */ + PSD1 |= AEXPBIT; /* set the enable AEXP flag in PSD 1 */ + MODES |= AEXPBIT; /* enable arithmetic exception in modes & PSD 1 */ + CPUSTATUS |= AEXPBIT; /* into status word too */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + break; + case 0x9: /* RDSTS */ + GPR[reg] = CPUSTATUS; /* get CPU status word */ + break; + case 0xA: /* SIPU */ /* ignore for now */ + sim_debug(DEBUG_CMD, &cpu_dev, + "SIPU CPUSTATUS %08x SPAD[0xf9] %08x\n", CPUSTATUS, SPAD[0xf9]); + break; + case 0xB: /* RWCS */ /* RWCS ignore for now */ + /* reg = specifies reg containing the ACS/WCS address */ + /* sreg = specifies the ACS/WCS address */ + /* if the WCS option is not present, address spec error */ + /* if the mem addr is not a DW, address spec error */ + /* If 0<-Rs<=fff and Rs bit 0=0, then PROM address */ + /* If 0<-Rs<=fff and Rs bit 0=1, then ACS address */ + /* if bit 20 set, WCS enables, else addr spec error */ + if ((CPUSTATUS & 0x00000800) == 0) { + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + /* Maybe TODO copy something from WCS */ + break; + case 0xC: /* WWCS */ /* WWCS ignore for now */ + /* reg = specifies the logical address in memory that */ + /* is to receive the ACS/WCS contents */ + /* sreg = specifies the ACS/WCS address */ + /* bit 20 of cpu stat must be set=1 to to write to ACS or WCS */ + /* bit 21 of CPU stat must be 0 to write to ACS */ + /* if bit 20 set, WCS enables, else addr spec error */ + if ((CPUSTATUS & 0x00000800) == 0) { + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + /* Maybe TODO copy something to WCS */ + break; + case 0xD: /* SEA */ + if (MODES & BASEBIT) /* see if based */ + goto inv; /* invalid instruction in based mode */ + MODES |= EXTDBIT; /* set new extended flag (bit 5) in modes & PSD */ + PSD1 |= EXTDBIT; /* set the enable AEXP flag in PSD1 */ + CPUSTATUS |= EXTDBIT; /* into status word too */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + break; + case 0xE: /* DAE */ + MODES &= ~AEXPBIT; /* disable arithmetic exception in modes & PSD */ + PSD1 &= ~AEXPBIT; /* disable AEXP flag in PSD */ + CPUSTATUS &= ~AEXPBIT; /* into status word too */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + break; + + case 0xF: /* CEA */ + if (MODES & BASEBIT) /* see if based */ + goto inv; /* invalid instruction in based mode */ + MODES &= ~EXTDBIT; /* disable extended mode in modes and PSD */ + PSD1 &= ~EXTDBIT; /* disable extended mode (bit 5) flag in PSD */ + CPUSTATUS &= ~EXTDBIT; /* into status word too */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + break; + } + break; + case 0x04>>2: /* 0x04 RR|R1|SD|HLF - SD|HLF */ /* ANR, SMC, CMC, RPSWT */ + i_flags &= ~SCC; /* make sure we do not set CC's for dest value */ + switch(opr & 0xF) { + case 0x0: /* ANR */ + dest &= source; /* just an and reg to reg */ + if (dest & MSIGN) + dest |= D32LMASK; /* force upper word to all ones */ + i_flags |= SCC; /* make sure we set CC's for dest value */ + break; + + case 0xA: /* CMC */ /* Cache Memory Control - Diag use only */ + if (CPU_MODEL == MODEL_87) + break; /* just ignore */ + if (CPU_MODEL < MODEL_67) { + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + if (CPU_MODEL <= MODEL_V6) { + /* Cache memory control bit assignments for reg */ + /* 0-22 reserved, must be zero */ + /* 23 - Initialize Instruction Cache Bank 0 On = 1 Off = 0 */ + /* 24 - Initialize Instruction Cache Bank 1 On = 1 Off = 0 */ + /* 25 - Initialize Operand Cache Bank 0 On = 1 Off = 0 */ + /* 26 - Initialize Operand Cache Bank 1 On = 1 Off = 0 */ + /* 27 - Enable Instruction Cache Bank 0 On = 1 Off = 0 */ + /* 28 - Enable Instruction Cache Bank 1 On = 1 Off = 0 */ + /* 29 - Enable Operand Cache Bank 0 On = 1 Off = 0 */ + /* 30 - Enable Operand Cache Bank 1 On = 1 Off = 0 */ + /* 31 - Bypass Instruction Cache Bank 1 On = 1 Off = 0 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "CMC V6/67 GPR[%02x] = %04x CMCR = %08x CPU STATUS SPAD[f9] = %08x\r\n", + reg, GPR[reg], CMCR, SPAD[0xf9]); + CMCR = GPR[reg]; /* write reg bits 23-31 to cache memory controller */ + i_flags &= ~SD; /* turn off store dest for this instruction */ + } else + if (CPU_MODEL == MODEL_V9) { + sim_debug(DEBUG_EXP, &cpu_dev, + "CMC V9 GPR[%02x] = %08x CMCR = %08x CPU STATUS SPAD[f9] = %08x\r\n", + reg, GPR[reg], CMCR, SPAD[0xf9]); + CMCR = GPR[reg]; /* write reg bits 23-31 to cache memory controller */ + i_flags &= ~SD; /* turn off store dest for this instruction */ + } + break; + + case 0x7: /* SMC */ /* Shared Memory Control - Diag use only */ + if (CPU_MODEL < MODEL_67) { + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + /* Shared memory control bit assignments for reg */ + /* 0 - Reserved */ + /* 1 - Shared Memory Enabled (=1)/Disabled (=0) */ + /* 2-6 - Upper Bound of Shared Memory */ + /* 7 - Read & Lock Enabled (=1)/Disabled (=0) */ + /* 8-12 - Lower Bound of Shared Memory */ + /* 3-31 - Reserved and must be zero */ + sim_debug(DEBUG_CMD, &cpu_dev, + "SMC V6/67 GPR[%02x] = %08x SMCR = %08x CPU STATUS SPAD[f9] = %08x\n", + reg, GPR[reg], SMCR, SPAD[0xf9]); + SMCR = GPR[reg]; /* write reg bits 0-12 to shared memory controller */ + i_flags &= ~SD; /* turn off store dest for this instruction */ + break; + +/* 67, 97, V6 Computer Configuration Word is copied when bit zero of Rd set to one (0x80000000) */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* |00|01|02 03 04 05 06|07|08 09 10 11 12|13 14 15|16|17|18|19|20 21|22|23 24 25 26|27|28|29|30|31| */ +/* | | S| Upper Bound |RL| Lower Bound |Reserved|4k|8k|SM|P2| Res |AP| Reserved |I0|I1|D0|D1|BY| */ +/* | 0| x| x x x x x| x| x x x x x| 0 0 0| x| x| x| x| 0 0| 0| 0 0 0 0| x| x| x| x| x| */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* */ +/* Bits: 0 Reserved */ +/* 1 Shared Memory Enabled (=1)/Disabled (=0) */ +/* 2-6 Upper Bound of Shared Memory */ +/* 7 Read & Lock Enabled (=1)/Disabled (=0) */ +/* 8-12 Lower Bound of Shared Memory */ +/* 13-15 Reserved */ +/* 16 4K WCS Option Present (=1)/Not Present (=0) */ +/* 17 8K WCS Option Present (=1)/Not Present (=0) */ +/* 18 Firmware Control Store Mode ROMSIM (=1)/PROM (=0) */ +/* 19 IPU Present (=1)/Not Present (=0) */ +/* 20-21 Reserved */ +/* 22 Access Protection ECO Present (=0)/No Access Protection (=0) V6 & V9 */ +/* 23-26 Reserved */ +/* 27 Instruction Cache Bank 0 on (=1)/Off (=0) */ +/* 28 Instruction Cache Bank 1 on (=1)/Off (=0) */ +/* 29 Data Cache Bank 0 on (=1)/Off (=0) */ +/* 30 Data Cache Bank 1 on (=1)/Off (=0) */ +/* 31 Instruction Cache Enabled (=1)/Disabled (=0) */ +/* */ +/* V9 Computer Configuration Word when bit zero of Rd set to one (0x80000000) */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* |00 01 02 03|04 05 06 07|08 09 10 11|12 13 14 15|16|17|18|19|20|21|22|23|24 25 26 27|28 29 30 31| */ +/* | CPU Bank1 | CPU Bank2 | IPU Bank0 | IPU Bank1 |M1|M2|C1|C2|P2|SM|AP| | CPU FW Ver| CPU FW Rev| */ +/* | x x x x| x x x x| x x x x| x x x x| x| x| x| x| x| x| x| x| x x x x| x x x x| */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* */ +/* Bits: 0-15 Cache/Shadow Unit Present (=1)/Not Present (=0) */ +/* 16 MACC Present in CP1 (=1)/Not Present (=0) */ +/* 17 MACC Present in CP2 (=1)/Not Present (=0) */ +/* 18 CP1 Present (=1)/CP1 Not Present (=0) */ +/* 19 CP2 Present (=1)/CP2 Not Present (=0) */ +/* 20 IPU Present (=1)/Not Present (=0) */ +/* 21 Shared Memory Present (=1)/Not Present (=0) */ +/* 22 Access Protection ECO Present (=0)/No Access Protection (=0) V6 & V9 */ +/* 23 Reserved */ +/* 24-27 CPU Firmware Version */ +/* 28-31 CPU Formware Revision Level */ +/* */ +/* V9 CPU Shadow Memory Configuration Word when bit one of Rd set to one (0x40000000) */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* |00 01 02|03 04 05 06 07|08 09 10 11 12 13 14 15|16 17 18 19 20 21 22 23|24 25 26 27 28 29 30 31| */ +/* | SMU # | Not Used | CPU Unit 1 Base Addr | CPU Unit 2 Base Addr | CPU Unit 3 Base Addr | */ +/* | x x x| 0 0 0 0 0| x x x x x x x 0| x x x x x x x 0| x x x x x x x 0| */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* */ +/* Bits: 0 Shadow Memory Unit 1 Present (=1)/Not Present (=0) */ +/* 1 Shadow Memory Unit 2 Present (=1)/Not Present (=0) */ +/* 2 Shadow Memory Unit 3 Present (=1)/Not Present (=0) */ +/* 3-7 Not Used */ +/* 8-14 Shadow Memory Unit 1 Base Address (bits 08-14 of address) */ +/* 15 Always zero */ +/* 16-22 Shadow Memory Unit 2 Base Address (bits 08-14 of address) */ +/* 23 Always zero */ +/* 24-30 Shadow Memory Unit 2 Base Address (bits 08-14 of address) */ +/* 31 Always zero */ +/* */ +/* V9 IPU Shadow Memory Configuration Word when bit two of Rd set to one (0x20000000) */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* |00 01 02|03 04 05 06 07|08 09 10 11 12 13 14 15|16 17 18 19 20 21 22 23|24 25 26 27 28 29 30 31| */ +/* | SMU # | Not Used | IPU Unit 1 Base Addr | IPU Unit 2 Base Addr | IPU Unit 3 Base Addr | */ +/* | x x x| 0 0 0 0 0| x x x x x x x 0| x x x x x x x 0| x x x x x x x 0| */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* */ +/* Bits: 0 Shadow Memory Unit 1 Present (=1)/Not Present (=0) */ +/* 1 Shadow Memory Unit 2 Present (=1)/Not Present (=0) */ +/* 2 Shadow Memory Unit 3 Present (=1)/Not Present (=0) */ +/* 3-7 Not Used */ +/* 8-14 Shadow Memory Unit 1 Base Address (bits 08-14 of address) */ +/* 15 Always zero */ +/* 16-22 Shadow Memory Unit 2 Base Address (bits 08-14 of address) */ +/* 23 Always zero */ +/* 24-30 Shadow Memory Unit 2 Base Address (bits 08-14 of address) */ +/* 31 Always zero */ +/* */ +/* When bit zero of Rd is zero, PSW word 2 is copies to Rd (0x00000000) */ +/* */ + case 0xB: /* RPSWT */ /* Read Processor Status Word 2 (PSD2) */ + if ((GPR[reg] & 0x80000000) && (CPU_MODEL < MODEL_V9)) { + /* if bit 0 of reg set, return (default 0) CPU Configuration Word */ + dest = CCW; /* no cache or shared memory */ + /* make sure bit 19 is zero saying IPU not present */ + dest &= ~0x00001000; /* reset IPU bit for DIAGS */ + /* bit 22 set for access ECO present */ + dest |= 0x00000200; /* set ECO bit for DIAGS */ + /* Try setting cache on bits 27-31 */ + dest |= 0x0000001f; /* set SIM bit for DIAGS */ + } else + if ((GPR[reg] & 0x80000000) && (CPU_MODEL == MODEL_V9)) { + /* if bit 0 of reg set, return Cache/Shadow Configuration Word */ + CMSMC = 0xffff0000; /* no CPU/IPU Cache/Shadow unit present */ + CMSMC |= 0x00000000; /* CPU Cache/Shadow unit present */ + CMSMC |= 0x00000800; /* bit 20, IPU not present */ + CMSMC |= 0x00000200; /* bit 22, Access Protection ECO present */ + CMSMC |= 0x0000001f; /* CPU Firmware Version 1/Rev level 0 */ + dest = CMSMC; /* return starus */ + } else + if ((GPR[reg] & 0x40000000) && (CPU_MODEL == MODEL_V9)) { + /* if bit 1 of reg set, return CPU Shadow Memory Configuration Word */ + CSMCW = 0x00000000; /* no Shadow unit present */ + dest = CSMCW; /* return starus */ + } else + if ((GPR[reg] & 0x20000000) && (CPU_MODEL == MODEL_V9)) { + /* if bit 2 of reg set, return Cache Memory Configuration Word */ + ISMCW = 0x00000000; /* no Shadow unit present */ + dest = ISMCW; /* return starus */ + } else + if ((GPR[reg] & BIT0) == 0x00000000) { + /* if bit 0 of reg not set, return PSD2 */ + /* make sure bit 49 (block state is current state */ + dest = SPAD[0xf5]; /* get PSD2 for user from SPAD 0xf5 */ + dest &= ~(SETBBIT|RETBBIT); /* clear bit 48 & 49 to be unblocked */ + if (CPUSTATUS & BIT24) { /* see if old mode is blocked */ + dest |= SETBBIT; /* set bit 49 for blocked */ + } + } + break; + + case 0x08: /* 0x0408 INV (Diag Illegal instruction) */ + /* HACK HACK HACK for DIAGS */ + if (CPU_MODEL <= MODEL_27) { /* DIAG error for 32/27 only */ + if ((PSD1 & 2) == 0) /* if lf hw instruction */ + i_flags |= HLF; /* if nop in rt hw, bump pc a word */ + } + /* drop through */ + default: /* INV */ /* everything else is invalid instruction */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + break; + } + break; + + case 0x08>>2: /* 0x08 SCC|RR|R1|SD|HLF - */ /* ORR or ORRM */ + dest |= source; /* or the regs into dest reg */ + switch(opr & 0x0f) { + case 0x8: /* this is ORRM op */ + dest &= GPR[4]; /* mask with reg 4 contents */ + /* drop thru */ + case 0x0: /* this is ORR op */ + if (dest & MSIGN) /* see if we need to sign extend */ + dest |= D32LMASK; /* force upper word to all ones */ + break; + default: /* INV */ /* everything else is invalid instruction */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + break; + + case 0x0C>>2: /* 0x0c SCC|RR|R1|SD|HLF - SCC|SD|HLF */ /* EOR or EORM */ + dest ^= source; /* exclusive or the regs into dest reg */ + switch(opr & 0x0f) { + case 0x8: /* this is EORM op */ + dest &= GPR[4]; /* mask with reg 4 contents */ + /* drop thru */ + case 0x0: /* this is EOR op */ + if (dest & MSIGN) /* see if we need to sign extend */ + dest |= D32LMASK; /* force upper word to all ones */ + break; + default: /* INV */ /* everything else is invalid instruction */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + break; + + case 0x10>>2: /* 0x10 HLF - HLF */ /* CAR or (basemode SACZ ) */ + if ((opr & 0xF) == 0) { /* see if CAR instruction */ + /* handle non basemode/basemode CAR instr */ + if ((int32)GPR[reg] < (int32)GPR[sreg]) + CC = CC3BIT; /* Rd < Rs; negative */ + else + if (GPR[reg] == GPR[sreg]) + CC = CC4BIT; /* Rd == Rs; zero */ + else + CC = CC2BIT; /* Rd > Rs; positive */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + } else { + if ((MODES & BASEBIT) == 0) { /* if not basemode, error */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + goto newpsd; /* handle trap */ + } + /* handle basemode SACZ instruction */ +sacz: /* non basemode SCZ enters here */ + temp = GPR[reg]; /* get destination reg contents to shift */ + CC = 0; /* zero the CC's */ + t = 0; /* start with zero shift count */ + if (temp == 0) { + CC = CC4BIT; /* set CC4 showing dest is zero & cnt is zero too */ + } +#ifdef NOT_FOR_DIAG + /* The doc says the reg is not shifted if bit 0 is set on entry. */ + /* diags says it does, so that is what we will do */ + /* set count to zero, but shift reg 1 left */ + else + if (temp & BIT0) { + CC = 0; /* clear CC4 & set count to zero */ + } +#endif + else + if (temp != 0) { /* shift non zero values */ + while ((temp & FSIGN) == 0) { /* shift the reg until bit 0 is set */ + temp <<= 1; /* shift left 1 bit */ + t++; /* increment shift count */ + } + temp <<= 1; /* shift the sign bit out */ + } + GPR[reg] = temp; /* save the shifted values */ + GPR[sreg] = t; /* set the shift cnt into the src reg */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + } + break; + + case 0x14>>2: /* 0x14 HLF - HLF */ /* CMR compare masked with reg */ + if (opr & 0xf) { /* any subop not zero is error */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + temp = GPR[reg] ^ GPR[sreg]; /* exclusive or src and destination values */ + temp &= GPR[4]; /* and with mask reg (GPR 4) */ + CC = 0; /* set all CCs zero */ + if (temp == 0) /* if result is zero, set CC4 */ + CC = CC4BIT; /* set CC4 to show result 0 */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + break; + + case 0x18>>2: /* 0x18 HLF - HLF */ /* SBR, (basemode ZBR, ABR, TBR */ + if (MODES & BASEBIT) { /* handle basemode ZBR, ABR, TBR */ + if ((opr & 0xC) == 0x0) /* SBR instruction */ + goto sbr; /* use nonbase SBR code */ + if ((opr & 0xC) == 0x4) /* ZBR instruction */ + goto zbr; /* use nonbase ZBR code */ + if ((opr & 0xC) == 0x8) /* ABR instruction */ + goto abr; /* use nonbase ABR code */ + if ((opr & 0xC) == 0xC) /* TBR instruction */ + goto tbr; /* use nonbase TBR code */ +inv: + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + + } else { /* handle non basemode SBR */ + if (opr & 0xc) { /* any subop not zero is error */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } +sbr: /* handle basemode too */ + /* move the byte field bits 14-15 to bits 27-28 */ + /* or in the bit# from dest reg field bits 6-8 into bit 29-31 */ + bc = (((opr << 3) & 0x18) | reg); /* get # bits to shift right */ + bc = BIT0 >> bc; /* make a bit mask of bit number */ + t = (PSD1 & 0x70000000) >> 1; /* get old CC bits 1-3 into CCs 2-4*/ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + if (GPR[sreg] & bc) /* test the bit in src reg */ + t |= CC1BIT; /* set CC1 to the bit value */ + GPR[sreg] |= bc; /* set the bit in src reg */ + PSD1 |= t; /* update the CC's in the PSD */ + } + break; + + case 0x1C>>2: /* 0x1C HLF - HLF */ /* ZBR (basemode SRA, SRL, SLA, SLL) */ + if (MODES & BASEBIT) { /* handle basemode SRA, SRL, SLA, SLL */ + bc = opr & 0x1f; /* get bit shift count */ + if ((opr & 0x60) == 0x00) { /* SRA instruction */ + temp = GPR[reg]; /* get reg value to shift */ + t = temp & FSIGN; /* sign value */ + for (ix=0; ix>= 1; /* shift bit 0 right one bit */ + temp |= t; /* restore original sign bit */ + } + GPR[reg] = temp; /* save the new value */ + break; + } + if ((opr & 0x60) == 0x20) { /* SRL instruction */ + GPR[reg] >>= bc; /* value to be output */ + break; + } + if ((opr & 0x60) == 0x40) { /* SLA instruction */ + temp = GPR[reg]; /* get reg value to shift */ + t = temp & FSIGN; /* sign value */ + ovr = 0; /* set ovr off */ + for (ix=0; ix> bc; /* make a bit mask of bit number */ + t = (PSD1 & 0x70000000) >> 1; /* get old CC bits 1-3 into CCs 2-4*/ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + if (GPR[sreg] & bc) /* test the bit in src reg */ + t |= CC1BIT; /* set CC1 to the bit value */ + GPR[sreg] &= ~bc; /* reset the bit in src reg */ + PSD1 |= t; /* update the CC's in the PSD */ + } + break; + + case 0x20>>2: /* 0x20 HLF - HLF */ /* ABR (basemode SRAD, SRLD, SLAD, SLLD) */ + if (MODES & BASEBIT) { /* handle basemode SRAD, SRLD, SLAD, SLLD */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + dest = (t_uint64)GPR[reg+1]; /* get low order reg value */ + dest |= (((t_uint64)GPR[reg]) << 32); /* insert upper reg value */ + bc = opr & 0x1f; /* get bit shift count */ + source = dest & DMSIGN; /* 64 bit sign value */ + switch (opr & 0x60) { + case 0x00: /* SRAD instruction */ + for (ix=0; ix>= 1; /* shift bit 0 right one bit */ + dest |= source; /* restore original sign bit */ + } + break; + + case 0x20: /* SRLD */ + dest >>= bc; /* shift right #bits */ + break; + + case 0x40: /* SLAD instruction */ + ovr = 0; /* set ovr off */ + for (ix=0; ix>32) & FMASK);/* save the hi order reg */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + if (ovr) + PSD1 |= BIT1; /* CC1 in PSD */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* go execute the trap now */ + } + break; + + case 0x60: /* SLLD */ + dest <<= bc; /* shift left #bits */ + break; + } + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + break; + + } else { /* handle nonbase mode ABR */ + if (opr & 0xc) { /* any subop not zero is error */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } +abr: /* basemode ABR too */ + /* move the byte field bits 14-15 to bits 27-28 */ + /* or in the bit# from dest reg field bits 6-8 into bit 29-31 */ + bc = (((opr << 3) & 0x18) | reg); /* get # bits to shift right */ + bc = BIT0 >> bc; /* make a bit mask of bit number */ + temp = GPR[sreg]; /* get reg value to add bit to */ + t = (temp & FSIGN) != 0; /* set flag for sign bit not set in temp value */ + t |= ((bc & FSIGN) != 0) ? 2 : 0; /* ditto for the bit value */ + temp += bc; /* add the bit value to the reg */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if ((t == 3 && (temp & FSIGN) == 0) || + (t == 0 && (temp & FSIGN) != 0)) { + ovr = 1; /* we have an overflow */ + } + GPR[sreg] = temp; /* save the new value */ + set_CCs(temp, ovr); /* set the CC's, CC1 = ovr */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* handle trap */ + } + } + break; + + case 0x24>>2: /* 0x24 HLF - HLF */ /* TBR (basemode SRC) */ + if (MODES & BASEBIT) { /* handle SRC basemode */ + bc = opr & 0x1f; /* get bit shift count */ + temp = GPR[reg]; /* get reg value to shift */ + if ((opr & 0x60) == 0x40) { /* SLCBR instruction */ + for (ix=0; ix>= 1; /* shift the bit out */ + if (t) + temp |= BIT0; /* put in new sign bit */ + } + } + GPR[reg] = temp; /* shift result */ + } else { /* handle TBR non basemode */ + if (opr & 0xc) { /* any subop not zero is error */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } +tbr: /* handle basemode TBR too */ + /* move the byte field bits 14-15 to bits 27-28 */ + /* or in the bit# from dest reg field bits 6-8 into bit 29-31 */ + bc = (((opr << 3) & 0x18) | reg); /* get # bits to shift right */ + bc = BIT0 >> bc; /* make a bit mask of bit number */ + t = (PSD1 & 0x70000000) >> 1; /* get old CC bits 1-3 into CCs 2-4*/ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + if (GPR[sreg] & bc) /* test the bit in src reg */ + t |= CC1BIT; /* set CC1 to the bit value */ + PSD1 |= t; /* update the CC's in the PSD */ + } + break; + + case 0x28>>2: /* 0x28 HLF - HLF */ /* Misc OP REG instructions */ + switch(opr & 0xF) { + case 0x0: /* TRSW */ + if (MODES & BASEBIT) + temp = 0x78FFFFFE; /* bits 1-4 and 24 bit addr for based mode */ + else + temp = 0x7807FFFE; /* bits 1-4 and 19 bit addr for non based mode */ + addr = GPR[reg]; /* get reg value */ + /* we are returning to the addr in reg, set CC's from reg */ + /* update the PSD with new address from reg */ + PSD1 &= ~temp; /* clean the bits to be changed */ + PSD1 |= (addr & temp); /* insert the CC's and address */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "TRSW REG %01x PSD %08x %08x modes %08x temp %06x\n", + reg, PSD1, PSD2, MODES, temp); + i_flags |= BT; /* we branched, so no PC update */ + break; + + case 0x2: /* XCBR */ /* Exchange base registers */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + temp = BR[reg]; /* get dest reg value */ + BR[reg] = BR[sreg]; /* put source reg value int dest reg */ + BR[sreg] = temp; /* put dest reg value into src reg */ + break; + + case 0x4: /* TCCR */ /* Transfer condition codes to GPR bits 28-31 */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + temp = CC >> 27; /* right justify CC's in reg */ + GPR[reg] = temp; /* put dest reg value into src reg */ + break; + + case 0x5: /* TRCC */ /* Transfer GPR bits 28-31 to condition codes */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + PSD1 = ((PSD1 & 0x87fffffe)|((GPR[reg] & 0xf) << 27)); /* insert CCs from reg */ + break; + + case 0x8: /* BSUB */ /* Procedure call */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + + /* if Rd field is 0 (reg is b6-b8), this is a BSUB instruction */ + /* otherwise it is a CALL instruction (Rd != 0) */ + if (reg == 0) { + /* BSUB instruction */ + uint32 cfp = BR[2]; /* get dword bounded frame pointer from BR2 */ + if ((BR[2] & 0x7) != 0) { + /* Fault, must be dw bounded address */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + goto newpsd; /* go execute the trap now */ + } + cfp = BR[2] & 0x00fffff8; /* clean the cfp address to 24 bit dw */ + + M[cfp>>2] = (PSD1 + 2) & 0x01fffffe; /* save AEXP bit and PC into frame */ + M[(cfp>>2)+1] = 0x80000000; /* show frame created by BSUB instr */ + BR[1] = BR[sreg] & MASK24; /* Rs reg to BR 1 */ + PSD1 = (PSD1 & 0xff000000) | (BR[1] & MASK24); /* New PSD address */ + BR[3] = GPR[0]; /* GPR 0 to BR 3 (AP) */ + BR[0] = cfp; /* set frame pointer from BR 2 into BR 0 */ + i_flags |= BT; /* we changed the PC, so no PC update */ + } else + { + /* CALL instruction */ + /* get frame pointer from BR2-16 words & make it a dword addr */ + uint32 cfp = ((BR[2]-0x40) & 0x00fffff8); + + /* if cfp and cfp+15w are in different maps, then addr exception error */ + if ((cfp & 0xffe000) != ((cfp+0x3f) & 0xffe000)) { + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + + temp = (PSD1+2) & 0x01fffffe; /* save AEXP bit and PC from PSD1 in to frame */ + if ((TRAPME = Mem_write(cfp, &temp))) { /* Save the PSD into memory */ + goto newpsd; /* memory write error or map fault */ + } + + temp = 0x00000000; /* show frame created by CALL instr */ + if ((TRAPME = Mem_write(cfp+4, &temp))) { /* Save zero into memory */ + goto newpsd; /* memory write error or map fault */ + } + + /* Save BR 0-7 to stack */ + for (ix=0; ix<8; ix++) { + if ((TRAPME = Mem_write(cfp+(4*ix)+8, &BR[ix]))) { /* Save into memory */ + goto newpsd; /* memory write error or map fault */ + } + } + + /* save GPR 2-8 to stack */ + for (ix=2; ix<8; ix++) { + if ((TRAPME = Mem_write(cfp+(4*ix)+32, &GPR[ix]))) { /* Save into memory */ + goto newpsd; /* memory write error or map fault */ + } + } + + /* keep bits 0-7 from old PSD */ + PSD1 = (PSD1 & 0xff000000) | ((BR[sreg]) & MASK24); /* New PSD address */ + BR[1] = BR[sreg]; /* Rs reg to BR 1 */ + BR[3] = GPR[reg]; /* Rd to BR 3 (AP) */ + BR[0] = cfp; /* set current frame pointer into BR[0] */ + BR[2] = cfp; /* set current frame pointer into BR[2] */ + i_flags |= BT; /* we changed the PC, so no PC update */ + } + break; + + case 0xC: /* TPCBR */ /* Transfer program Counter to Base Register */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + BR[reg] = PSD1 & 0xfffffe; /* save PC from PSD1 into BR */ + break; + + case 0xE: /* RETURN */ /* procedure return for basemode calls */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + t = BR[0]; /* get frame pointer from BR[0] */ + if ((TRAPME = Mem_read(t+4, &temp))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + /* if Bit0 set, restore all saved regs, else restore only BRs */ + if ((temp & BIT0) == 0) { /* see if GPRs are to be restored */ + /* Bit 0 is not set, so restore all GPRs */ + for (ix=2; ix<8; ix++) + if ((TRAPME = Mem_read(t+ix*4+32, &GPR[ix]))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + } + for (ix=0; ix<8; ix++) { + if ((TRAPME = Mem_read(t+ix*4+8, &BR[ix]))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + } + PSD1 &= ~0x1fffffe; /* leave everything except AEXP bit and PC */ + if ((TRAPME = Mem_read(t, &temp))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + PSD1 |= (temp & 0x01fffffe); /* restore AEXP bit and PC from call frame */ + i_flags |= BT; /* we changed the PC, so no PC update */ + break; + + case 0x1: /* INV */ + case 0x3: /* INV */ + case 0x6: /* INV */ + case 0x7: /* INV */ + case 0x9: /* INV */ + case 0xA: /* INV */ + case 0xB: /* INV */ + case 0xD: /* INV */ + case 0xF: /* INV */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + break; + } + break; + + case 0x2C>>2: /* 0x2C HLF - HLF */ /* Reg-Reg instructions */ + temp = GPR[reg]; /* reg contents specified by Rd */ + addr = GPR[sreg]; /* reg contents specified by Rs */ + bc = 0; + + switch(opr & 0xF) { + case 0x0: /* TRR */ /* SCC|SD|R1 */ + temp = addr; /* set value to go to GPR[reg] */ + bc = 1; /* set CC's at end */ + break; + + case 0x1: /* TRBR */ /* Transfer GPR to BR */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + BR[reg] = GPR[sreg]; /* copy GPR to BR */ + break; + + case 0x2: /* TBRR */ /* transfer BR to GPR */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + temp = BR[sreg]; /* set base reg value */ + bc = 1; /* set CC's at end */ + break; + + case 0x3: /* TRC */ /* Transfer register complement */ + temp = addr ^ FMASK; /* complement Rs */ + bc = 1; /* set CC's at end */ + break; + + case 0x4: /* TRN */ /* Transfer register negative */ + temp = NEGATE32(addr); /* negate Rs value */ + if (temp == addr) /* overflow if nothing changed */ + ovr = 1; /* set overflow flag */ + /* reset ovr if val == 0, not set for DIAGS */ + if ((temp == 0) & ovr) + ovr = 0; + bc = 1; /* set the CC's */ + break; + + case 0x5: /* XCR */ /* exchange registers Rd & Rs */ + GPR[sreg] = temp; /* Rd to Rs */ + set_CCs(temp, ovr); /* set the CC's from original Rd */ + temp = addr; /* save the Rs value to Rd reg */ + break; + + case 0x6: /* INV */ + goto inv; + break; + + case 0x7: /* LMAP */ /* Load map reg - Diags only */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* handle trap */ + } + /* cpu must be unmapped */ + if (MODES & MAPMODE) { /* must be unmapped cpu */ + TRAPME = MAPFAULT_TRAP; /* Map Fault Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT8; /* set bit 8 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* handle trap */ + } + { /* load the cpu maps using diag psd */ + uint32 DPSD[2]; /* the PC for the instruction */ + /* get PSD pointed to by real addr in Rd (temp) */ + DPSD[0] = RMW(temp); /* get word one of psd */ + DPSD[1] = RMW(temp+4); /* get word two of psd */ + sim_debug(DEBUG_CMD, &cpu_dev, + "LMAP PSD %08x %08x DPSD %08x %08x modes %08x temp %06x\n", + PSD1, PSD2, DPSD[0], DPSD[1], MODES, temp); + if ((DPSD[1] & MAPBIT) == 0) /* if PSD2 is unmapped, treat as NOP */ + goto skipit; + if (PSD2 & RETMBIT) /* don't load maps if retain bit set */ + goto skipit; + temp2 = MODES; /* save modes bits through load_maps call */ + MODES = DPSD[0] & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ + MODES |= MAPMODE; /* set mapped mode flag for load_maps call */ + sim_debug(DEBUG_CMD, &cpu_dev, + "LMAP PSD %08x %08x DPSD %08x %08x modes %08x temp2 %08x\n", + PSD1, PSD2, DPSD[0], DPSD[1], MODES, temp2); + /* we need to load the new maps */ + TRAPME = load_maps(DPSD, 1); /* load maps for new PSD */ + sim_debug(DEBUG_CMD, &cpu_dev, + "LMAP TRAPME %08x MAPC[8-c] %08x %08x %08x %08x %08x %08x\n", + TRAPME, MAPC[7], MAPC[8], MAPC[9], MAPC[10], MAPC[11], MAPC[12]); + MODES = temp2; /* restore modes flags */ + if (TRAPME) { + /* DIAGS wants the cpix for the psd to be the requested one */ + PSD2 = (PSD2 & 0xffffc000) | (DPSD[1] & 0x3ff8); + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + goto newpsd; /* handle trap */ + } + goto skipit; + break; + } + break; + + case 0x8: /* TRRM */ /* SCC|SD|R1 */ + temp = addr & GPR[4]; /* transfer reg-reg masked */ + bc = 1; /* set CC's at end */ + break; + + /* CPUSTATUS bits */ + /* Bits 0-19 reserved */ + /* Bit 20 =0 Write to writable control store is disabled */ + /* =1 Write to writable control store is enabled */ + /* Bit 21 =0 Enable PROM mode */ + /* =1 Enable Alterable Control Store Mode */ + /* Bit 22 =0 Enable High Speed Floating Point Accelerator */ + /* =1 Disable High Speed Floating Point Accelerator */ + /* Bit 23 =0 Disable privileged mode halt trap */ + /* =1 Enable privileged mode halt trap */ + /* Bit 24 is reserved */ + /* bit 25 =0 Disable software trap handling (enable automatic trap handling) */ + /* =1 Enable software trap handling */ + /* Bits 26-31 reserved */ + case 0x9: /* SETCPU */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* handle trap */ + } + temp2 = CPUSTATUS; /* save original */ + /* bits 20-23 and bit 25 can change */ + CPUSTATUS &= 0xfffff0bf; /* zero bits that can change */ + CPUSTATUS |= (temp & 0x0f40); /* or in the new status bits */ + CPUSTATUS |= BIT22; /* HS Floating is set to off */ + /* make sure WCS is off and prom mode set to 0 (on) */ + CPUSTATUS &= ~(BIT20|BIT21); /* make zero */ + sim_debug(DEBUG_CMD, &cpu_dev, + "SETCPU orig %08x user bits %08x New CPUSTATUS %08x SPAD[f9] %08x\n", + temp2, temp, CPUSTATUS, SPAD[0xf9]); + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + break; + + case 0xA: /* TMAPR */ /* Transfer map to Reg - Diags only */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* handle trap */ + } + if (CPU_MODEL <= MODEL_27) { /* 7X & 27 must be unmapped */ + if (MODES & MAPMODE) { /* must be unmapped cpu */ + TRAPME = MAPFAULT_TRAP; /* Map Fault Trap */ + goto newpsd; /* handle trap */ + } + } + /* Rs has map number for even/odd pair loading */ + if (CPU_MODEL < MODEL_27) { + /* 32/77 with 32 map regs */ + addr &= 0x1e; /* make 0-15 */ + temp = MAPC[addr>>1]; /* get even/odd maps */ + } else + if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_87)) { + /* 32/27 & 32/87 have 256 maps */ + addr &= 0xfe; /* make 0-255 */ + temp = MAPC[addr>>1]; /* get even/odd maps */ + } else { + /* 32/67, 32/97, V6 & V9 have 2048 maps demand paging */ + addr &= 0x7ff; /* make 0-2047 */ + temp = MAPC[addr>>1]; /* get even/odd maps */ + if ((addr & 1) == 0) /* if even reg, use left hw */ + temp >>= 16; /* move over reg value */ + temp &= 0xffff; /* just 16 bits */ + if (TLB[addr] & 0x04000000) /* see if HIT bit set */ + temp |= 0x80000000; /* show hit BIT is set */ + temp |= ((TLB[addr] & 0xf8000000) >> 16); /* add in protect bits */ + if ((addr < 0x26) || (addr > 0x7f8)) + sim_debug(DEBUG_CMD, &cpu_dev, + "TMAPR #%4x val %08x TLB %08x RMR %04x MAPC %08x\n", + addr, temp, TLB[addr], RMR(addr<<1), MAPC[addr/2]); + } + GPR[reg] = temp; /* save the temp value to Rd reg */ + goto skipit; + break; + + case 0xB: /* TRCM */ /* Transfer register complemented masked */ + temp = (addr ^ FMASK) & GPR[4]; /* compliment & mask */ + bc = 1; /* set the CC's */ + break; + + case 0xC: /* TRNM */ /* Transfer register negative masked */ + temp = NEGATE32(addr); /* complement GPR[reg] */ + if (temp == addr) /* check for overflow */ + ovr = 1; /* overflow */ + /* reset ovr if val == 0, not set for DIAGS */ + if ((temp == 0) & ovr) + ovr = 0; + temp &= GPR[4]; /* and with negative reg */ + bc = 1; /* set the CC's */ + break; + + case 0xD: /* XCRM */ /* Exchange registers masked */ + addr &= GPR[4]; /* and Rs with mask reg */ + temp &= GPR[4]; /* and Rd with mask reg */ + GPR[sreg] = temp; /* Rs to get Rd masked value */ + set_CCs(temp, ovr); /* set the CC's from original Rd */ + temp = addr; /* save the Rs value to Rd reg */ + break; + + case 0xE: /* TRSC */ /* transfer reg to SPAD */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* handle trap */ + } + t = (GPR[reg] >> 16) & 0xff; /* get SPAD address from Rd (6-8) */ + temp2 = SPAD[t]; /* get old SPAD data */ + SPAD[t] = GPR[sreg]; /* store Rs into SPAD */ + break; + + case 0xF: /* TSCR */ /* Transfer scratchpad to register */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* handle trap */ + } + t = (GPR[sreg] >> 16) & 0xff; /* get SPAD address from Rs (9-11) */ + temp = SPAD[t]; /* get SPAD data into Rd (6-8) */ + break; + } + GPR[reg] = temp; /* save the temp value to Rd reg */ + if (bc) /* set cc's if bc set */ + set_CCs(temp, ovr); /* set the CC's */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* handle trap */ + } +skipit: + /* for retain, leave PSD2 alone */ + break; + + case 0x30>>2: /* 0x30 */ /* CALM */ + /* Process CALM for 32/27 when in left hw, else invalid */ + if ((CPU_MODEL <= MODEL_87) && (CPU_MODEL != MODEL_67)) { + uint32 oldstatus = CPUSTATUS; /* keep for retain blocking state */ + /* DIAG error for 32/27 or 32/87 only */ + if ((PSD1 & 2) != 0) /* is it lf hw instruction */ + goto inv; /* invalid instr if in rt hw */ + addr = SPAD[0xf0]; /* get trap table memory address from SPAD (def 80) */ + if ((addr == 0) || ((addr&MASK24) == MASK24)) { /* see if secondary vector table set up */ + TRAPME = ADDRSPEC_TRAP; /* Not setup, error */ + goto newpsd; /* program error */ + } + addr = addr + (0x0A << 2); /* addr has mem addr of CALM trap vector (def A8) */ + t = M[addr >> 2]; /* get the ICB address from memory */ + if ((t == 0) || ((t&MASK24) == MASK24)) { /* see if ICB set up */ + TRAPME = ADDRSPEC_TRAP; /* Not setup, error */ + goto newpsd; /* program error */ + } + bc = PSD2 & 0x3ff8; /* get copy of cpix */ + /* this will skip over rt hw instruction if any */ + PSD1 = (PSD1 + 4) | (((PSD1 & 2) >> 1) & 1); /* bump pc by 1 wd */ + M[t>>2] = PSD1 & 0xfffffffe; /* store PSD 1 + 1HW to point to next instruction */ + M[(t>>2)+1] = PSD2; /* store PSD 2 */ + PSD1 = M[(t>>2)+2]; /* get new PSD 1 */ + PSD2 = (M[(t>>2)+3] & ~0x3fff) | bc; /* get new PSD 2 w/old cpix */ + M[(t>>2)+4] = opr & 0x03FF; /* store calm number in bits 6-15 */ + + /* set the mode bits and CCs from the new PSD */ + CC = PSD1 & 0x78000000; /* extract bits 1-4 from PSD1 */ + MODES = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ + CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */ + CPUSTATUS |= MODES; /* now insert into CPUSTATUS */ + + /* set new map mode and interrupt blocking state in CPUSTATUS */ + if (PSD2 & MAPBIT) { + CPUSTATUS |= BIT8; /* set bit 8 of cpu status */ + MODES |= MAPMODE; /* set mapped mode */ + } else { + CPUSTATUS &= ~BIT8; /* reset bit 8 of cpu status */ +/*TRY_01072022*/ MODES &= ~MAPMODE; /* reset mapped mode */ + } + + /* set interrupt blocking state */ + if ((PSD2 & RETBBIT) == 0) { /* is it retain blocking state */ + if (PSD2 & SETBBIT) { /* no, is it set blocking state */ + CPUSTATUS |= BIT24; /* yes, set blk state in cpu status bit 24 */ + MODES |= BLKMODE; /* set blocked mode */ + } else { + CPUSTATUS &= ~BIT24; /* no, reset blk state in cpu status bit 24 */ + MODES &= ~BLKMODE; /* reset blocked mode */ + irq_pend = 1; /* start scanning interrupts again */ +#ifdef LEAVE_ACTIVE + if (irq_auto) { +/*AIR*/ INTS[irq_auto] &= ~INTS_ACT; /* deactivate specified int level */ +/*AIR*/ SPAD[irq_auto+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>IntX deactivate level %02x at CALM PSD1 %08x\n", + irq_auto, PSD1); +/*AIR*/ irq_auto = 0; /* show done processing in blocked mode */ + } +#endif + } + } else { + /* handle retain blocking state */ + PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ + /* set new blocking state in PSD2 */ + PSD2 &= ~(SETBBIT|RETBBIT); /* clear bit 48 & 49 to be unblocked */ + MODES &= ~(BLKMODE|RETBLKM); /* reset blocked & retain mode bits */ + if (oldstatus & BIT24) { /* see if old mode is blocked */ + PSD2 |= SETBBIT; /* set to blocked state */ + MODES |= BLKMODE; /* set blocked mode */ + } + } + + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + TRAPME = 0; /* not to be processed as trap */ + goto newpsd; /* new psd loaded */ + } else { +// fprintf(stderr, "got CALM trap\r\n"); + goto inv; /* invalid instr */ + } + break; + + case 0x34>>2: /* 0x34 SD|ADR - inv */ /* LA non-basemode */ + if (MODES & BASEBIT) /* see if based */ + goto inv; /* invalid instruction in based mode */ + if (MODES & EXTDBIT) { /* see if extended mode */ + dest = (t_uint64)(addr&MASK24); /* just pure 24 bit address */ + } else { /* use bits 13-31 */ + dest = (t_uint64)((addr&0x7ffff) | ((FC & 4) << 17)); /* F bit to bit 12 */ + } + break; + + case 0x38>>2: /* 0x38 HLF - HLF */ /* REG - REG floating point */ + switch(opr & 0xF) { + case 0x0: /* ADR */ + temp = GPR[reg]; /* reg contents specified by Rd */ + addr = GPR[sreg]; /* reg contents specified by Rs */ + t = (temp & FSIGN) != 0; /* set flag for sign bit not set in temp value */ + t |= ((addr & FSIGN) != 0) ? 2 : 0; /* ditto for the reg value */ + temp = temp + addr; /* add the values */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if ((t == 3 && (temp & FSIGN) == 0) || (t == 0 && (temp & FSIGN) != 0)) { + ovr = 1; /* we have an overflow */ + } + i_flags |= SF; /* special processing */ + break; + + case 0x1: /* ADRFW */ + case 0x3: /* SURFW */ + /* TODO not on 32/27 */ + temp = GPR[reg]; /* reg contents specified by Rd */ + addr = GPR[sreg]; /* reg contents specified by Rs */ + /* temp has Rd (GPR[reg]), addr has Rs (GPR[sreg]) */ + if ((opr & 0xF) == 0x3) { + addr = NEGATE32(addr); /* subtract, so negate source */ + } + temp2 = s_adfw(temp, addr, &CC); /* do ADFW */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "%s GPR[%d] %08x addr %08x result %08x CC %08x\n", + (opr&0xf)==3 ? "SURFW":"ADRFW", + reg, GPR[reg], GPR[sreg], temp2, CC); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + if (CC & CC1BIT) { /* check for arithmetic exception */ + ovr = 1; /* exception */ + /* leave Rd & Rs unchanged if AEXPBIT is set */ + if (MODES & AEXPBIT) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + } + /* AEXPBIT not set, so save the fixed return value */ + /* return result to destination reg */ + GPR[reg] = temp2; /* dest - reg contents specified by Rd */ + break; + + case 0x2: /* MPRBR */ + /* TODO not on 32/27 */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + if (reg & 1) { + /* Spec fault if not even reg */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + temp = GPR[reg+1]; /* get multiplicand */ + addr = GPR[sreg]; /* multiplier */ + + /* change value into a 64 bit value */ + dest = ((t_uint64)(addr & FMASK)) | ((addr & FSIGN) ? D32LMASK : 0); + source = ((t_uint64)(temp & FMASK)) | ((temp & FSIGN) ? D32LMASK : 0); + dest = dest * source; /* do the multiply */ + i_flags |= (SD|SCC); /* save dest reg and set CC's */ + dbl = 1; /* double reg save */ + break; + + case 0x4: /* DVRFW */ + /* TODO not on 32/27 */ + temp = GPR[reg]; /* reg contents specified by Rd */ + addr = GPR[sreg]; /* reg contents specified by Rs */ + /* temp has Rd (GPR[reg]), addr has Rs (GPR[sreg]) */ + temp2 = (uint32)s_dvfw(temp, addr, &CC); /* divide reg by sreg */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "DVRFW GPR[%d] %08x src %08x result %08x\n", + reg, GPR[reg], addr, temp2); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + if (CC & CC1BIT) { /* check for arithmetic exception */ + ovr = 1; /* exception */ + /* leave Rd & Rs unchanged if AEXPBIT is set */ + if (MODES & AEXPBIT) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + } + /* AEXPBIT not set, so save the fixed return value */ + /* return result to destination reg */ + GPR[reg] = temp2; /* dest - reg contents specified by Rd */ + break; + + case 0x5: /* FIXW */ + /* TODO not on 32/27 */ + /* convert from 32 bit float to 32 bit fixed */ + addr = GPR[sreg]; /* reg contents specified by Rs */ + temp2 = s_fixw(addr, &CC); /* do conversion */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "FIXW GPR[%d] %08x result %08x\n", + sreg, GPR[sreg], temp2); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + if (CC & CC1BIT) { /* check for arithmetic exception */ + ovr = 1; /* exception */ + /* leave Rd & Rs unchanged if AEXPBIT is set */ + if (MODES & AEXPBIT) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + } + /* AEXPBIT not set, so save the fixed return value */ + /* return result to destination reg */ + GPR[reg] = temp2; /* dest - reg contents specified by Rd */ + break; /* go set CC's */ + + case 0x6: /* MPRFW */ + /* TODO not on 32/27 */ + temp = GPR[reg]; /* reg contents specified by Rd */ + addr = GPR[sreg]; /* reg contents specified by Rs */ + /* temp has Rd (GPR[reg]), addr has Rs (GPR[sreg]) */ + temp2 = s_mpfw(temp, addr, &CC); /* mult reg by sreg */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "MPRFW GPR[%d] %08x src %08x result %08x\n", + reg, GPR[reg], addr, temp2); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + if (CC & CC1BIT) { /* check for arithmetic exception */ + ovr = 1; /* exception */ + /* leave Rd & Rs unchanged if AEXPBIT is set */ + if (MODES & AEXPBIT) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + } + /* AEXPBIT not set, so save the fixed return value */ + /* return result to destination reg */ + GPR[reg] = temp2; /* dest - reg contents specified by Rd */ + break; + + case 0x7: /* FLTW */ + /* TODO not on 32/27 */ + /* convert from 32 bit integer to 32 bit float */ + addr = GPR[sreg]; /* reg contents specified by Rs */ + GPR[reg] = s_fltw(addr, &CC); /* do conversion & set CC's */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "FLTW GPR[%d] %08x result %08x\n", + sreg, GPR[sreg], GPR[reg]); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + break; + + case 0x8: /* ADRM */ + temp = GPR[reg]; /* reg contents specified by Rd */ + addr = GPR[sreg]; /* reg contents specified by Rs */ + t = (temp & FSIGN) != 0; /* set flag for sign bit not set in temp value */ + t |= ((addr & FSIGN) != 0) ? 2 : 0; /* ditto for the reg value */ + temp = temp + addr; /* add the values */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if ((t == 3 && (temp & FSIGN) == 0) || + (t == 0 && (temp & FSIGN) != 0)) + ovr = 1; /* we have an overflow */ + temp &= GPR[4]; /* mask the destination reg */ + i_flags |= SF; /* special processing */ + break; + + case 0x9: /* ADRFD */ + case 0xB: /* SURFD */ + /* TODO not on 32/27 */ + if ((reg & 1) || (sreg & 1)) { /* see if any odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + td = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */ + td |= (t_uint64)GPR[reg+1]; /* insert low order reg value */ + source = (((t_uint64)GPR[sreg]) << 32); /* get upper reg value */ + source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */ + if ((opr & 0xF) == 0xb) { + source = NEGATE32(source); /* make negative for subtract */ + } + dest = s_adfd(td, source, &CC); /* do ADFD */ + + sim_debug(DEBUG_DETAIL, &cpu_dev, + "%s GPR[%d] %08x %08x src %016llx result %016llx\n", + (opr&0xf)==8 ? "ADRFD":"SURFD", reg, GPR[reg], GPR[reg+1], source, dest); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + if (CC & CC1BIT) { /* check for arithmetic exception */ + ovr = 1; /* exception */ + /* leave Rd & Rs unchanged if AEXPBIT is set */ + if (MODES & AEXPBIT) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + } + /* AEXPBIT not set, so save the fixed return value */ + /* return result to destination reg */ + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + break; + + case 0xA: /* DVRBR */ + /* TODO not on 32/27 */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + if (reg & 1) { + /* Spec fault if not even reg */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + /* get Rs divisor value */ + source = (t_uint64)(GPR[sreg]) | ((GPR[sreg] & FSIGN) ? D32LMASK : 0); + /* merge the dividend regs into the 64bit value */ + dest = (((t_uint64)GPR[reg]) << 32) | ((t_uint64)GPR[reg+1]); + if (source == 0) { + goto doovr4; + break; + } + td = (t_int64)dest % (t_int64)source; /* remainder */ + if (((td & DMSIGN) ^ (dest & DMSIGN)) != 0) /* Fix sign if needed */ + td = NEGATE32(td); /* dividend and remainder must be same sign */ + dest = (t_int64)dest / (t_int64)source; /* now do the divide */ + /* test for overflow */ + if ((dest & D32LMASK) != 0 && (dest & D32LMASK) != D32LMASK) { +doovr4: + ovr = 1; /* the quotient exceeds 31 bit, overflow */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + } + /* the original regs must be returned unchanged if aexp */ + set_CCs(temp, ovr); /* set the CC's */ + } else { + GPR[reg] = (uint32)(td & FMASK); /* reg gets remainder, reg+1 quotient */ + GPR[reg+1] = (uint32)(dest & FMASK); /* store quotient in reg+1 */ + set_CCs(GPR[reg+1], ovr); /* set the CC's, CC1 = ovr */ + } + break; + + case 0xC: /* DVRFD */ + /* TODO not on 32/27 */ + if ((reg & 1) || (sreg & 1)) { /* see if any odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + td = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */ + td |= (t_uint64)GPR[reg+1]; /* insert low order reg value */ + source = (((t_uint64)GPR[sreg]) << 32); /* get upper reg value */ + source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */ + dest = s_dvfd(td, source, &CC); /* divide double values */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "DVRFD GPR[%d] %08x %08x src %016llx result %016llx\n", + reg, GPR[reg], GPR[reg+1], source, dest); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + if (CC & CC1BIT) { /* check for arithmetic exception */ + ovr = 1; /* exception */ + /* leave Rd & Rs unchanged if AEXPBIT is set */ + if (MODES & AEXPBIT) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + } + /* AEXPBIT not set, so save the fixed return value */ + /* return result to destination reg */ + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + break; + + case 0xD: /* FIXD */ + /* dest - reg contents specified by Rd & Rd+1 */ + /* source - reg contents specified by Rs & Rs+1 */ + if (sreg & 1) { + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + goto newpsd; /* go execute the trap now */ + } + /* merge the sregs into the 64bit value */ + source = (((t_uint64)GPR[sreg]) << 32) | ((t_uint64)GPR[sreg+1]); + /* convert from 64 bit double to 64 bit int */ + dest = s_fixd(source, &CC); + sim_debug(DEBUG_DETAIL, &cpu_dev, + "FIXD GPR[%d] %08x %08x result %016llx\n", + sreg, GPR[sreg], GPR[sreg+1], dest); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + if (CC & CC1BIT) { /* check for arithmetic exception */ + ovr = 1; /* exception */ + /* leave Rd & Rs unchanged if AEXPBIT is set */ + if (MODES & AEXPBIT) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + } + /* AEXPBIT not set, so save the fixed return value */ + /* return result to destination reg */ + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + break; + + case 0xE: /* MPRFD */ + /* TODO not on 32/27 */ + if ((reg & 1) || (sreg & 1)) { /* see if any odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + td = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */ + td |= (t_uint64)GPR[reg+1]; /* insert low order reg value */ + source = (((t_uint64)GPR[sreg]) << 32); /* get upper reg value */ + source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */ + dest = s_mpfd(td, source, &CC); /* multiply double values */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "MPRFD GPR[%d] %08x %08x src %016llx result %016llx\n", + reg, GPR[reg], GPR[reg+1], source, dest); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + if (CC & CC1BIT) { /* check for arithmetic exception */ + ovr = 1; /* exception */ + /* leave Rd & Rs unchanged if AEXPBIT is set */ + if (MODES & AEXPBIT) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + } + /* AEXPBIT not set, so save the fixed return value */ + /* return result to destination reg */ + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + break; + + case 0xF: /* FLTD */ + /* TODO not on 32/27 */ + /* convert from 64 bit integer to 64 bit float */ + if ((reg & 1) || (sreg & 1)) { /* see if any odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + source = (((t_uint64)GPR[sreg]) << 32); /* get upper reg value */ + source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */ + dest = s_fltd(source, &CC); /* do conversion & set CC's */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "FLTD GPR[%d] %08x %08x result %016llx\n", + sreg, GPR[sreg], GPR[sreg+1], dest); + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + break; + } + if (i_flags & SF) { /* see if special processing */ + GPR[reg] = temp; /* temp has destination reg value */ + set_CCs(temp, ovr); /* set the CC's */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* go execute the trap now */ + } + } + break; + + case 0x3C>>2: /* 0x3C HLF - HLF */ /* SUR and SURM */ + temp = GPR[reg]; /* get negative value to add */ + temp2 = GPR[sreg]; /* get negative value to add */ + addr = NEGATE32(GPR[sreg]); /* reg contents specified by Rs */ + switch(opr & 0xF) { + case 0x0: /* SUR */ + t = (temp & FSIGN) != 0; /* set flag for sign bit not set in temp value */ + t |= ((addr & FSIGN) != 0) ? 2 : 0; /* ditto for the reg value */ + temp = temp + addr; /* add the values */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if ((t == 3 && (temp & FSIGN) == 0) || + (t == 0 && (temp & FSIGN) != 0)) + ovr = 1; /* we have an overflow */ + if (addr == FSIGN) + ovr = 1; /* we have an overflow */ + break; + + case 0x8: /* SURM */ + t = (temp & FSIGN) != 0; /* set flag for sign bit not set in temp value */ + t |= ((addr & FSIGN) != 0) ? 2 : 0; /* ditto for the reg value */ + temp = temp + addr; /* add the values */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if ((t == 3 && (temp & FSIGN) == 0) || + (t == 0 && (temp & FSIGN) != 0)) + ovr = 1; /* we have an overflow */ + temp &= GPR[4]; /* mask the destination reg */ + if (addr == FSIGN) + ovr = 1; /* we have an overflow */ + break; + default: + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + break; + } + GPR[reg] = temp; /* save the result */ + set_CCs(temp, ovr); /* set CCs for result */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* go execute the trap now */ + } + break; + + case 0x40>>2: /* 0x40 SCC|SD|HLF - INV */ /* MPR */ + if (MODES & BASEBIT) + goto inv; /* invalid instruction in basemode */ + if (reg & 1) { /* odd reg specified? */ + /* Spec fault */ + /* HACK HACK HACK for DIAGS */ + if (CPU_MODEL <= MODEL_27) { /* DIAG error for 32/27 only */ + if ((PSD1 & 2) == 0) /* if lf hw instruction */ + i_flags &= ~HLF; /* if nop in rt hw, bump pc a word */ + else + PSD1 &= ~3; /* fake out 32/27 diag error */ + } + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if (opr & 0xf) { /* any subop not zero is error */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + temp = GPR[reg+1]; /* get multiplicand */ + addr = GPR[sreg]; /* multiplier */ + + /* change immediate value into a 64 bit value */ + dest = ((t_uint64)(addr & FMASK)) | ((addr & FSIGN) ? D32LMASK : 0); + source = ((t_uint64)(temp & FMASK)) | ((temp & FSIGN) ? D32LMASK : 0); + dest = dest * source; /* do the multiply */ + dbl = 1; /* double reg save */ + break; + + case 0x44>>2: /* 0x44 ADR - ADR */ /* DVR */ + /* sreg has Rs */ + if (reg & 1) { + /* Spec fault */ + /* HACK HACK HACK for DIAGS */ + if (CPU_MODEL <= MODEL_27) { /* DIAG error for 32/27 only */ + if ((PSD1 & 2) == 0) /* if lf hw instruction */ + i_flags &= ~HLF; /* if nop in rt hw, bump pc a word */ + else + PSD1 &= ~3; /* fake out 32/27 diag error */ + } + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if (opr & 0xf) { /* any subop not zero is error */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + goto newpsd; /* handle trap */ + } + /* get Rs divisor value */ + source = (t_uint64)(GPR[sreg]) | ((GPR[sreg] & FSIGN) ? D32LMASK : 0); + /* merge the dividend regs into the 64bit value */ + dest = (((t_uint64)GPR[reg]) << 32) | ((t_uint64)GPR[reg+1]); + if (source == 0) + goto doovr3; + td = (t_int64)dest % (t_int64)source; /* remainder */ + if (((td & DMSIGN) ^ (dest & DMSIGN)) != 0) /* Fix sign if needed */ + td = NEGATE32(td); /* dividend and remainder must be same sign */ + dest = (t_int64)dest / (t_int64)source; /* now do the divide */ + int64a = dest; + if (int64a < 0) + int64a = -int64a; + if (int64a > 0x7fffffff) /* if more than 31 bits, we have an error */ + goto doovr3; + if (((dest & D32LMASK) != 0 && (dest & D32LMASK) != D32LMASK) || + (((dest & D32LMASK) == D32LMASK) && ((dest & D32RMASK) == 0))) { /* test for overflow */ +doovr3: + dest = (((t_uint64)GPR[reg]) << 32);/* insert upper reg value */ + dest |= (t_uint64)GPR[reg+1]; /* get low order reg value */ + ovr = 1; /* the quotient exceeds 31 bit, overflow */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + } + /* the original regs must be returned unchanged if aexp */ + CC = CC1BIT; /* set ovr CC bit */ + if (dest == 0) + CC |= CC4BIT; /* dw is zero, so CC4 */ + else + if (dest & DMSIGN) + CC |= CC3BIT; /* it is neg dw, so CC3 */ + else + CC |= CC2BIT; /* then dest > 0, so CC2 */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + PSD1 |= CC; /* update the CC's in the PSD */ + } else { + GPR[reg] = (uint32)(td & FMASK); /* reg gets remainder, reg+1 quotient */ + GPR[reg+1] = (uint32)(dest & FMASK); /* store quotient in reg+1 */ + set_CCs(GPR[reg+1], ovr); /* set the CC's, CC1 = ovr */ + } + break; + + case 0x48>>2: /* 0x48 INV - INV */ /* unused opcodes */ + case 0x4C>>2: /* 0x4C INV - INV */ /* unused opcodes */ + default: + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + break; + + case 0x50>>2: /* 0x50 INV - SD|ADR */ /* LA basemode LABRM */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + dest = (t_uint64)(addr&MASK24); /* just pure 24 bit address */ + break; + + case 0x54>>2: /* 0x54 SM|ADR - INV */ /* (basemode STWBR) */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + if (FC != 0) { /* word address only */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC8 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + dest = BR[reg]; /* save the BR to memory */ + break; + + case 0x58>>2: /* 0x58 SB|ADR - INV */ /* (basemode SUABR and LABR) */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + if ((FC & 4) == 0) { /* see if SUABR F=0 0x5800 */ + dest = BR[reg] - addr; /* subtract addr from the BR and store back to BR */ + } else { /* LABR if F=1 0x5808 */ + dest = addr; /* addr goes to specified BR */ + } + break; + + case 0x5C>>2: /* 0x5C RM|ADR - INV */ /* (basemode LWBR and BSUBM) */ + if ((MODES & BASEBIT) == 0) /* see if nonbased */ + goto inv; /* invalid instruction in nonbased mode */ + if ((FC & 3) != 0) { /* word address only */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC9 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + if ((FC & 0x4) == 0) { /* this is a LWBR 0x5C00 instruction */ + BR[reg] = (uint32)source; /* load memory location into BR */ + } else + { /* this is a CALLM/BSUBM instruction */ + /* if Rd field is 0 (reg is b6-8), this is a BSUBM instruction */ + /* otherwise it is a CALLM instruction (Rd != 0) */ + if (reg == 0) { + /* BSUBM instruction */ + uint32 cfp = BR[2]; /* get dword bounded frame pointer from BR2 */ + + if ((BR[2] & 0x7) != 0) { + /* Fault, must be dw bounded address */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + goto newpsd; /* go execute the trap now */ + } + + temp = (PSD1+4) & 0x01fffffe; /* save AEXP bit and PC from PSD1 into frame */ + if ((TRAPME = Mem_write(cfp, &temp))) { /* Save the PSD into memory */ + goto newpsd; /* memory write error or map fault */ + } + + temp = 0x80000000; /* show frame created by BSUBM instr */ + if ((TRAPME = Mem_write(cfp+4, &temp))) { /* Save zero into memory */ + goto newpsd; /* memory write error or map fault */ + } + + temp = addr & 0xfffffe; /* CALL memory address */ + if ((temp & 0x3) != 0) { /* check for word aligned */ + /* Fault, must be word bounded address */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + goto newpsd; /* go execute the trap now */ + } + + if ((TRAPME = Mem_read(temp, &addr))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + + BR[1] = addr; /* effective address contents to BR 1 */ + /* keep bits 0-7 from old PSD */ + PSD1 = ((PSD1 & 0xff000000) | (BR[1] & 0x01fffffe)); /* New PSD address */ + BR[3] = GPR[0]; /* GPR[0] to BR[3] (AP) */ + BR[0] = cfp; /* set current frame pointer into BR[0] */ + i_flags |= BT; /* we changed the PC, so no PC update */ + } else { + /* CALLM instruction */ + + /* get frame pointer from BR2 - 16 words & make it a dword addr */ + uint32 cfp = ((BR[2]-0x40) & 0x00fffff8); + + /* if cfp and cfp+15w are in different maps, then addr exception error */ + if ((cfp & 0xffe000) != ((cfp+0x3f) & 0xffe000)) { + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + + temp = (PSD1+4) & 0x01fffffe; /* save AEXP bit and PC from PSD1 in to frame */ + if ((TRAPME = Mem_write(cfp, &temp))) { /* Save the PSD into memory */ + goto newpsd; /* memory write error or map fault */ + } + + temp = 0x00000000; /* show frame created by CALL instr */ + if ((TRAPME = Mem_write(cfp+4, &temp))) { /* Save zero into memory */ + goto newpsd; /* memory write error or map fault */ + } + + /* save the BRs 0-7 on stack */ + for (ix=0; ix<8; ix++) { + if ((TRAPME = Mem_write(cfp+(4*ix)+8, &BR[ix]))) { /* Save into memory */ + goto newpsd; /* memory write error or map fault */ + } + } + + /* save GPRs 2-7 on stack */ + for (ix=2; ix<8; ix++) { + if ((TRAPME = Mem_write(cfp+(4*ix)+32, &GPR[ix]))) { /* Save into memory */ + goto newpsd; /* memory write error or map fault */ + } + } + + temp = addr & 0xfffffe; /* CALL memory address */ + if ((temp & 0x3) != 0) { /* check for word aligned */ + /* Fault, must be word bounded address */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + goto newpsd; /* go execute the trap now */ + } + + if ((TRAPME = Mem_read(temp, &addr))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + + BR[1] = addr; /* effective address contents to BR 1 */ + /* keep bits 0-6 from old PSD */ + PSD1 = (PSD1 & 0xff000000) | ((BR[1]) & 0x01fffffe); /* New PSD address */ + BR[3] = GPR[reg]; /* Rd to BR 3 (AP) */ + BR[0] = cfp; /* set current frame pointer into BR[0] */ + BR[2] = cfp; /* set current frame pointer into BR[2] */ + i_flags |= BT; /* we changed the PC, so no PC update */ + } + } + break; + + case 0x60>>2: /* 0x60 HLF - INV */ /* NOR Rd,Rs */ + if ((MODES & BASEBIT)) { /* only for nonbased mode */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + if (opr & 0xf) { /* any subop not zero is error */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + /* exponent must not be zero or all 1's */ + /* normalize the value Rd in GPR[reg] and put exponent into Rs GPR[sreg] */ + temp = s_nor(GPR[reg], &GPR[sreg]); + sim_debug(DEBUG_DETAIL, &cpu_dev, + "NOR GPR[%d] %08x result %08x exp %02x\n", + reg, GPR[reg], temp, GPR[sreg]); + GPR[reg] = temp; + break; + + case 0x64>>2: /* 0x64 SD|HLF - INV */ /* NORD */ + if ((MODES & BASEBIT)) { /* only for nonbased mode */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if (opr & 0xf) { /* any subop not zero is error */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + /* shift until upper 5 bits are neither 0 or all 1's */ + /* merge the GPR[reg] & GPR[reg+1] into a 64bit value */ + td = (((t_uint64)GPR[reg]) << 32) | ((t_uint64)GPR[reg+1]); + /* normalize the value Rd in GPR[reg] and put exponent into Rs GPR[sreg] */ + dest = s_nord(td, &GPR[sreg]); + sim_debug(DEBUG_DETAIL, &cpu_dev, + "NORD GPR[%d] %08x %08x result %016llx exp %02x\n", + reg, GPR[reg], GPR[reg+1], dest, GPR[sreg]); + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + break; + + case 0x68>>2: /* 0x68 HLF - INV */ /* non basemode SCZ */ + if (MODES & BASEBIT) + goto inv; /* invalid instruction */ + if (opr & 0xf) { /* any subop not zero is error */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + goto sacz; /* use basemode sacz instruction */ + + case 0x6C>>2: /* 0x6C HLF - INV */ /* non basemode SRA & SLA */ + if (MODES & BASEBIT) + goto inv; /* invalid instruction */ + bc = opr & 0x1f; /* get bit shift count */ + temp = GPR[reg]; /* get reg value to shift */ + t = temp & FSIGN; /* sign value */ + if (opr & 0x0040) { /* is this SLA */ + ovr = 0; /* set ovr off */ + for (ix=0; ix>= 1; /* shift bit 0 right one bit */ + temp |= t; /* restore original sign bit */ + } + GPR[reg] = temp; /* save the new value */ + } + break; + + case 0x70>>2: /* 0x70 SD|HLF - INV */ /* non-basemode SRL & SLL */ + if (MODES & BASEBIT) + goto inv; /* invalid instruction in basemode */ + bc = opr & 0x1f; /* get bit shift count */ + if (opr & 0x0040) /* is this SLL, bit 9 set */ + GPR[reg] <<= bc; /* shift left #bits */ + else + GPR[reg] >>= bc; /* shift right #bits */ + break; + + case 0x74>>2: /* 0x74 SD|HLF - INV */ /* non-basemode SRC & SLC */ + if (MODES & BASEBIT) + goto inv; /* invalid instruction in basemode */ + bc = opr & 0x1f; /* get bit shift count */ + temp = GPR[reg]; /* get reg value to shift */ + if (opr & 0x0040) { /* is this SLC, bit 9 set */ + for (ix=0; ix>= 1; /* shift the bit out */ + if (t) + temp |= BIT0; /* put in new sign bit */ + } + } + GPR[reg] = temp; /* shift result */ + break; + + case 0x78>>2: /* 0x78 HLF - INV */ /* non-basemode SRAD & SLAD */ + if (MODES & BASEBIT) /* Base mode? */ + goto inv; /* invalid instruction in basemode */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + bc = opr & 0x1f; /* get bit shift count */ + dest = (t_uint64)GPR[reg+1]; /* get low order reg value */ + dest |= (((t_uint64)GPR[reg]) << 32); /* insert upper reg value */ + source = dest & DMSIGN; /* 64 bit sign value */ + if (opr & 0x0040) { /* is this SLAD */ + ovr = 0; /* set ovr off */ + for (ix=0; ix>32) & FMASK);/* save the hi order reg */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + if (ovr) + PSD1 |= BIT1; /* CC1 in PSD */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* go execute the trap now */ + } + } else { /* this is a SRAD */ + for (ix=0; ix>= 1; /* shift bit 0 right one bit */ + dest |= source; /* restore original sign bit */ + } + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + } + break; + + case 0x7C>>2: /* 0x7C HLF - INV */ /* non-basemode SRLD & SLLD */ + if (MODES & BASEBIT) + goto inv; /* invalid instruction in basemode */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + dest = (t_uint64)GPR[reg+1]; /* get low order reg value */ + dest |= (((t_uint64)GPR[reg]) << 32); /* insert upper reg value */ + bc = opr & 0x1f; /* get bit shift count */ + if (opr & 0x0040) /* is this SLL, bit 9 set */ + dest <<= bc; /* shift left #bits */ + else + dest >>= bc; /* shift right #bits */ + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + break; + + case 0x80>>2: /* 0x80 SD|ADR - SD|ADR */ /* LEAR */ + /* convert address to real physical address */ + TRAPME = RealAddr(addr, &temp, &t, MEM_RD); + // diag allows any addr if mapped + if (TRAPME != ALLOK) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "At LEAR with TRAPME %04x addr %08x\n", TRAPME, addr); + goto newpsd; /* memory read error or map fault */ + } + /* set access bit for mapped addresses */ + if ((CPU_MODEL >= MODEL_V6) && (MODES & MAPMODE)) { + uint32 map, mix, nix, msdl, mpl, mmap; + + nix = (addr >> 13) & 0x7ff; /* get 11 bit map value */ + /* check our access to the memory */ + switch (t & 0x0e) { + case 0x0: case 0x2: + /* O/S or user has no read/execute access, do protection violation */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "LEAR readI protect error @ %06x prot %02x modes %08x page %04x\n", + addr, t, MODES, nix); + if (CPU_MODEL == MODEL_V9) + TRAPSTATUS |= BIT1; /* set bit 1 of trap status */ + else + TRAPSTATUS |= BIT12; /* set bit 12 of trap status */ + return MPVIOL; /* return memory protection violation */ + case 0x4: case 0x6: case 0x8: case 0xc: case 0xa: case 0xe: + /* O/S or user has read/execute access, no protection violation */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "LEAR readJ protect is ok @ %06x prot %02x modes %08x page %04x\n", + addr, t, MODES, nix); + } + /* we have read access, so go set the access bit in the map entry */ + mpl = SPAD[0xf3]; /* get mpl from spad address */ + if (nix < BPIX) { + mix = nix; /* get map index in memory */ + msdl = RMW(mpl+4); /* get mpl entry for O/S */ + } else { + mix = nix-BPIX; /* get map index in memory */ + msdl = RMW(mpl+CPIX+4); /* get mpl entry for given CPIX */ + } + mmap = RMH(msdl+(mix<<1)); /* map content from memory */ + map = RMR((nix<<1)); /* read the map cache contents */ + if (((map & 0x800) == 0)) { /* see if access bit is already on */ + mmap |= 0x800; /* set the accessed bit in the map cache entry */ + map |= 0x800; /* set the accessed bit in the memory map entry */ + WMR((nix<<1), map); /* store the map reg contents into cache */ + TLB[nix] |= 0x0c000000; /* set the accessed & hit bits in TLB too */ + WMH(msdl+(mix<<1), mmap); /* save modified memory map with access bit set */ + sim_debug(DEBUG_EXP, &cpu_dev, + "LEAR Laddr %06x page %04x set access bit TLB %08x map %04x nmap %04x\n", + addr, nix, TLB[nix], map, mmap); + } + } + + /* OS code says F bit is not transferred, so just ignore it */ + /* DIAGS needs it, so put it back */ + if (FC & 4) /* see if F bit was set */ + temp |= 0x01000000; /* set bit 7 of address */ + dest = temp; /* put in dest to go out */ + break; + + case 0x84>>2: /* 0x84 SD|RR|RNX|ADR - SD|RNX|ADR */ /* ANMx */ + td = dest & source; /* DO ANMX */ + CC = 0; + switch(FC) { /* adjust for hw or bytes */ + case 4: case 5: case 6: case 7: /* byte address */ + /* ANMB */ + td &= 0xff; /* mask out right most byte */ + dest &= 0xffffff00; /* make place for byte */ + if (td == 0) + CC |= CC4BIT; /* byte is zero, so CC4 */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + break; + case 1: /* left halfword addr */ + case 3: /* right halfword addr */ + /* ANMH */ + td &= RMASK; /* mask out right most 16 bits */ + dest &= LMASK; /* make place for halfword */ + if (td == 0) + CC |= CC4BIT; /* hw is zero, so CC4 */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + break; + case 0: /* 32 bit word */ + /* ANMW */ + td &= D32RMASK; /* mask out right most 32 bits */ + dest = 0; /* make place for 64 bits */ + if (td == 0) + CC |= CC4BIT; /* word is zero, so CC4 */ + else + if (td & 0x80000000) + CC |= CC3BIT; /* it is neg wd, so CC3 */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + break; + case 2: /* 64 bit double */ + /* ANMD */ + dest = 0; /* make place for 64 bits */ + if (td == 0) + CC |= CC4BIT; /* dw is zero, so CC4 */ + else + if (td & DMSIGN) + CC |= CC3BIT; /* it is neg dw, so CC3 */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + break; + } + dest |= td; /* insert result into dest */ + if (FC != 2) { /* do not sign extend DW */ + if (dest & 0x80000000) /* see if we need to sign extend */ + dest |= D32LMASK; /* force upper word to all ones */ + } + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + PSD1 |= CC; /* update the CC's in the PSD */ + break; + + case 0x88>>2: /* 0x88 SD|RR|RNX|ADR - SD|RNX|ADR */ /* ORMx */ + td = dest | source; /* DO ORMX */ +meoa: /* merge point for eor, and, or */ + CC = 0; + switch(FC) { /* adjust for hw or bytes */ + case 4: case 5: case 6: case 7: /* byte address */ + /* ORMB */ + td &= 0xff; /* mask out right most byte */ + dest &= 0xffffff00; /* make place for byte */ + dest |= td; /* insert result into dest */ + if (dest == 0) + CC |= CC4BIT; /* byte is zero, so CC4 */ + else + if (dest & MSIGN) { + CC |= CC3BIT; /* assume negative */ + dest |= D32LMASK; /* force upper word to all ones */ + } + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + break; + case 1: /* left halfword addr */ + case 3: /* right halfword addr */ + /* ORMH */ + td &= RMASK; /* mask out right most 16 bits */ + dest &= LMASK; /* make place for halfword */ + dest |= td; /* insert result into dest */ + if (dest == 0) + CC |= CC4BIT; /* byte is zero, so CC4 */ + else + if (dest & MSIGN) { + CC |= CC3BIT; /* assume negative */ + dest |= D32LMASK; /* force upper word to all ones */ + } + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + break; + case 0: /* 32 bit word */ + /* ORMW */ + td &= D32RMASK; /* mask out right most 32 bits */ + dest = 0; /* make place for 64 bits */ + dest |= td; /* insert result into dest */ + if (dest == 0) + CC |= CC4BIT; /* byte is zero, so CC4 */ + else + if (dest & MSIGN) { + CC |= CC3BIT; /* assume negative */ + dest |= D32LMASK; /* force upper word to all ones */ + } + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + break; + case 2: /* 64 bit double */ + /* ORMD */ + dest = 0; /* make place for 64 bits */ + dest |= td; /* insert result into dest */ + if (dest == 0) + CC |= CC4BIT; /* byte is zero, so CC4 */ + else + if (dest & DMSIGN) + CC |= CC3BIT; /* assume negative */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + break; + } + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + PSD1 |= CC; /* update the CC's in the PSD */ + break; + + case 0x8C>>2: /* 0x8C SD|RR|RNX|ADR - SD|RNX|ADR */ /* EOMx */ + /* must special handle because we are getting bit difference */ + /* for word, halfword, & byte zero the upper 32 bits of dest */ + /* Diags require CC's to be set on result value of byte, hw, wd, or dw */ + td = dest ^ source; /* DO EOMX */ + goto meoa; + break; + + case 0x90>>2: /* 0x90 SCC|RR|RM|ADR - RM|ADR */ /* CAMx */ + if (dbl == 0) { + int32a = dest & D32RMASK; /* mask out right most 32 bits */ + int32b = source & D32RMASK; /* mask out right most 32 bits */ + int32c = int32a - int32b; /* signed diff */ + td = int32c; + if (int32a > int32b) dest = 1; + else + if (int32a == int32b) dest = 0; + else dest = -1; + } else { + int64a = dest; /* mask out right most 32 bits */ + int64b = source; /* mask out right most 32 bits */ + int64c = int64a - int64b; /* signed diff */ + td = int64c; + if (int64a > int64b) dest = 1; + else + if (int64a == int64b) dest = 0; + else dest = -1; + } + break; + + case 0x94>>2: /* 0x94 RR|RM|ADR - RM|ADR */ /* CMMx */ + /* CMMD needs both regs to be masked with R4 */ + if (dbl) { + /* we need to and both regs with R4 */ + t_uint64 nm = (((t_uint64)GPR[4]) << 32) | (((t_uint64)GPR[4]) & D32RMASK); + td = dest; /* save dest */ + dest ^= source; + dest &= nm; /* mask both regs with reg 4 contents */ + } else { + td = dest; /* save dest */ + dest ^= source; /* <= 32 bits, so just do lower 32 bits */ + dest &= (((t_uint64)GPR[4]) & D32RMASK); /* mask with reg 4 contents */ + } + CC = 0; + if (dest == 0ll) + CC |= CC4BIT; + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + PSD1 |= CC; /* update the CC's in the PSD */ + break; + + case 0x98>>2: /* 0x98 ADR - ADR */ /* SBM */ + if ((FC & 04) == 0) { + /* Fault, f-bit must be set for SBM instruction */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if ((TRAPME = Mem_read(addr, &temp))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + + t = (PSD1 & 0x70000000) >> 1; /* get old CC bits 1-3 into CCs 2-4*/ + /* use C bits and bits 6-8 (reg) to generate shift bit count */ + bc = ((FC & 3) << 3) | reg; /* get # bits to shift right */ + bc = BIT0 >> bc; /* make a bit mask of bit number */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + if (temp & bc) /* test the bit in memory */ + t |= CC1BIT; /* set CC1 to the bit value */ + PSD1 |= t; /* update the CC's in the PSD */ + temp |= bc; /* set the bit in temp */ + if ((TRAPME = Mem_write(addr, &temp))) { /* put word back into memory */ + goto newpsd; /* memory write error or map fault */ + } + break; + + case 0x9C>>2: /* 0x9C ADR - ADR */ /* ZBM */ + if ((FC & 04) == 0) { + /* Fault, byte address not allowed */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if ((TRAPME = Mem_read(addr, &temp))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + + t = (PSD1 & 0x70000000) >> 1; /* get old CC bits 1-3 into CCs 2-4*/ + /* use C bits and bits 6-8 (reg) to generate shift bit count */ + bc = ((FC & 3) << 3) | reg; /* get # bits to shift right */ + bc = BIT0 >> bc; /* make a bit mask of bit number */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + if (temp & bc) /* test the bit in memory */ + t |= CC1BIT; /* set CC1 to the bit value */ + PSD1 |= t; /* update the CC's in the PSD */ + temp &= ~bc; /* reset the bit in temp */ + if ((TRAPME = Mem_write(addr, &temp))) { /* put word into memory */ + goto newpsd; /* memory write error or map fault */ + } + break; + + case 0xA0>>2: /* 0xA0 ADR - ADR */ /* ABM */ + if ((FC & 04) == 0) { + /* Fault, byte address not allowed */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if ((TRAPME = Mem_read(addr, &temp))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + + /* use C bits and bits 6-8 (reg) to generate shift bit count */ + bc = ((FC & 3) << 3) | reg; /* get # bits to shift right */ + bc = BIT0 >> bc; /* make a bit mask of bit number */ + t = (temp & FSIGN) != 0; /* set flag for sign bit not set in temp value */ + t |= ((bc & FSIGN) != 0) ? 2 : 0; /* ditto for the bit value */ + temp += bc; /* add the bit value to the reg */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if ((t == 3 && (temp & FSIGN) == 0) || + (t == 0 && (temp & FSIGN) != 0)) { + ovr = 1; /* we have an overflow */ + } + set_CCs(temp, ovr); /* set the CC's, CC1 = ovr */ + if ((TRAPME = Mem_write(addr, &temp))) { /* put word into memory */ + goto newpsd; /* memory write error or map fault */ + } + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* handle trap */ + } + break; + + case 0xA4>>2: /* 0xA4 ADR - ADR */ /* TBM */ + if ((FC & 04) == 0) { + /* Fault, byte address not allowed */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if ((TRAPME = Mem_read(addr, &temp))) /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + + t = (PSD1 & 0x70000000) >> 1; /* get old CC bits 1-3 into CCs 2-4*/ + /* use C bits and bits 6-8 (reg) to generate shift bit count */ + bc = ((FC & 3) << 3) | reg; /* get # bits to shift right */ + bc = BIT0 >> bc; /* make a bit mask of bit number */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + if (temp & bc) /* test the bit in memory */ + t |= CC1BIT; /* set CC1 to the bit value */ + PSD1 |= t; /* update the CC's in the PSD */ + break; + + case 0xA8>>2: /* 0xA8 RM|ADR - RM|ADR */ /* EXM */ + if ((FC & 04) != 0 || FC == 2) { /* can not be byte or doubleword */ + /* Fault */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + if (CPU_MODEL == MODEL_V9) /* V9 wants bit0 set in pfault */ + if (TRAPME == DMDPG) /* demand page request */ + pfault |= 0x80000000; /* set instruction fetch paging error */ + goto newpsd; /* memory read error or map fault */ + } + + IR = temp; /* get instruction from memory */ + if (FC == 3) /* see if right halfword specified */ + IR <<= 16; /* move over the HW instruction */ +#ifdef DIAG_SAYS_OK_TO_EXECUTE_ANOTHER_EXECUTE + if ((IR & 0xFC7F0000) == 0xC8070000 || /* No EXR target */ + (IR & 0xFF800000) == 0xA8000000 || /* No EXM target */ + (IR & 0xFC000000) == 0x80000000) { +#else + /* 32/67 diag says execute of execute is OK */ + if ((IR & 0xFC000000) == 0x80000000) { +#endif + /* Fault, attempt to execute another EXR, EXRR, EXM, or LEAR */ + goto inv; /* invalid instruction */ + } + EXM_EXR = 4; /* set PC increment for EXM */ + + OPSD1 &= 0x87FFFFFE; /* clear the old PSD CC's */ + OPSD1 |= PSD1 & 0x78000000; /* update the CC's in the old PSD */ + /* TODO Update other history information for this instruction */ + if (hst_lnt) { + hst[hst_p].opsd1 = OPSD1; /* update the CC in opsd1 */ + hst[hst_p].npsd1 = PSD1; /* save new psd1 */ + hst[hst_p].npsd2 = PSD2; /* save new psd2 */ + hst[hst_p].modes = MODES; /* save current mode bits */ + hst[hst_p].modes |= (CPUSTATUS & BIT24); /* save blocking mode bit */ + for (ix=0; ix<8; ix++) { + hst[hst_p].reg[ix] = GPR[ix]; /* save reg */ + hst[hst_p].reg[ix+8] = BR[ix]; /* save breg */ + } + } + + /* DEBUG_INST support code */ + OPSD1 &= 0x87FFFFFE; /* clear the old CC's */ + OPSD1 |= PSD1 & 0x78000000; /* update the CC's in the PSD */ + /* output mapped/unmapped */ + if (MODES & BASEBIT) + BM = 'B'; + else + BM = 'N'; + if (MODES & MAPMODE) + MM = 'M'; + else + MM = 'U'; + if (CPUSTATUS & BIT24) + BK = 'B'; + else + BK = 'U'; + sim_debug(DEBUG_INST, &cpu_dev, "%c%c%c %.8x %.8x %.8x ", + BM, MM, BK, OPSD1, PSD2, OIR); + if (cpu_dev.dctrl & DEBUG_INST) + fprint_inst(sim_deb, OIR, 0); /* display instruction */ + sim_debug(DEBUG_INST, &cpu_dev, + "\n\tR0=%.8x R1=%.8x R2=%.8x R3=%.8x", GPR[0], GPR[1], GPR[2], GPR[3]); + sim_debug(DEBUG_INST, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + goto exec; /* go execute the instruction */ + break; + + case 0xAC>>2: /* 0xAC SCC|SD|RM|ADR - SCC|SD|RM|ADR */ /* Lx */ + dest = source; /* set value to load into reg */ + break; + + case 0xB0>>2: /* 0xB0 SCC|SD|RM|ADR - SCC|SD|RM|ADR */ /* LMx */ + /* LMD needs both regs to be masked with R4 */ + if (dbl) { + /* we need to and both regs with R4 */ + t_uint64 nm = (((t_uint64)GPR[4]) << 32) | (((t_uint64)GPR[4]) & D32RMASK); + dest = source & nm; /* mask both regs with reg 4 contents */ + } else { + dest = source; /* <= 32 bits, so just do lower 32 bits */ + dest &= (((t_uint64)GPR[4]) & D32RMASK); /* mask with reg 4 contents */ + if (dest & 0x80000000) /* see if we need to sign extend */ + dest |= D32LMASK; /* force upper word to all ones */ + } + break; + + case 0xB4>>2: /* 0xB4 SCC|SD|RM|ADR - SCC|SD|RM|ADR */ /* LNx */ + dest = NEGATE32(source); /* set the value to load into reg */ + td = dest; + if (dest != 0 && (dest == source || dest == 0x80000000)) + ovr = 1; /* set arithmetic exception status */ + if (FC != 2) { /* do not sign extend DW */ + if (dest & 0x80000000) /* see if we need to sign extend */ + dest |= D32LMASK; /* force upper word to all ones */ + } + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (dest != 0 && ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + } + break; + + case 0xBC>>2: /* 0xBC SD|RR|RM|ADR - SD|RR|RM|ADR */ /* SUMx */ + source = NEGATE32(source); + /* Fall through */ + + case 0xB8>>2: /* 0xB8 SD|RR|RM|ADR - SD|RR|RM|ADR */ /* ADMx */ + ovr = 0; + CC = 0; + /* DIAG fixs */ + if (dbl == 0) { + source &= D32RMASK; /* just 32 bits */ + dest &= D32RMASK; /* just 32 bits */ + t = (source & MSIGN) != 0; + t |= ((dest & MSIGN) != 0) ? 2 : 0; + td = dest + source; /* DO ADMx*/ + td &= D32RMASK; /* mask out right most 32 bits */ + dest = 0; /* make place for 64 bits */ + dest |= td; /* insert 32 bit result into dest */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if (((t == 3) && ((dest & MSIGN) == 0)) || + ((t == 0) && ((dest & MSIGN) != 0))) + ovr = 1; + if ((td == 0) && ((source & MSIGN) == MSIGN) && ovr) + ovr = 0; /* Diags want 0 and no ovr on MSIGN - MSIGN */ + if (dest & MSIGN) + dest = (D32LMASK | dest); /* sign extend */ + else + dest = (D32RMASK & dest); /* zero fill */ + if (td == 0) + CC |= CC4BIT; /* word is zero, so CC4 */ + else + if (td & 0x80000000) + CC |= CC3BIT; /* it is neg wd, so CC3 */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + } else { + /* ADMD */ + t = (source & DMSIGN) != 0; + t |= ((dest & DMSIGN) != 0) ? 2 : 0; + td = dest + source; /* get sum */ + dest = td; /* insert 64 bit result into dest */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if (((t == 3) && ((dest & DMSIGN) == 0)) || + ((t == 0) && ((dest & DMSIGN) != 0))) + ovr = 1; + if (td == 0) + CC |= CC4BIT; /* word is zero, so CC4 */ + else + if (td & DMSIGN) + CC |= CC3BIT; /* it is neg wd, so CC3 */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + } + if (ovr) + CC |= CC1BIT; /* set overflow CC */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + PSD1 |= CC; /* update the CC's in the PSD */ + + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + } + break; + + case 0xC0>>2: /* 0xC0 SCC|SD|RM|ADR - SCC|SD|RM|ADR */ /* MPMx */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if (FC == 2) { /* must not be double word adddress */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + goto newpsd; /* go execute the trap now */ + } + td = dest; + dest = GPR[reg+1]; /* get low order reg value */ + if (dest & MSIGN) + dest = (D32LMASK | dest); /* sign extend */ + dest = (t_uint64)((t_int64)dest * (t_int64)source); + dbl = 1; + break; + + case 0xC4>>2: /* 0xC4 RM|ADR - RM|ADR */ /* DVMx */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + if (FC == 2) { /* must not be double word adddress */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + goto newpsd; /* go execute the trap now */ + } + if (source == 0) + goto doovr; /* we have div by zero */ + dest = (((t_uint64)GPR[reg]) << 32); /* insert upper reg value */ + dest |= (t_uint64)GPR[reg+1]; /* get low order reg value */ + td = ((t_int64)dest % (t_int64)source); /* remainder */ + if (((td & DMSIGN) ^ (dest & DMSIGN)) != 0) /* Fix sign if needed */ + td = NEGATE32(td); /* dividend and remainder must be same sign */ + dest = (t_int64)dest / (t_int64)source; /* now do the divide */ + int64a = dest; + if (int64a < 0) + int64a = -int64a; + if (int64a > 0x7fffffff) /* if more than 31 bits, we have an error */ + goto doovr; + if (((dest & D32LMASK) != 0 && (dest & D32LMASK) != D32LMASK) || + (((dest & D32LMASK) == D32LMASK) && ((dest & D32RMASK) == 0))) { /* test for overflow */ +doovr: + dest = (((t_uint64)GPR[reg]) << 32);/* insert upper reg value */ + dest |= (t_uint64)GPR[reg+1]; /* get low order reg value */ + ovr = 1; /* the quotient exceeds 31 bit, overflow */ + /* the original regs must be returned unchanged if aexp */ + CC = CC1BIT; /* set ovr CC bit */ + if (dest == 0) + CC |= CC4BIT; /* dw is zero, so CC4 */ + else + if (dest & DMSIGN) + CC |= CC3BIT; /* it is neg dw, so CC3 */ + else + CC |= CC2BIT; /* then dest > 0, so CC2 */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + PSD1 |= CC; /* update the CC's in the PSD */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (MODES & AEXPBIT) + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + } else { + GPR[reg] = (uint32)(td & FMASK); /* reg gets remainder, reg+1 quotient */ + GPR[reg+1] = (uint32)(dest & FMASK); /* store quotient in reg+1 */ + set_CCs(GPR[reg+1], ovr); /* set the CC's, CC1 = ovr */ + } + break; + + case 0xC8>>2: /* 0xC8 IMM - IMM */ /* Immedate */ + temp = GPR[reg]; /* get reg contents */ + addr = IR & RMASK; /* sign extend 16 bit imm value from IR */ + if (addr & 0x8000) /* negative */ + addr |= LMASK; /* extend sign */ + + switch(opr & 0xF) { /* switch on aug code */ + case 0x0: /* LI */ /* SCC | SD */ + GPR[reg] = addr; /* put immediate value into reg */ + set_CCs(addr, ovr); /* set the CC's, CC1 = ovr */ + break; + + case 0x2: /* SUI */ + addr = NEGATE32(addr); /* just make value a negative add */ + /* drop through */ + case 0x1: /* ADI */ + t = (temp & FSIGN) != 0; /* set flag for sign bit not set in reg value */ + t |= ((addr & FSIGN) != 0) ? 2 : 0; /* ditto for the extended immediate value */ + temp = temp + addr; /* now add the numbers */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if ((t == 3 && (temp & FSIGN) == 0) || + (t == 0 && (temp & FSIGN) != 0)) + ovr = 1; /* we have an overflow */ + GPR[reg] = temp; /* save the result */ + set_CCs(temp, ovr); /* set the CC's, CC1 = ovr */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + goto newpsd; /* go execute the trap now */ + } + break; + + case 0x3: /* MPI */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + /* change immediate value into a 64 bit value */ + source = ((t_uint64)(addr & FMASK)) | ((addr & FSIGN) ? D32LMASK : 0); + temp = GPR[reg+1]; /* get reg multiplier */ + dest = ((t_uint64)(temp & FMASK)) | ((temp & FSIGN) ? D32LMASK : 0); + dest = dest * source; /* do the multiply */ + i_flags |= (SD|SCC); /* save regs and set CC's */ + dbl = 1; /* double reg save */ + break; + + case 0x4: /* DVI */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + /* change immediate value into a 64 bit value */ + source = ((t_uint64)(addr & FMASK)) | ((addr & FSIGN) ? D32LMASK : 0); + if (source == 0) { + goto doovr2; + } + dest = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */ + dest |= (t_uint64)GPR[reg+1]; /* insert low order reg value */ + td = ((t_int64)dest % (t_int64)source); /* remainder */ + /* fix double reg if neg remainder */ + if (((td & DMSIGN) ^ (dest & DMSIGN)) != 0) /* Fix sign if needed */ + td = NEGATE32(td); /* dividend and remainder must be same sign */ + dest = (t_int64)dest / (t_int64)source; /* now do the divide */ + int64a = dest; + if (int64a < 0) + int64a = -int64a; + if (int64a > 0x7fffffff) /* if more than 31 bits, we have an error */ + goto doovr2; + if ((dest & D32LMASK) != 0 && (dest & D32LMASK) != D32LMASK) { /* test for overflow */ +doovr2: + dest = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */ + dest |= (t_uint64)GPR[reg+1]; /* insert low order reg value */ + ovr = 1; /* the quotient exceeds 31 bit, overflow */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (MODES & AEXPBIT) + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + /* the original regs must be returned unchanged if aexp */ + /* put reg values back in dest for CC test */ + CC = CC1BIT; /* set ovr CC bit */ + if (dest == 0) + CC |= CC4BIT; /* dw is zero, so CC4 */ + else + if (dest & DMSIGN) + CC |= CC3BIT; /* it is neg dw, so CC3 */ + else + CC |= CC2BIT; /* then dest > 0, so CC2 */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + PSD1 |= CC; /* update the CC's in the PSD */ + } else { + GPR[reg] = (uint32)(td & FMASK); /* reg gets remainder, reg+1 quotient */ + GPR[reg+1] = (uint32)(dest & FMASK); /* store quotient in reg+1 */ + set_CCs(GPR[reg+1], ovr); /* set the CC's, CC1 = ovr */ + } + break; + + case 0x5: /* CI */ /* SCC */ + temp = ((int)temp - (int)addr); /* subtract imm value from reg value */ + set_CCs(temp, ovr); /* set the CC's, CC1 = ovr */ + break; + +/* SVC instruction format C806 */ +/* |-------+-------+-------+-------+-------+-------+-------+-------| */ +/* |0 0 0 0 0 0|0 0 0|0 1 1|1 1 1 1|1 1 1 1|2 2 2 2 2 2 2 2 2 2 3 3| */ +/* |0 1 2 3 4 5|6 7 8|8 0 1|2 3 4 5|6 7 8 9|0 1 2 3 4 5 6 7 8 9 0 1| */ +/* | Op Code | N/U | N/U | Aug |SVC num| SVC Call Number | */ +/* |1 1 0 0 1 0|0 0 0|0 0 0|0 1 1 0|x x x x|x x x x x x x x x x x x| */ +/* |-------+-------+-------+-------+-------+-------+-------+-------| */ +/* */ + case 0x6: /* SVC none - none */ /* Supervisor Call Trap */ + { +#ifdef MPXTEST /* set to 1 for traceme in MPX to work */ + /* get current MPX task name */ + int j; + char n[9]; + uint32 sq59 = M[0x930>>2]; /* get C.SQ59 headcell */ + uint32 dqe = M[0x8e8>>2]; /* get DQE of current task */ + + sim_debug(DEBUG_IRQ, &cpu_dev, + "SVC start sq59 %04x dqe %04x\n",sq59, dqe); + if (sq59 != 0x930) + goto skipdqe2; /* not running on mpx, skip */ + for (j=0; j<8; j++) { /* get the task name */ + n[j] = (M[((dqe+0x18)>>2)+(j/4)] >> ((3-(j&7))*8)) & 0xff; + if (n[j] == 0) + n[j] = 0x20; + } + n[8] = 0; +skipdqe2: +#endif + int32c = CPUSTATUS; /* keep for retain blocking state */ + addr = SPAD[0xf0]; /* get trap table memory address from SPAD (def 80) */ + int32a = addr; + if (addr == 0 || ((addr&MASK24) == MASK24)) { /* see if secondary vector table set up */ + TRAPME = ADDRSPEC_TRAP; /* Not setup, error */ + goto newpsd; /* program error */ + } + addr = addr + (0x06 << 2); /* addr has mem addr of SVC trap vector (def 98) */ + temp = M[addr >> 2]; /* get the secondary trap table address from memory */ + if (temp == 0 || ((temp&MASK24) == MASK24)) { /* see if ICB set up */ + TRAPME = ADDRSPEC_TRAP; /* Not setup, error */ + goto newpsd; /* program error */ + } + temp2 = ((IR>>12) & 0x0f) << 2; /* get SVC index from IR */ + t = M[(temp+temp2)>>2]; /* get secondary trap vector address ICB address */ + if (temp == 0 || ((temp&MASK24) == MASK24)) { /* see if ICB set up */ + TRAPME = ADDRSPEC_TRAP; /* Not setup, error */ + goto newpsd; /* program error */ + } + bc = PSD2 & 0x3ff8; /* get copy of cpix */ + M[t>>2] = (PSD1+4) & 0xfffffffe; /* store PSD 1 + 1W to point to next instruction */ + M[(t>>2)+1] = PSD2; /* store PSD 2 */ + PSD1 = M[(t>>2)+2]; /* get new PSD 1 */ + PSD2 = (M[(t>>2)+3] & ~0x3ff8) | bc; /* get new PSD 2 w/old cpix */ + M[(t>>2)+4] = IR&0xFFF; /* store call number */ +#ifdef MPXTEST /* set to 1 for traceme to work */ + if (sq59 == 0x930) { /* running on MPX? */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "SVC %x,%x @ %.8x PSD %.8x %.8x SPAD PSD2 %x C.CURR %x LMN %8s\n", + temp2>>2, IR&0xFFF, OPSD1, PSD1, PSD2, SPAD[0xf5], dqe, n); + sim_debug(DEBUG_IRQ, &cpu_dev, + " R0=%.8x R1=%.8x R2=%.8x R3=%.8x\n", GPR[0], GPR[1], GPR[2], GPR[3]); + sim_debug(DEBUG_IRQ, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + } +#if DYNAMIC_DEBUG + if (((temp2>>2) == 1) && ((IR&0xFFF) == 0x03f)) { /* SVC 1,3f */ + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ + } +#endif +#else + sim_debug(DEBUG_IRQ, &cpu_dev, + "SVC %x,%x @ %.8x PSD %.8x %.8x SPADF5 PSD2 %x CPUSTATUS %08x\n", + temp2>>2, IR&0xFFF, OPSD1, PSD1, PSD2, SPAD[0xf5], CPUSTATUS); + sim_debug(DEBUG_IRQ, &cpu_dev, + " R0=%.8x R1=%.8x R2=%.8x R3=%.8x\n", GPR[0], GPR[1], GPR[2], GPR[3]); + sim_debug(DEBUG_IRQ, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); +#endif +#if DYNAMIC_DEBUG + if (((temp2>>2) == 0) && ((IR&0xFFF) == 0xb01)) { /* SVC 0,VOMM,1 */ + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ + } +#endif +#ifdef DO_DYNAMIC_DEBUG + if (((temp2>>2) == 0) && ((IR&0xFFF) == 0x303)) { /* SVC 0,TAMM,1 */ + if (GPR[3] == 0x3a000) + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ + } +#endif +#ifdef DO_DYNAMIC_DEBUG + if (((temp2>>2) == 2) && ((IR&0xFFF) == 0x028)) { /* SVC 2,28 H.VOMM,9 */ + if (cpu_dev.dctrl & DEBUG_INST) + cpu_dev.dctrl &= ~DEBUG_INST; /* stop instruction trace */ + else + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ + } +#endif +#ifdef DO_DYNAMIC_DEBUG + if (((temp2>>2) == 0) && ((IR&0xFFF) == 0xa11)) { /* SVC 0,REMM,17 */ + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ + } +#endif +#ifdef DO_DYNAMIC_DEBUG + if (((temp2>>2) == 0) && ((IR&0xFFF) == 0x910)) { /* SVC 0,REXS,16 */ + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ + } + if (((temp2>>2) == 0) && ((IR&0xFFF) == 0x925)) { /* SVC 0,REXS,40 */ + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ + } +#endif + /* set the mode bits and CCs from the new PSD */ + CC = PSD1 & 0x78000000; /* extract bits 1-4 from PSD1 */ + MODES = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ + CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */ + CPUSTATUS |= MODES; /* now insert into CPUSTATUS */ + + /* set new map mode and interrupt blocking state in CPUSTATUS */ + if (PSD2 & MAPBIT) { + CPUSTATUS |= BIT8; /* set bit 8 of cpu status */ + MODES |= MAPMODE; /* set mapped mode */ + } else { + CPUSTATUS &= ~BIT8; /* reset bit 8 of cpu status */ +/*TRY_01072022*/ MODES &= ~MAPMODE; /* reset mapped mode */ + } + + /* set interrupt blocking state */ + if ((PSD2 & RETBBIT) == 0) { /* is it retain blocking state */ + if (PSD2 & SETBBIT) { /* no, is it set blocking state */ + CPUSTATUS |= BIT24; /* yes, set blk state in cpu status bit 24 */ + MODES |= BLKMODE; /* set blocked mode */ + } else { + CPUSTATUS &= ~BIT24; /* no, reset blk state in cpu status bit 24 */ + MODES &= ~BLKMODE; /* reset blocked mode */ + irq_pend = 1; /* start scanning interrupts again */ +#ifdef LEAVE_ACTIVE + if (irq_auto) { +/*AIR*/ INTS[irq_auto] &= ~INTS_ACT; /* deactivate specified int level */ +/*AIR*/ SPAD[irq_auto+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>IntX deactivate level %02x at SVC #%2x PSD1 %08x\n", + irq_auto, temp2, PSD1); +/*AIR*/ irq_auto = 0; /* show done processing in blocked mode */ + } +#endif + } + } else { + /* handle retain blocking state */ + PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ + /* set new blocking state in PSD2 */ + PSD2 &= ~(SETBBIT|RETBBIT); /* clear bit 48 & 49 to be unblocked */ + MODES &= ~(BLKMODE|RETBLKM); /* reset blocked & retain mode bits */ + if (int32c & BIT24) { /* see if old mode is blocked */ + PSD2 |= SETBBIT; /* set to blocked state */ + MODES |= BLKMODE; /* set blocked mode */ + } + } + + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + TRAPME = 0; /* not to be processed as trap */ + goto newpsd; /* new psd loaded */ + } + break; + + case 0x7: /* EXR */ + IR = temp; /* get instruction to execute */ + /* if bit 30 set, instruction is in right hw, do EXRR */ + if (addr & 2) + IR <<= 16; /* move instruction to left HW */ +#ifdef DIAG_SAYS_OK_TO_EXECUTE_ANOTHER_EXECUTE + /* 32/67 diag says execute of execute is OK */ + if ((IR & 0xFC7F0000) == 0xC8070000 || + (IR & 0xFF800000) == 0xA8000000) { + /* Fault, attempt to execute another EXR, EXRR, or EXM */ + goto inv; /* invalid instruction */ + } +#endif + EXM_EXR = 4; /* set PC increment for EXR */ + OPSD1 &= 0x87FFFFFE; /* clear the old CC's */ + OPSD1 |= PSD1 & 0x78000000; /* update the CC's in the PSD */ + /* TODO Update other history information for this instruction */ + if (hst_lnt) { + hst[hst_p].opsd1 = OPSD1; /* update the CC in opsd1 */ + hst[hst_p].npsd1 = PSD1; /* save new psd1 */ + hst[hst_p].npsd2 = PSD2; /* save new psd2 */ + hst[hst_p].modes = MODES; /* save current mode bits */ + hst[hst_p].modes |= (CPUSTATUS & BIT24); /* save blocking mode bit */ + for (ix=0; ix<8; ix++) { + hst[hst_p].reg[ix] = GPR[ix]; /* save reg */ + hst[hst_p].reg[ix+8] = BR[ix]; /* save breg */ + } + } + /* DEBUG_INST support code */ + OPSD1 &= 0x87FFFFFE; /* clear the old CC's */ + OPSD1 |= PSD1 & 0x78000000; /* update the CC's in the PSD */ + /* output mapped/unmapped */ + if (MODES & BASEBIT) + BM = 'B'; + else + BM = 'N'; + if (MODES & MAPMODE) + MM = 'M'; + else + MM = 'U'; + if (CPUSTATUS & BIT24) + BK = 'B'; + else + BK = 'U'; + sim_debug(DEBUG_INST, &cpu_dev, "%c%c%c %.8x %.8x %.8x ", + BM, MM, BK, OPSD1, PSD2, OIR); + if (cpu_dev.dctrl & DEBUG_INST) { + fprint_inst(sim_deb, OIR, 0); /* display instruction */ + sim_debug(DEBUG_INST, &cpu_dev, + "\n\tR0=%.8x R1=%.8x R2=%.8x R3=%.8x", GPR[0], GPR[1], GPR[2], GPR[3]); + sim_debug(DEBUG_INST, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + if (MODES & BASEBIT) { + sim_debug(DEBUG_INST, &cpu_dev, + "\tB0=%.8x B1=%.8x B2=%.8x B3=%.8x", BR[0], BR[1], BR[2], BR[3]); + sim_debug(DEBUG_INST, &cpu_dev, + " B4=%.8x B5=%.8x B6=%.8x B7=%.8x\n", BR[4], BR[5], BR[6], BR[7]); + } + } + goto exec; /* go execute the instruction */ + break; + + /* these instruction were never used by MPX, only diags */ + /* diags treat them as invalid halfword instructions */ + /* so set the HLF flag to get proper PC increment */ + case 0x8: /* SEM */ + case 0x9: /* LEM */ + case 0xA: /* CEMA */ + case 0xB: /* INV */ + case 0xC: /* INV */ + case 0xD: /* INV */ + case 0xE: /* INV */ + case 0xF: /* INV */ + default: + goto inv; /* invalid instruction */ + break; + } + break; + + case 0xCC>>2: /* 0xCC ADR - ADR */ /* LF */ + /* For machines with Base mode 0xCC08 stores base registers */ + if ((FC & 3) != 0) { /* must be word address */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + temp = addr & 0xffe000; /* get 11 bit map # */ + bc = addr & 0x20; /* bit 26 initial value */ + while (reg < 8) { + if (bc != (addr & 0x20)) { /* test for crossing file boundry */ + if (CPU_MODEL < MODEL_27) { + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + } + if (temp != (addr & 0xffe000)) { /* test for crossing map boundry */ + if (CPU_MODEL >= MODEL_V6) { + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + } + if (FC & 0x4) /* LFBR? 0xCC08 */ + TRAPME = Mem_read(addr, &BR[reg]); /* read the base reg */ + else /* LF? 0xCC00 */ + TRAPME = Mem_read(addr, &GPR[reg]); /* read the GPR reg */ + if (TRAPME) /* TRAPME has error */ + goto newpsd; /* go execute the trap now */ + reg++; /* next reg to write */ + addr += 4; /* next addr */ + } + break; + + case 0xD0>>2: /* 0xD0 SD|ADR - INV */ /* LEA none basemode only */ + if (MODES & BASEBIT) + goto inv; /* invalid instruction in basemode */ + /* bc has last bits 0,1 for indirect addr of both 1 for no indirection */ + addr &= 0x3fffffff; /* clear bits 0-1 */ + addr |= bc; /* insert bits 0,1 values into address */ + if (FC & 0x4) + addr |= F_BIT; /* copy F bit from instruction */ + dest = (t_uint64)(addr); + break; + + case 0xD4>>2: /* 0xD4 RR|SM|ADR - RR|SM|ADR */ /* STx */ + break; + + case 0xD8>>2: /* 0xD8 RR|SM|ADR - RR|SM|ADR */ /* STMx */ + /* STMD needs both regs to be masked with R4 */ + if (dbl) { + /* we need to and both regs */ + t_uint64 nm = (((t_uint64)GPR[4]) << 32) | (((t_uint64)GPR[4]) & D32RMASK); + dest &= nm; /* mask both regs with reg 4 contents */ + } else { + dest &= (((t_uint64)GPR[4]) & D32RMASK); /* mask with reg 4 contents */ + } + break; + + case 0xDC>>2: /* 0xDC INV - ADR */ /* INV nonbasemode (STFx basemode) */ + /* DC00 STF */ /* DC08 STFBR */ + if ((FC & 0x4) && (CPU_MODEL <= MODEL_27)) { + /* basemode undefined for 32/7x & 32/27 */ + TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* handle trap */ + } + /* For machines with Base mode 0xDC08 stores base registers */ + if ((FC & 3) != 0) { /* must be word address */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + bc = addr & 0x20; /* bit 26 initial value */ + temp = addr & 0xffe000; /* get 11 bit map # */ + while (reg < 8) { + if (bc != (addr & 0x20)) { /* test for crossing file boundry */ + if (CPU_MODEL < MODEL_27) { + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + } + if (temp != (addr & 0xffe000)) { /* test for crossing map boundry */ + if (CPU_MODEL >= MODEL_V6) { + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + } + if (FC & 0x4) /* STFBR? */ + TRAPME = Mem_write(addr, &BR[reg]); /* store the base reg */ + else /* STF */ + TRAPME = Mem_write(addr, &GPR[reg]); /* store the GPR reg */ + if (TRAPME) /* TRAPME has error */ + goto newpsd; /* go execute the trap now */ + reg++; /* next reg to write */ + addr += 4; /* next addr */ + } + break; + + case 0xE0>>2: /* 0xE0 ADR - ADR */ /* ADFx, SUFx */ + if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + } + source = (t_uint64)temp; /* make into 64 bit value */ + if (FC & 2) { /* see if double word addr */ + if ((TRAPME = Mem_read(addr+4, &temp))) { /* get the 2nd word from memory */ + goto newpsd; /* memory read error or map fault */ + } + source = (source << 32) | (t_uint64)temp; /* merge in the low order 32 bits */ + dbl = 1; /* double word instruction */ + } else { + source |= (source & MSIGN) ? D32LMASK : 0; + dbl = 0; /* not double wd */ + } + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + CC = 0; /* clear the CC'ss */ + /* handle float or double add/sub instructions */ + if (dbl == 0) { + /* do ADFW or SUFW instructions */ + temp2 = GPR[reg]; /* dest - reg contents specified by Rd */ + addr = (uint32)(source & D32RMASK); /* get 32 bits from source memory */ + if ((opr & 8) == 0) { /* Was it SUFW? */ + addr = NEGATE32(addr); /* take negative for add */ + } + temp = s_adfw(temp2, addr, &CC); /* do ADFW */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "%s GPR[%d] %08x addr %08x result %08x CC %08x\n", + (opr&8) ? "ADFW":"SUFW", reg, GPR[reg], addr, temp, CC); + ovr = 0; + if (CC & CC1BIT) + ovr = 1; + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + /* check if we had an arithmetic exception on the last instruction*/ + if (ovr && (MODES & AEXPBIT)) { + /* leave regs unchanged */ + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + /* AEXP not enabled, so apply fix here */ + /* return temp to destination reg */ + GPR[reg] = temp; /* dest - reg contents specified by Rd */ + } else { + /* handle ADFD or SUFD */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + /* do ADFD or SUFD instructions */ + td = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */ + td |= (t_uint64)GPR[reg+1]; /* insert low order reg value */ + /* source has 64 bit memory data */ + if ((opr & 8) == 0) { /* Was it SUFD? */ + source = NEGATE32(source); /* make negative for subtract */ + } + dest = s_adfd(td, source, &CC); /* do ADFD */ + sim_debug(DEBUG_DETAIL, &cpu_dev, + "%s GPR[%d] %08x %08x src %016llx result %016llx CC %08x\n", + (opr&8) ? "ADFD":"SUFD", reg, GPR[reg], GPR[reg+1], source, dest, CC); + ovr = 0; + if (CC & CC1BIT) /* test for overflow detection */ + ovr = 1; + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + /* check if we had an arithmetic exception on the last instruction */ + if (ovr && (MODES & AEXPBIT)) { + /* leave regs unchanged */ + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + /* dest will be returned to destination regs */ + /* if AEXP not enabled, apply fix here */ + /* return dest to destination reg */ + GPR[reg] = (uint32)((dest & D32LMASK) >> 32); /* get upper reg value */ + GPR[reg+1] = (uint32)(dest & D32RMASK); /* get lower reg value */ + } + break; + + case 0xE4>>2: /* 0xE4 ADR - ADR */ /* MPFx, DVFx */ + if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + } + source = (t_uint64)temp; /* make into 64 bit value */ + if (FC & 2) { /* see if double word addr */ + if ((TRAPME = Mem_read(addr+4, &temp))) { /* get the 2nd word from memory */ + goto newpsd; /* memory read error or map fault */ + } + source = (source << 32) | (t_uint64)temp; /* merge in the low order 32 bits */ + dbl = 1; /* double word instruction */ + } else { + source |= (source & MSIGN) ? D32LMASK : 0; + dbl = 0; /* not double wd */ + } + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + CC = 0; /* clear the CC'ss */ + /* handle float or double mul/div instructions */ + if (dbl == 0) { + /* do MPFW or DVFW instructions */ + temp2 = GPR[reg]; /* dest - reg contents specified by Rd */ + addr = (uint32)(source & D32RMASK); /* get 32 bits from source memory */ + if (opr & 8) { /* Was it MPFW? */ + temp = s_mpfw(temp2, addr, &CC); /* do MPFW */ + } else { + temp = (uint32)s_dvfw(temp2, addr, &CC); /* do DVFW */ + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "%s GPR[%d] %08x addr %08x result %08x\n", + (opr&8) ? "MPFW":"DVFW", reg, GPR[reg], addr, temp); + if (CC & CC1BIT) + ovr = 1; + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + /* check if we had an arithmetic exception on the last instruction*/ + if (ovr && (MODES & AEXPBIT)) { + /* leave regs unchanged */ + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + /* if AEXP not enabled, apply fix here */ + /* return temp to destination reg */ + GPR[reg] = temp; /* dest - reg contents specified by Rd */ + } else { + /* handle MPFD or DVFD */ + if (reg & 1) { /* see if odd reg specified */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + goto newpsd; /* go execute the trap now */ + } + /* do MPFD or DVFD instructions */ + td = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */ + td |= (t_uint64)GPR[reg+1]; /* insert low order reg value */ + /* source has 64 bit memory data */ + if (opr & 8) { /* Was it MPFD? */ + dest = s_mpfd(td, source, &CC); /* do MPFD */ + } else { + dest = s_dvfd(td, source, &CC); /* do DVFD */ + } + sim_debug(DEBUG_DETAIL, &cpu_dev, + "%s GPR[%d] %08x %08x src %016llx result %016llx\n", + (opr&8) ? "MPFD":"DVFD", reg, GPR[reg], GPR[reg+1], source, dest); + if (CC & CC1BIT) /* test for overflow detection */ + ovr = 1; + PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */ + /* check if we had an arithmetic exception on the last instruction*/ + if (ovr && (MODES & AEXPBIT)) { + /* leave regs unchanged */ + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + /* dest will be returned to destination regs */ + /* if AEXP not enabled, apply fix here */ + /* return dest to destination reg */ + GPR[reg] = (uint32)((dest & D32LMASK) >> 32); /* get upper reg value */ + GPR[reg+1] = (uint32)(dest & D32RMASK); /* get lower reg value */ + } + break; + + case 0xE8>>2: /* 0xE8 SM|RR|RNX|ADR - SM|RM|ADR */ /* ARMx */ + ovr = 0; + CC = 0; + switch(FC) { /* adjust for hw or bytes */ + case 4: case 5: case 6: case 7: /* byte address */ + /* ARMB */ + td = dest + source; /* DO ARMB */ + td &= 0xff; /* mask out right most byte */ + dest &= 0xffffff00; /* make place for byte */ + dest |= td; /* insert result into dest */ + if (td == 0) + CC |= CC4BIT; /* byte is zero, so CC4 */ + break; + case 1: /* left halfword addr */ + case 3: /* right halfword addr */ + /* ARMH */ + td = dest + source; /* DO ARMH */ + td &= RMASK; /* mask out right most 16 bits */ + dest &= LMASK; /* make place for halfword */ + dest |= td; /* insert result into dest */ + if (td == 0) + CC |= CC4BIT; /* hw is zero, so CC4 */ + break; + case 0: /* 32 bit word */ + /* ARMW */ + /* dest and source are really 32 bit values */ + t = (source & MSIGN) != 0; + t |= ((dest & MSIGN) != 0) ? 2 : 0; + td = dest + source; /* DO ARMW */ + td &= D32RMASK; /* mask out right most 32 bits */ + dest = 0; /* make place for 64 bits */ + dest |= td; /* insert result into dest */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if (((t == 3) && ((dest & MSIGN) == 0)) || + ((t == 0) && ((dest & MSIGN) != 0))) + ovr = 1; + if (dest & MSIGN) + dest = (D32LMASK | dest); /* sign extend */ + else + dest = (D32RMASK & dest); /* zero fill */ + if (td == 0) + CC |= CC4BIT; /* word is zero, so CC4 */ + else { + if (td & 0x80000000) + CC |= CC3BIT; /* it is neg wd, so CC3 */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + } + break; + case 2: /* 64 bit double */ + /* ARMD */ + t = (source & DMSIGN) != 0; + t |= ((dest & DMSIGN) != 0) ? 2 : 0; + td = dest + source; /* DO ARMD */ + dest = td; /* insert result into dest */ + /* if both signs are neg and result sign is positive, overflow */ + /* if both signs are pos and result sign is negative, overflow */ + if (((t == 3) && ((dest & DMSIGN) == 0)) || + ((t == 0) && ((dest & DMSIGN) != 0))) + ovr = 1; + if (td == 0) + CC |= CC4BIT; /* dw is zero, so CC4 */ + else { + if (td & DMSIGN) + CC |= CC3BIT; /* it is neg dw, so CC3 */ + else + CC |= CC2BIT; /* then td > 0, so CC2 */ + } + break; + } + if (ovr) + CC |= CC1BIT; /* set overflow CC */ + PSD1 &= 0x87FFFFFE; /* clear the old CC's from PSD1 */ + PSD1 |= CC; /* update the CC's in the PSD */ + /* the arithmetic exception will be handled */ + /* after instruction is completed */ + /* check for arithmetic exception trap enabled */ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* set the trap type */ + } + break; + + case 0xEC>>2: /* 0xEC ADR - ADR */ /* Branch unconditional or Branch True */ + /* GOOF alert, the assembler sets bit 31 to 1 so this test will fail*/ + /* so just test for F bit and go on */ + /* if ((FC & 5) != 0) { */ + if ((FC & 4) != 0) { + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC10 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + temp2 = CC; /* save the old CC's */ + CC = PSD1 & 0x78000000; /* get CC's if any */ + switch(reg) { + case 0: t = 1; break; + case 1: t = (CC & CC1BIT) != 0; break; + case 2: t = (CC & CC2BIT) != 0; break; + case 3: t = (CC & CC3BIT) != 0; break; + case 4: t = (CC & CC4BIT) != 0; break; + case 5: t = (CC & (CC2BIT|CC4BIT)) != 0; break; + case 6: t = (CC & (CC3BIT|CC4BIT)) != 0; break; + case 7: t = (CC & (CC1BIT|CC2BIT|CC3BIT|CC4BIT)) != 0; break; + } + if (t) { /* see if we are going to branch */ + /* we are taking the branch, set CC's if indirect, else leave'm */ + /* update the PSD with new address */ + PSD1 = (PSD1 & 0xff000000) | (addr & 0xfffffe); /* set new PC */ + i_flags |= BT; /* we branched, so no PC update */ + if (((MODES & BASEBIT) == 0) && (IR & IND)) /* see if CCs from last indirect wanted */ + PSD1 = (PSD1 & 0x87fffffe) | temp2; /* insert last indirect CCs */ +/*FIX F77*/ if ((MODES & (BASEBIT|EXTDBIT)) == 0) /* see if basemode */ +/*FIX F77*/ PSD1 &= 0xff07ffff; /* only 19 bit address allowed */ + } + /* branch not taken, go do next instruction */ + break; + + case 0xF0>>2: /* 0xF0 ADR - ADR */ /* Branch False or Branch Function True BFT */ + /* GOOF alert, the assembler sets bit 31 to 1 so this test will fail*/ + /* so just test for F bit and go on */ + /* if ((FC & 5) != 0) { */ + if ((FC & 4) != 0) { + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC11 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + temp2 = CC; /* save the old CC's */ + CC = PSD1 & 0x78000000; /* get CC's if any */ + switch(reg) { + case 0: t = (GPR[4] & (0x8000 >> ((CC >> 27) & 0xf))) != 0; break; + case 1: t = (CC & CC1BIT) == 0; break; + case 2: t = (CC & CC2BIT) == 0; break; + case 3: t = (CC & CC3BIT) == 0; break; + case 4: t = (CC & CC4BIT) == 0; break; + case 5: t = (CC & (CC2BIT|CC4BIT)) == 0; break; + case 6: t = (CC & (CC3BIT|CC4BIT)) == 0; break; + case 7: t = (CC & (CC1BIT|CC2BIT|CC3BIT|CC4BIT)) == 0; break; + } + if (t) { /* see if we are going to branch */ + /* we are taking the branch, set CC's if indirect, else leave'm */ + /* update the PSD with new address */ + PSD1 = (PSD1 & 0xff000000) | (addr & 0xfffffe); /* set new PC */ + i_flags |= BT; /* we branched, so no PC update */ + if (((MODES & BASEBIT) == 0) && (IR & IND)) /* see if CCs from last indirect wanted */ + PSD1 = (PSD1 & 0x87fffffe) | temp2; /* insert last indirect CCs */ +/*FIX F77*/ if ((MODES & (BASEBIT|EXTDBIT)) == 0) /* see if basemode */ +/*FIX F77*/ PSD1 &= 0xff07ffff; /* only 19 bit address allowed */ + } + break; + + case 0xF4>>2: /* 0xF4 RR|SD|ADR - RR|SB|WRD */ /* Branch increment */ + dest += ((t_uint64)1) << ((IR >> 21) & 3); /* use bits 9 & 10 to incr reg */ + if (dest != 0) { /* if reg is not 0, take the branch */ + /* we are taking the branch, set CC's if indirect, else leave'm */ + /* update the PSD with new address */ + +#if 0 /* set #if to 1 to stop branch to self while tracing, for now */ + if (PC == (addr & 0xFFFFFC)) { /* BIB to current PC, bump branch addr */ + addr += 4; +// fprintf(stderr, "BI? stopping BIB $ addr %x PC %x\r\n", addr, PC); + dest = 0; /* force reg to zero */ + } +#endif + PSD1 = (PSD1 & 0xff000000) | (addr & 0xfffffe); /* set new PC */ + if (((MODES & BASEBIT) == 0) && (IR & IND)) /* see if CCs from last indirect wanted */ + PSD1 = (PSD1 & 0x87fffffe) | CC; /* insert last CCs */ + i_flags |= BT; /* we branched, so no PC update */ +/*FIX F77*/ if ((MODES & (BASEBIT|EXTDBIT)) == 0) /* see if basemode */ +/*FIX F77*/ PSD1 &= 0xff07ffff; /* only 19 bit address allowed */ + } + break; + + case 0xF8>>2: /* 0xF8 SM|ADR - SM|ADR */ /* ZMx, BL, BRI, LPSD, LPSDCM, TPR, TRP */ + switch((opr >> 7) & 0x7) { /* use bits 6-8 to determine instruction */ + case 0x0: /* ZMx F80x */ /* SM */ + dest = 0; /* destination value is zero */ + i_flags |= SM; /* SM not set so set it to store value */ + break; + case 0x1: /* BL F880 */ + /* copy CC's from instruction and PC incremented by 4 */ + GPR[0] = ((PSD1 & 0xff000000) | ((PSD1 + 4) & 0xfffffe)); + if (((MODES & BASEBIT) == 0) && (IR & IND)) /* see if CCs from last indirect wanted */ + PSD1 = (PSD1 & 0x87fffffe) | CC; /* insert last CCs */ + /* update the PSD with new address */ + if (MODES & BASEBIT) + PSD1 = (PSD1 & 0xff000000) | (addr & 0xfffffe); /* bit 8-30 */ + else + PSD1 = (PSD1 & 0xff000000) | (addr & 0x07fffe); /* bit 13-30 */ + i_flags |= BT; /* we branched, so no PC update */ +/*FIX F77*/ if ((MODES & (BASEBIT|EXTDBIT)) == 0) /* see if basemode */ +/*FIX F77*/ PSD1 &= 0xff07ffff; /* only 19 bit address allowed */ + break; + + case 0x3: /* LPSD F980 */ + /* fall through */; + case 0x5: /* LPSDCM FA80 */ + irq_pend = 1; /* start scanning interrupts again */ + if ((MODES & PRIVBIT) == 0) { /* must be privileged */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* Privlege violation trap */ + } + CPUSTATUS |= BIT25; /* enable software traps */ + /* this will allow attn and */ + /* power fail traps */ + if ((FC & 04) != 0 || FC == 2) { /* can not be byte or doubleword */ + /* Fault */ + TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC12 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + if ((TRAPME = Mem_read(addr, &temp))) { /* get PSD1 from memory */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + TRAPSTATUS |= BIT7; /* set bit 7 of trap status */ + } else + TRAPSTATUS |= BIT18; /* set bit 18 of trap status */ + goto newpsd; /* memory read error or map fault */ + } + bc = CPUSTATUS; /* save the CPU STATUS */ + TPSD[0] = PSD1; /* save the PSD for the instruction */ + TPSD[1] = PSD2; + t = MODES; /* save modes too */ + ix = SPAD[0xf5]; /* save the current PSD2 */ + reg = irq_pend; /* save intr status */ + + if ((TRAPME = Mem_read(addr+4, &temp2))) { /* get PSD2 from memory */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + TRAPSTATUS |= BIT7; /* set bit 7 of trap status */ + } else + TRAPSTATUS |= BIT18; /* set bit 18 of trap status */ + goto newpsd; /* memory read error or map fault */ + } + if (opr & 0x0200) { /* Was it LPSDCM? */ + /* LPSDCM */ + PSD2 = temp2 & 0xfffffff8; /* PSD2 access good, clean & save it */ + } else { + /* LPSD */ + /* lpsd can not change cpix, so keep it */ + PSD2 = ((PSD2 & 0x3ff8) | (temp2 & 0xffffc000)); /* use current cpix */ + } + PSD1 = temp; /* PSD1 good, so set it */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "LPSD(CM) load [%06x] New PSD1 %08x %08x OPSD2 %08x SPAD %08x CPUSTATUS %08x\n", + addr, PSD1, PSD2, TPSD[1], ix, CPUSTATUS); +#ifdef MPXTEST + for (ii=0; ii<8; ii+=4) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "LPSD(CM) GPR[%d] %.8x GPR[%d] %.8x GPR[%d] %.8x GPR[%d] %.8x\n", + ii, GPR[ii], ii+1, GPR[ii+1], ii+2, GPR[ii+2], ii+3, GPR[ii+3]); + } + /* DYNAMIC 05282021 */ +#endif + /* set the mode bits and CCs from the new PSD */ + CC = PSD1 & 0x78000000; /* extract bits 1-4 from PSD1 */ + MODES = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ + CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */ + CPUSTATUS |= MODES; /* now insert into CPUSTATUS */ + + /* set new map mode and interrupt blocking state in CPUSTATUS */ + if (PSD2 & MAPBIT) { + CPUSTATUS |= BIT8; /* set bit 8 of cpu status */ + MODES |= MAPMODE; /* set mapped mode */ + } else { + CPUSTATUS &= ~BIT8; /* reset bit 8 of cpu status */ +/*TRY_01072022*/ MODES &= ~MAPMODE; /* reset mapped mode */ + } + + /* set interrupt blocking state */ + if ((PSD2 & RETBBIT) == 0) { /* is it retain blocking state */ + if (PSD2 & SETBBIT) { /* no, is it set blocking state */ + CPUSTATUS |= BIT24; /* yes, set blk state in cpu status bit 24 */ + MODES |= BLKMODE; /* set blocked mode */ + } else { + CPUSTATUS &= ~BIT24; /* no, reset blk state in cpu status bit 24 */ + MODES &= ~BLKMODE; /* reset blocked mode */ + irq_pend = 1; /* start scanning interrupts again */ +#ifdef LEAVE_ACTIVE + if (irq_auto) { +/*AIR*/ INTS[irq_auto] &= ~INTS_ACT; /* deactivate specified int level */ +/*AIR*/ SPAD[irq_auto+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "<|>IntX deactivate level %02x at LPSD(CM) %08x %08x R[3] %08x\n", + irq_auto, PSD1, PSD2, GPR[3]); +/*AIR*/ irq_auto = 0; /* show done processing in blocked mode */ +#ifdef DYNAMIC_DEBUG_01172021 + cpu_dev.dctrl &= ~DEBUG_INST; /* end instruction trace */ +#endif + } +#endif + } + } else { + /* set new blocking state in PSD2 */ + PSD2 &= ~(SETBBIT|RETBBIT); /* clear bit 48 & 49 to be unblocked */ + MODES &= ~(BLKMODE|RETBLKM); /* reset blocked & retain mode bits */ + if (bc & BIT24) { /* see if old mode is blocked */ + PSD2 |= SETBBIT; /* set to blocked state */ + MODES |= BLKMODE; /* set blocked mode */ + } + } + +#ifdef MPXTEST /* set to 1 for traceme to work */ + /* get current MPX task name */ + { + int j; + char n[9]; + uint32 sq59 = M[0x930>>2]; /* get C.SQ59 headcell */ + uint32 dqe = M[0x8e8>>2]; /* get DQE of current task */ + if (sq59 != 0x930) + goto skipdqe; /* not running on mpx, skip */ + for (j=0; j<8; j++) { /* get the task name */ + n[j] = (M[((dqe+0x18)>>2)+(j/4)] >> ((3-(j&7))*8)) & 0xff; + if (n[j] == 0) + n[j] = 0x20; + } + n[8] = 0; +#if 0 +#if DYNAMIC_DEBUG + if (dqe == 0x56e0) { + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ + } +#endif +#endif + if (opr & 0x0200) { /* Was it LPSDCM? */ +sim_debug(DEBUG_IRQ, &cpu_dev, + "LPSDCM OPSD %.8x %.8x NPSD %.8x %.8x SPDF5 %.8x DQE %x LMN %8s\n", + TPSD[0], TPSD[1], PSD1, PSD2, SPAD[0xf5], dqe, n); +sim_debug(DEBUG_IRQ, &cpu_dev, + " R0=%.8x R1=%.8x R2=%.8x R3=%.8x\n", GPR[0], GPR[1], GPR[2], GPR[3]); +sim_debug(DEBUG_IRQ, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + } else { +sim_debug(DEBUG_IRQ, &cpu_dev, + "LPSD OPSD %.8x %.8x NPSD %.8x %.8x SPDF5 %.8x DQE %x LMN %8s\n", + TPSD[0], TPSD[1], PSD1, PSD2, SPAD[0xf5], dqe, n); +sim_debug(DEBUG_IRQ, &cpu_dev, + " R0=%.8x R1=%.8x R2=%.8x R3=%.8x\n", GPR[0], GPR[1], GPR[2], GPR[3]); +sim_debug(DEBUG_IRQ, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + } +// cpu_dev.dctrl |= DEBUG_DETAIL; /* start instruction trace */ + } +skipdqe: +#else + if (opr & 0x0200) { /* Was it LPSDCM? */ +sim_debug(DEBUG_IRQ, &cpu_dev, + "LPSDCM OPSD %.8x %.8x NPSD %.8x %.8x SPDF5 %.8x CPUSTATUS %08x\n", + TPSD[0], TPSD[1], PSD1, PSD2, SPAD[0xf5], CPUSTATUS); +sim_debug(DEBUG_IRQ, &cpu_dev, + " R0=%.8x R1=%.8x R2=%.8x R3=%.8x\n", GPR[0], GPR[1], GPR[2], GPR[3]); +sim_debug(DEBUG_IRQ, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + } else { +sim_debug(DEBUG_IRQ, &cpu_dev, + "LPSD OPSD %.8x %.8x NPSD %.8x %.8x SPDF5 %.8x CPUSTATUS %08x\n", + TPSD[0], TPSD[1], PSD1, PSD2, SPAD[0xf5], CPUSTATUS); +sim_debug(DEBUG_IRQ, &cpu_dev, + " R0=%.8x R1=%.8x R2=%.8x R3=%.8x\n", GPR[0], GPR[1], GPR[2], GPR[3]); +sim_debug(DEBUG_IRQ, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + } +#endif + if (opr & 0x0200) { /* Was it LPSDCM? */ + /* map bit must be on to load maps */ + if (PSD2 & MAPBIT) { + /* set mapped mode in cpu status */ + CPUSTATUS |= BIT8; /* set bit 8 of cpu status */ +#ifdef LOOK_MAP_05272021 + sim_debug(DEBUG_IRQ, &cpu_dev, + "B4 LPSDCM temp %06x TPSD %08x %08x PSD %08x %08x\n", + temp, TPSD[0], TPSD[1], PSD1, PSD2); + sim_debug(DEBUG_IRQ, &cpu_dev, + "B4 LPSDCM BPIX %04x CPIX %04x CPIXPL %04x\n", + BPIX, CPIX, CPIXPL); + sim_debug(DEBUG_IRQ, &cpu_dev, + "B4 LPSDCM OS MAPC[0-7] %08x %08x %08x %08x %08x %08x %08x %08x\n", + MAPC[0], MAPC[1], MAPC[2], MAPC[3], MAPC[4], MAPC[5], MAPC[6], MAPC[7]); + sim_debug(DEBUG_IRQ, &cpu_dev, + "B4 LPSDCM US MAPC[%x-%x] %08x %08x %08x %08x %08x %08x %08x %08x\n", + BPIX, BPIX+5, MAPC[BPIX], MAPC[BPIX+1], MAPC[BPIX+2], + MAPC[BPIX+3], MAPC[BPIX+4], MAPC[BPIX+5], + MAPC[BPIX+6], MAPC[BPIX+7]); +#endif + /* this mod fixes MPX 1.X 1st swapr load */ + /* any O/S or user maps yet? */ + if (((CPIX != 0) && (CPIXPL == 0)) && (PSD2 & RETMBIT)) { + PSD2 &= ~RETMBIT; /* no, turn off retain bit in PSD2 */ + sim_debug(DEBUG_EXP, &cpu_dev, "Turn off retain bit\n"); + } + + /* test if user count is equal to CPIXPL, if not load maps */ + /* this fixes software error in MPX3X where count is changed */ + /* but the retain bit was left set, so new maps were not loaded */ + /* until the next context switch and causes loading error */ + /* CHANGED 041420 maybe not right */ + if ((PSD2 & RETMBIT)) { /* don't load maps if retain bit set */ + uint32 mpl = SPAD[0xf3]; /* get mpl from spad address */ + uint32 cpix = PSD2 & 0x3ff8; /* get cpix 11 bit offset from psd wd 2 */ + uint32 midl = RMW(mpl+cpix); /* get midl entry for given user cpix */ + uint32 spc = midl & MASK16; /* get 16 bit user segment description count */ +#ifdef TRY_TEST_05182021 + /* output O/S and User MPL entries */ + sim_debug(DEBUG_EXP, &cpu_dev, + "#LPSDCM MEM %06x MPL %06x MPL[0] %08x %06x MPL[%04x] %08x %06x\n", + MEMSIZE, mpl, RMW(mpl), RMW(mpl+4), cpix, + RMW(cpix+mpl), RMW(cpix+mpl+4)); + sim_debug(DEBUG_EXP, &cpu_dev, + "#LPSDCM2 MEM %06x BPIX %04x cpix %04x CPIX %04x CPIXPL %04x HIWM %04x\n", + MEMSIZE, BPIX, cpix, CPIX, CPIXPL, HIWM); +#endif + /* if this code is not present, MPX3X will not boot correctly */ + if (spc != CPIXPL) { + PSD2 &= ~RETMBIT; /* no, turn off retain bit in PSD2 */ + } + /* if this code is not present MPX3X will abort */ + /* when trying to mount a secondary disk */ + else + { + if ((CPU_MODEL == MODEL_67) || (CPU_MODEL == MODEL_97) || + (CPU_MODEL == MODEL_V6) || (CPU_MODEL == MODEL_V9)) { + PSD2 &= ~RETMBIT; /* no, turn off retain bit in PSD2 */ + } + } + sim_debug(DEBUG_IRQ, &cpu_dev, + "LPSDCM FIX MAP TRAPME %02x PSD1 %08x PSD2 %08x spc %02x BPIX %02x CPIXPL %02x retain %01x\n", + TRAPME, PSD1, PSD2, spc, BPIX, CPIXPL, PSD2&RETMBIT?1:0); + } + + if ((PSD2 & RETMBIT) == 0) { /* don't load maps if retain bit set */ + /* we need to load the new maps */ + TRAPME = load_maps(PSD, 0); /* load maps for new PSD */ +#ifdef LOOK_MAP_05272021 + sim_debug(DEBUG_IRQ, &cpu_dev, + "AF LPSDCM TPSD %08x %08x PSD %08x %08x TRAPME %02x\n", + TPSD[0], TPSD[1], PSD1, PSD2, TRAPME); + sim_debug(DEBUG_IRQ, &cpu_dev, + "AF LPSDCM BPIX %04x CPIX %04x CPIXPL %04x\n", + BPIX, CPIX, CPIXPL); + sim_debug(DEBUG_IRQ, &cpu_dev, + "AF LPSDCM OS MAPC[0-7] %08x %08x %08x %08x %08x %08x %08x %08x\n", + MAPC[0], MAPC[1], MAPC[2], MAPC[3], MAPC[4], MAPC[5], MAPC[6], MAPC[7]); + sim_debug(DEBUG_IRQ, &cpu_dev, + "AF LPSDCM US MAPC[%x-%x] %08x %08x %08x %08x %08x %08x %08x %08x\n", + BPIX, BPIX+5, MAPC[BPIX], MAPC[BPIX+1], MAPC[BPIX+2], + MAPC[BPIX+3], MAPC[BPIX+4], MAPC[BPIX+5], + MAPC[BPIX+6], MAPC[BPIX+7]); +#endif + } + PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "LPSDCM MAPS LOADED TRAPME %02x PSD1 %08x PSD2 %08x BPIX %02x CPIXPL %02x retain %01x\n", + TRAPME, PSD1, PSD2, BPIX, CPIXPL, PSD2&RETMBIT?1:0); + } + PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ + } else { + /* LPSD */ + /* if cpix is zero, copy cpix from PSD2 in SPAD[0xf5] */ + if ((PSD2 & 0x3ff8) == 0) { + PSD2 |= (SPAD[0xf5] & 0x3ff8); /* use new cpix */ + } + } + /* TRAPME can be error from LPSDCM or OK here */ + if (TRAPME) { /* if we have an error, restore old PSD */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "LPSDCM MAPS2 LOADED TRAPME = %02x PSD1 %08x PSD2 %08x CPUSTAT %08x SPAD[f9] %08x\n", + TRAPME, PSD1, PSD2, CPUSTATUS, SPAD[0xf9]); + PSD1 = TPSD[0]; /* restore PSD1 */ + /* HACK HACK HACK */ + /* Diags wants the new PSD2, not the original??? */ + /* if old one was used, we fail test 21/0 in cn.mmm for 32/67 */ + CPUSTATUS = bc; /* restore the CPU STATUS */ + MODES = t; /* restore modes too */ + SPAD[0xf5] = ix; /* restore the current PSD2 to SPAD */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + irq_pend = reg; /* restore intr status */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { + TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ + TRAPSTATUS |= BIT7; /* set bit 7 of trap status */ + } else + TRAPSTATUS |= BIT18; /* set bit 18 of trap status */ + goto newpsd; /* go process error */ + } + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + drop_nop = 0; /* nothing to drop */ + goto newpsd; /* load the new psd, or process error */ + break; + + case 0x4: /* JWCS */ /* not used in simulator */ + sim_debug(DEBUG_EXP, &cpu_dev, "Got JWCS\n"); + break; + case 0x2: /* BRI */ /* TODO - only for 32/55 or 32/7X in PSW mode */ + case 0x6: /* TRP */ + case 0x7: /* TPR */ + TRAPME = UNDEFINSTR_TRAP; /* trap condition */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* undefined instruction trap */ + break; + } + break; + +/* F Class I/O device instruction format */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* |00 01 02 03 04 05|06 07 08|09 10 11 12|13 14 15|16|17 18 19 20 21 22 23|24 25 26 27 28 29 30 31| */ +/* | Op Code | Reg | I/O type | Aug |0 | Channel Address | Device Sub-address | */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* */ +/* E Class I/O device instruction format */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* |00 01 02 03 04 05|06 07 08 09 10 11 12|13 14 15|16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31| */ +/* | Op Code | Device Number | Aug | Command Code | */ +/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ +/* */ + case 0xFC>>2: /* 0xFC IMM - IMM */ /* XIO, CD, TD, Interrupt Control */ +#ifdef MAYBE_NO + irq_pend = 1; /* start scanning interrupts again */ +#endif + if ((MODES & PRIVBIT) == 0) { /* must be privileged to do I/O */ + TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + else + TRAPSTATUS |= BIT19; /* set bit 19 of trap status */ + goto newpsd; /* Privlege violation trap */ + } + if ((opr & 0x7) != 0x07) { /* aug is 111 for XIO instruction */ + /* Process Non-XIO instructions */ + uint32 status = 0; /* status returned from device */ + uint32 device = (opr >> 3) & 0x7f; /* get device code */ + uint32 prior = device; /* interrupt priority */ + uint32 maxlev = 0x5f; /* max lev for all but 32/27 in diags */ +//MAYBEBAD uint32 maxlev = 0x6f; /* max lev for all but 32/27 in diags */ + + t = SPAD[prior+0x80]; /* get spad entry for interrupt */ + addr = SPAD[0xf1] + (prior<<2); /* vector address in SPAD */ + addr = M[addr>>2]; /* get the interrupt context block addr */ + prior = (opr >> 3) & 0x7f; /* get priority level */ + if (CPU_MODEL <= MODEL_27) { + maxlev = 0x6f; /* 27 uses 112 */ + } + + switch(opr & 0x7) { /* use bits 13-15 to determine instruction */ + case 0x0: /* EI FC00 Enable Interrupt */ + if (prior > maxlev) /* ignore for invalid levels */ + break; /* ignore */ + /* SPAD entries for interrupts begin at 0x80 */ + t = SPAD[prior+0x80]; /* get spad entry for interrupt */ + if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */ + break; /* ignore */ + + if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */ + break; /* ignore for F class */ + + /* does not effect REQ status */ + INTS[prior] |= INTS_ENAB; /* enable specified int level */ + SPAD[prior+0x80] |= SINT_ENAB; /* enable in SPAD too */ + irq_pend = 1; /* start scanning interrupts again */ + +#ifdef TRY_ME_01072022 + sim_debug(DEBUG_IRQ, &cpu_dev, + "EI skipinstr %d PSD1 %08x irq_pend %d wait4int %d irq_auto %x\n", + skipinstr, PSD1, irq_pend, wait4int, irq_auto); + sim_debug(DEBUG_IRQ, &cpu_dev, + "EI INTS[%d] = %08x SPAD[%d] %08x CPUSTATUS %08x\n", + prior, INTS[prior], 0x80+prior, SPAD[prior+0x80], CPUSTATUS); +#endif + /* test for clock at address 0x7f06 and interrupt level 0x18 */ + /* the diags want the type to be 0 */ + /* UTX wants the type to be 3?? */ + /* UTX would be 0x03807f06 Diags would be 0x00807f06 */ + if ((SPAD[prior+0x80] & 0x0000ffff) == 0x00007f06) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "Clock EI %02x SPAD %08x Turn on\n", prior, t); + rtc_setup(1, prior); /* tell clock to start */ + } + /* the diags want the type to be 3 */ + if ((SPAD[prior+0x80] & 0x0f00ffff) == 0x03007f04) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "Intv Timer EI %02x SPAD %08x Turn on\n", prior, t); + itm_setup(1, prior); /* tell timer to start */ +#ifdef DO_DYNAMIC_INSTR + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ +#endif + } + break; + + case 0x1: /* DI FC01 */ + if (prior > maxlev) /* ignore for invalid levels */ + break; /* ignore */ + /* SPAD entries for interrupts begin at 0x80 */ + t = SPAD[prior+0x80]; /* get spad entry for interrupt */ + + if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */ + break; /* ignore */ + + if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */ + break; /* ignore for F class */ + + /* active state is left alone */ + INTS[prior] &= ~INTS_ENAB; /* disable specified int level */ + SPAD[prior+0x80] &= ~SINT_ENAB; /* disable in SPAD too */ + INTS[prior] &= ~INTS_REQ; /* clears any requests also */ + irq_pend = 1; /* start scanning interrupts again */ + + /* test for clock at address 0x7f06 and interrupt level 0x18 */ + /* the diags want the type to be 0 */ + /* UTX wants the type to be 3?? */ + /* UTX would be 0x03807f06 Diags would be 0x00807f06 */ + if ((SPAD[prior+0x80] & 0x0000ffff) == 0x00007f06) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "Clock DI %02x SPAD %08x Turn off\n", prior, t); + rtc_setup(0, prior); /* tell clock to stop */ + } + /* the diags want the type to be 3 */ + if ((SPAD[prior+0x80] & 0x0f00ffff) == 0x03007f04) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "Intv Timer DI %02x SPAD %08x Turn off\n", prior, t); +#ifdef DO_DYNAMIC_INSTR + cpu_dev.dctrl &= ~DEBUG_INST; /* stop instruction trace */ +#endif + itm_setup(0, prior); /* tell timer to stop */ + } + break; + + case 0x2: /* RI FC02 */ + if (prior > maxlev) /* ignore for invalid levels */ + break; /* ignore */ + /* SPAD entries for interrupts begin at 0x80 */ + t = SPAD[prior+0x80]; /* get spad entry for interrupt */ + if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */ + break; /* ignore */ + + if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */ + break; /* ignore for F class */ + + INTS[prior] |= INTS_REQ; /* set the request flag for this level */ + irq_pend = 1; /* start scanning interrupts again */ + break; + + case 0x3: /* AI FC03 */ + if (prior > maxlev) /* ignore for invalid levels */ + break; /* ignore */ + /* SPAD entries for interrupts begin at 0x80 */ + t = SPAD[prior+0x80]; /* get spad entry for interrupt */ + if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */ + break; /* ignore */ + + if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */ + break; /* ignore for F class */ + + INTS[prior] |= INTS_ACT; /* activate specified int level */ + SPAD[prior+0x80] |= SINT_ACT; /* activate in SPAD too */ + irq_pend = 1; /* start scanning interrupts again */ + break; + + case 0x4: /* DAI FC04 */ + if (prior > maxlev) /* ignore for invalid levels */ + break; /* ignore */ + /* SPAD entries for interrupts begin at 0x80 */ + t = SPAD[prior+0x80]; /* get spad entry for interrupt */ + if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */ + break; /* ignore */ + + if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */ + break; /* ignore for F class */ + + sim_debug(DEBUG_IRQ, &cpu_dev, + "DAI spad %08x INTS[%02x] %08x\n", t, prior, INTS[prior]); + INTS[prior] &= ~INTS_ACT; /* deactivate specified int level */ + SPAD[prior+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ + irq_pend = 1; /* start scanning interrupts again */ + /* instruction following a DAI can not be interrupted */ + /* skip tests for interrupts if this is the case */ + skipinstr = 1; /* skip interrupt test */ +#ifdef DO_DYNAMIC_DEBUG + /* test for DAI 0x03 */ + if ((prior == 3) && (GPR[5] == 0xfc1c0000) && (GPR[6] == 0x44a4)) { + cpu_dev.dctrl |= (DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */ + con_dev.dctrl |= DEBUG_XIO|DEBUG_CMD; + sim_debug(DEBUG_IRQ, &cpu_dev, "DAI 0x03 received start debug\n"); + } + if ((prior == 0x0a) && (GPR[5] == 0xfc540000)) { /* test for DAI 0x0A */ + /* turn off debug trace because we are already hung */ + sim_debug(DEBUG_IRQ, &cpu_dev, "DAI 0x0A received stopping debug\n"); + cpu_dev.dctrl &= ~(DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */ + con_dev.dctrl &= ~(DEBUG_XIO|DEBUG_CMD); + } +#endif + break; + + case 0x5: /* TD FC05 */ /* bits 13-15 is test code type */ + case 0x6: /* CD FC06 */ + /* If CD or TD, make sure device is not F class device */ + /* the channel must be defined as a non class F I/O channel in SPAD */ + /* if class F, the system will generate a system check trap */ + t = SPAD[device]; /* get spad entry for channel */ + if ((t & 0x0f000000) == 0x0f000000) { /* class in bits 4-7 */ + TRAPME = SYSTEMCHK_TRAP; /* trap condition if F class */ + TRAPSTATUS &= ~BIT0; /* class E error bit */ + TRAPSTATUS &= ~BIT1; /* I/O processing error */ + goto newpsd; /* machine check trap */ + } + /* t has spad entry for device */ + /* get the 1's comp of interrupt address from bits 9-15 SPAD entry */ + ix = ((~t)>>16)&0x7f; /* get positive number for interrupt */ + if (opr & 0x1) { /* see if CD or TD */ + /* TODO process a TD */ + if (device == 0x7f) { + /* if this is for the interval timer check cmd type */ + /* if TD 8000 or 4000, set all cc's zero */ + temp = (IR & 0xf000); /* get cmd from instruction */ + if ((temp == 0x4000) || (temp == 0x8000)) + status = 0; /* no CC's */ + else + /* if TD 2000 set CC2 for caller */ + if (temp == 0x2000) + status = CC2BIT; /* set CC2 */ + /* return status has new CC's in bits 1-4 of status word */ + /* insert status CCs */ + PSD1 = ((PSD1 & 0x87fffffe) | (status & 0x78000000)); + } else { +#if 0 + /* may want to handle class E someday */ + if ((TRAPME = testEIO(device, testcode, &status))) + goto newpsd; /* error returned, trap cpu */ + /* return status has new CC's in bits 1-4 of status word */ + /* insert status CCs */ + PSD1 = ((PSD1 & 0x87fffffe) | (status & 0x78000000)); +#endif + goto inv; /* invalid instruction until I fix it */ + } + } else { + /* TODO process a CD */ +#if 0 + if ((TRAPME = startEIO(device, &status))) + goto newpsd; /* error returned, trap cpu */ +#endif + if (device == 0x7f) { + temp = (IR & 0x7f); /* get cmd from instruction */ + status = itm_rdwr(temp, GPR[0], ix); /* read/write the interval timer */ + /* see if the cmd does not return value */ + /* if bit 25 set, read reg val into R0 */ + if (temp & 0x40) + GPR[0] = status; /* return count in reg 0 */ + /* No CC's going out */ + } else { + goto inv; /* invalid instruction until I fix it */ + } + } + break; + case 0x7: /* XIO FC07*/ /* should never get here */ + break; + } + break; /* skip over XIO code */ + } + + /* Process XIO instructions */ + /* see if valid instruction */ + /* DIAGS wants this tested first */ + switch((opr >> 3) & 0xf) { /* use bits 9-12 to determine I/O instruction */ + case 0x00: /* Unassigned */ + case 0x01: /* Unassigned */ + case 0x0A: /* Unassigned */ + TRAPME = UNDEFINSTR_TRAP; /* trap condition */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* undefined instruction trap */ + } + + /* if reg is non-zero, add reg to 15 bits from instruction */ + if (reg) + temp2 = (IR & 0x7fff) + (GPR[reg] & 0x7fff); /* set new chan/suba into IR */ + else + temp2 = (IR & 0x7fff); /* set new chan/suba into IR */ + lchan = (temp2 & 0x7F00) >> 8; /* get 7 bit logical channel address */ + suba = temp2 & 0xFF; /* get 8 bit subaddress */ + lchsa = (lchan << 8) | suba; /* logical address */ + /* the channel must be defined as a class F I/O channel in SPAD */ + /* if not class F, the system will generate a system check trap */ + t = SPAD[lchan]; /* get spad entry for channel */ + if ((t == 0) || ((t&MASK24) == MASK24) || /* if not set up, system check */ + ((t & 0x0f800000) != 0x0f000000)) { /* class in bits 4-7 */ + TRAPME = SYSTEMCHK_TRAP; /* trap condition if F class */ + TRAPSTATUS |= BIT0; /* class F error bit */ + TRAPSTATUS &= ~BIT1; /* I/O processing error */ + goto newpsd; /* undefined instruction trap */ + } + /* get real channel from spad device entry */ + chan = (t & 0x7f00) >> 8; /* real channel */ + rchsa = (chan << 8) | suba; /* real ch & sa */ + /* get the 1's comp of interrupt address from bits 9-15 SPAD entry */ + ix = ((~t)>>16)&0x7f; /* get positive number for interrupt */ + bc = SPAD[ix+0x80]; /* get interrupt spad entry for channel */ + /* SPAD address F1 has interrupt table address */ + temp = SPAD[0xf1] + (ix<<2); /* vector address in SPAD */ + sim_debug(DEBUG_XIO, &cpu_dev, + "$$ XIO chsa %04x spad %08x BLK %1x INTS[%02x] %08x\n", + rchsa, t, CPUSTATUS&0x80?1:0, ix, INTS[ix]); + sim_debug(DEBUG_XIO, &cpu_dev, + "$$ XIO chsa %04x PSD1 %08x PSD2 %08x IR %08x ICBA %06x\n", + rchsa, PSD1, PSD2, IR, temp); + if ((TRAPME = Mem_read(temp, &addr))) { /* get interrupt context block addr */ +mcheck: + /* machine check if not there */ + TRAPME = MACHINECHK_TRAP; /* trap condition */ + TRAPSTATUS |= BIT0; /* class F error bit */ + TRAPSTATUS &= ~BIT1; /* I/O processing error */ + goto newpsd; /* machine check trap */ + } + /* the context block contains the old PSD, */ + /* new PSD, IOCL address, and I/O status address */ + if ((addr == 0) || (addr == 0xffffffff)) { /* must be initialized address */ + goto mcheck; /* bad int icb address */ + } + if ((TRAPME = Mem_read(addr+16, &temp))) { /* get iocl address from icb wd 4 */ + goto mcheck; /* machine check if not there */ + } + /* iocla must be valid addr if it is a SIO instruction */ + if (((temp & MASK24) == 0) && (((opr >> 2) & 0xf) == 2)) { + goto mcheck; /* bad iocl address */ + } + + sim_debug(DEBUG_XIO, &cpu_dev, + "XIO rdy PSD1 %08x chan %02x irq %02x icb %06x iocla %06x iocd %08x %08x\n", + PSD1, chan, ix, addr, addr+16, RMW(temp), RMW(temp+4)); + /* at this point, the channel has a valid SPAD channel entry */ + /* t is SPAD entry contents for chan device */ + /* temp2 has logical channel address */ + /* lchan - logical channel address */ + /* lchsa - logical channel & subaddress */ + /* chan - channel address */ + /* suba - channel device subaddress */ + /* rchsa - real chan & sub address from spad for logical channel */ + /* ix - positive interrupt level */ + /* addr - ICBA for specified interrupt level, points to 6 wd block */ + /* temp - First IOCD address */ + sim_debug(DEBUG_XIO, &cpu_dev, + "XIO switch %02x lchan %02x irq %02x rchsa %04x IOCDa %08x CPUSTATUS %08x BLK %1x\n", + ((opr>>3)&0x0f), lchan, ix, rchsa, temp, CPUSTATUS, CPUSTATUS&0x80?1:0); + + switch((opr >> 3) & 0xf) { /* use bits 9-12 to determine I/O instruction */ + case 0x00: /* Unassigned */ + case 0x01: /* Unassigned */ + case 0x0A: /* Unassigned */ + TRAPME = UNDEFINSTR_TRAP; /* trap condition */ + if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) + TRAPSTATUS |= BIT0; /* set bit 0 of trap status */ + goto newpsd; /* undefined instruction trap */ + break; + + case 0x09: /* Enable write channel ECWCS */ + case 0x0B: /* Write channel WCS WCWCS */ + /* TODO, provide support code */ + /* for now or maybe forever, return unsupported transaction */ + PSD1 = ((PSD1 & 0x87fffffe) | (CC2BIT|CC4BIT)); /* insert status 5 */ + sim_debug(DEBUG_XIO, &cpu_dev, + "XIO unsupported WCS chan %04x chsa %04x status %08x\n", + chan, rchsa, rstatus); + /* just give unsupported transaction */ +#ifdef JUST_RETURN_STATUS + TRAPME = SYSTEMCHK_TRAP; /* trap condition if F class */ + TRAPSTATUS |= BIT0; /* class F error bit */ + TRAPSTATUS &= ~BIT1; /* I/O processing error */ + goto newpsd; /* undefined instruction trap */ +#endif + break; + + case 0x02: /* Start I/O SIO */ + sim_debug(DEBUG_XIO, &cpu_dev, + "SIO b4 call PSD1 %08x rchsa %04x lchsa %04x BLK %1x\n", + PSD1, rchsa, lchsa, CPUSTATUS&0x80?1:0); + if ((TRAPME = startxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + sim_debug(DEBUG_XIO, &cpu_dev, + "SIO ret PSD1 %08x chsa %04x status %08x BLK %1x\n", + PSD1, lchsa, rstatus, CPUSTATUS&0x80?1:0); + break; + + case 0x03: /* Test I/O TIO */ + if ((TRAPME = testxio(lchsa, &rstatus))) { + sim_debug(DEBUG_TRAP, &cpu_dev, + "TIO ret PSD1 %x rchsa %x lchsa %x status %x BLK %1x\n", + PSD1, rchsa, lchsa, rstatus, CPUSTATUS&0x80?1:0); + goto newpsd; /* error returned, trap cpu */ + } + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + sim_debug(DEBUG_XIO, &cpu_dev, + "TIO ret PSD1 %08x lchsa %04x stat %08x spad %08x INTS[%02x] %08x BLK %1x\n", + PSD1, lchsa, rstatus, t, ix, INTS[ix], CPUSTATUS&0x80?1:0); + break; + + case 0x04: /* Stop I/O STPIO */ + if ((TRAPME = stopxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + sim_debug(DEBUG_XIO, &cpu_dev, "STPIO ret rchsa %04x lchsa %04x status %08x\n", + rchsa, lchsa, rstatus); + break; + + case 0x05: /* Reset channel RSCHNL */ + if ((TRAPME = rschnlxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + /* SPAD entries for interrupts begin at 0x80 */ + INTS[ix] &= ~INTS_REQ; /* clears any requests */ + INTS[ix] &= ~INTS_ACT; /* deactivate specified int level */ + SPAD[ix+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + sim_debug(DEBUG_XIO, &cpu_dev, "RSCHNL rschnlxio ret rchsa %04x lchsa %04x status %08x\n", + rchsa, lchsa, rstatus); + break; + + case 0x06: /* Halt I/O HIO */ + if ((TRAPME = haltxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + sim_debug(DEBUG_XIO, &cpu_dev, + "HIO haltxio ret rchsa %04x lchsa %04x status %08x\n", + rchsa, lchsa, rstatus); + break; + + case 0x07: /* Grab controller GRIO n/u */ + if ((TRAPME = grabxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + sim_debug(DEBUG_XIO, &cpu_dev, "GRIO ret rchsa %04x lchsa %04x status %08x\n", + rchsa, lchsa, rstatus); + break; + + case 0x08: /* Reset controller RSCTL */ + if ((TRAPME = rsctlxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + sim_debug(DEBUG_XIO, &cpu_dev, "RSCTL ret rchsa %04x lchsa %04x status %08x\n", + rchsa, lchsa, rstatus); + break; + + case 0x0C: /* Enable channel interrupt ECI */ + /* disable int only */ + sim_debug(DEBUG_XIO, &cpu_dev, + "ECI chsa %04x lchsa %04x spad %08x INTS[%02x] %08x\n", + rchsa, lchsa, t, ix, INTS[ix]); + if ((TRAPME = checkxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + sim_debug(DEBUG_XIO, &cpu_dev, + "ECI after checkxio rchsa %04x suba %04x status %08x\n", + rchsa, suba, rstatus); + + if ((INTS[ix] & INTS_ACT) == 0) + sim_debug(DEBUG_XIO, &cpu_dev, + "ECI INT %02x is NOT set rchsa %04x lchsa %04x status %08x\n", + ix, rchsa, lchsa, rstatus); + /* SPAD entries for interrupts begin at 0x80 */ + INTS[ix] |= INTS_ENAB; /* enable specified int level */ + SPAD[ix+0x80] |= SINT_ENAB; /* enable in SPAD too */ + irq_pend = 1; /* start scanning interrupts again */ + /* return status of zero for present and functioning */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + break; + + case 0x0D: /* Disable channel interrupt DCI */ + /* disable int, leave req */ + sim_debug(DEBUG_XIO, &cpu_dev, + "DCI rchsa %04x lchsa %04x spad %08x INTS[%02x] %08x\n", + rchsa, lchsa, t, ix, INTS[ix]); + + if ((TRAPME = checkxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + sim_debug(DEBUG_XIO, &cpu_dev, + "DCI After checkxio call rstatus %08x\n", rstatus); + /* doc says we need to drop 1 queued status entry too */ + if ((INTS[ix] & INTS_ACT) == 0) + sim_debug(DEBUG_XIO, &cpu_dev, + "DCI INT %02x is NOT set rchsa %04x lchsa %04x status %08x\n", + ix, rchsa, lchsa, rstatus); + /* SPAD entries for interrupts begin at 0x80 */ + INTS[ix] &= ~INTS_ENAB; /* disable specified int level */ + SPAD[ix+0x80] &= ~SINT_ENAB; /* disable in SPAD too */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + break; + + case 0x0E: /* Activate channel interrupt ACI */ + /* Set int active, clear request */ + sim_debug(DEBUG_XIO, &cpu_dev, + "ACI rchsa %04x lchsa %04x spad %08x INTS[%02x] %08x\n", + rchsa, lchsa, t, ix, INTS[ix]); + + if ((TRAPME = checkxio(lchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + if ((INTS[ix] & INTS_ACT) == 0) + sim_debug(DEBUG_XIO, &cpu_dev, + "ACI INT %02x is NOT set rchsa %04x lchsa %04x status %08x\n", + ix, rchsa, lchsa, rstatus); + /* SPAD entries for interrupts begin at 0x80 */ + INTS[ix] |= INTS_ACT; /* activate specified int level */ + SPAD[ix+0x80] |= SINT_ACT; /* enable in SPAD too */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + break; + + case 0x0F: /* Deactivate channel interrupt DACI */ + /* Clear active and leave any request */ + /* Note, instruction following DACI is not interruptable */ + sim_debug(DEBUG_XIO, &cpu_dev, + "DACI rchsa %04x lchsa %04x spad %08x INTS[%02x] %08x\n", + rchsa, lchsa, t, ix, INTS[ix]); + + if ((TRAPME = checkxio(rchsa, &rstatus))) + goto newpsd; /* error returned, trap cpu */ + if ((INTS[ix] & INTS_ACT) == 0) + sim_debug(DEBUG_XIO, &cpu_dev, + "DACI INT %02x is NOT set chan %04x suba %04x status %08x\n", + ix, chan, suba, rstatus); + /* SPAD entries for interrupts begin at 0x80 */ + INTS[ix] &= ~INTS_ACT; /* deactivate specified int level */ + SPAD[ix+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ + irq_pend = 1; /* start scanning interrupts again */ + skipinstr = 1; /* skip interrupt test */ + PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ + sim_debug(DEBUG_XIO, &cpu_dev, + "DACI ret lchsa %04x status %08x spad %08x INTS[%02x] %08x BLK %1x\n", + lchsa, rstatus, t, ix, INTS[ix], CPUSTATUS&0x80?1:0); + break; + } /* end of XIO switch */ + break; + } /* End of Instruction Switch */ + + /* [*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*] */ + + /* any instruction with an arithmetic exception will still end up here */ + /* after the instruction is done and before incrementing the PC, */ + /* we will trap the cpu if ovl is set nonzero by an instruction */ + + /* Store result to register */ + if (i_flags & SD) { + if (dbl) { /* if double reg, store 2nd reg */ + if (reg & 1) { /* is it double regs into odd reg */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "ADDRSPEC13 OP %04x addr %08x\n", OP, addr); + goto newpsd; /* go execute the trap now */ + } + GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */ + GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */ + } else { + GPR[reg] = (uint32)(dest & FMASK); /* save the reg */ + } + } + + /* Store result to base register */ + if (i_flags & SB) { + if (dbl) { /* no dbl wd store to base regs */ + TRAPME = ADDRSPEC_TRAP; /* bad address, error */ + goto newpsd; /* go execute the trap now */ + } + BR[reg] = (uint32)(dest & FMASK); /* save the base reg */ + } + + /* Store result to memory */ + if (i_flags & SM) { + /* Check if byte of half word */ + if (((FC & 04) || (FC & 5) == 1)) { /* hw or byte requires read first */ + if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + goto newpsd; /* memory read error or map fault */ + } + } + switch(FC) { + case 2: /* double word store */ + if ((addr & 7) != 2) { + TRAPME = ADDRSPEC_TRAP; /* address not on dbl wd boundry, error */ + goto newpsd; /* go execute the trap now */ + } + temp = (uint32)(dest & MASK32);/* get lo 32 bit */ + if ((TRAPME = Mem_write(addr + 4, &temp))) + goto newpsd; /* memory write error or map fault */ + temp = (uint32)(dest >> 32); /* move upper 32 bits to lo 32 bits */ + break; + + case 0: /* word store */ + temp = (uint32)(dest & FMASK); /* mask 32 bit of reg */ + if ((addr & 3) != 0) { + /* Address fault */ + TRAPME = ADDRSPEC_TRAP; /* address not on wd boundry, error */ + goto newpsd; /* go execute the trap now */ + } + break; + + case 1: /* left halfword write */ + temp &= RMASK; /* mask out 16 left most bits */ + temp |= (uint32)(dest & RMASK) << 16; /* put into left most 16 bits */ + if ((addr & 1) != 1) { + /* Address fault */ + TRAPME = ADDRSPEC_TRAP; /* address not on hw boundry, error */ + goto newpsd; /* go execute the trap now */ + } + break; + + case 3: /* right halfword write */ + temp &= LMASK; /* mask out 16 right most bits */ + temp |= (uint32)(dest & RMASK); /* put into right most 16 bits */ + if ((addr & 3) != 3) { + TRAPME = ADDRSPEC_TRAP; /* address not on hw boundry, error */ + goto newpsd; /* go execute the trap now */ + } + break; + + case 4: + case 5: + case 6: + case 7: /* byte store operation */ + temp &= ~(0xFF << (8 * (7 - FC))); /* clear the byte to store */ + temp |= (uint32)(dest & 0xFF) << (8 * (7 - FC)); /* insert new byte */ + break; + } + /* store back the modified memory location */ + if ((TRAPME = Mem_write(addr, &temp))) /* store back to memory */ + goto newpsd; /* memory write error or map fault */ + } + + /* Update condition code registers */ + if (i_flags & SCC) { + PSD1 &= 0x87FFFFFE; /* clear the old CC's */ + if (ovr) /* if overflow, set CC1 */ + CC = CC1BIT; /* show we had AEXP */ + else + CC = 0; /* no CC's yet */ + if (dest & DMSIGN) /* if neg, set CC3 */ + CC |= CC3BIT; /* if neg, set CC3 */ + else if (dest == 0) + CC |= CC4BIT; /* if zero, set CC4 */ + else + CC |= CC2BIT; /* if gtr than zero, set CC2 */ + PSD1 |= CC & 0x78000000; /* update the CC's in the PSD */ + } + + /* check if we had an arithmetic exception on the last instruction*/ + if (ovr && (MODES & AEXPBIT)) { + TRAPME = AEXPCEPT_TRAP; /* trap the system now */ + goto newpsd; /* process the trap */ + } + + /* Update instruction pointer to next instruction */ + if ((i_flags & BT) == 0) { /* see if PSD was replaced on a branch instruction */ + /* branch not taken, so update the PC */ + if (EXM_EXR != 0) { /* special handling for EXM, EXR, EXRR */ + PSD1 = (PSD1 + 4) | (((PSD1 & 2) >> 1) & 1); + EXM_EXR = 0; /* reset PC increment for EXR */ + } else + if (i_flags & HLF) { /* if nop in rt hw, bump pc a word */ + if ((drop_nop) && ((CPU_MODEL == MODEL_67) || (CPU_MODEL == MODEL_V6))) + { + PSD1 = (PSD1 + 4) | (((PSD1 & 2) >> 1) & 1); + } else { + PSD1 = (PSD1 + 2) | (((PSD1 & 2) >> 1) & 1); + } + } else { + PSD1 = (PSD1 + 4) | (((PSD1 & 2) >> 1) & 1); + } + drop_nop = 0; /* no NOP to drop */ + } else { + EXM_EXR = 0; /* reset PC increment for EXR */ + drop_nop = 0; /* no NOP to drop */ + } + + OPSD1 &= 0x87FFFFFE; /* clear the old CC's */ + OPSD1 |= PSD1 & 0x78000000; /* update the CC's in the PSD */ + /* TODO Update other history information for this instruction */ + if (hst_lnt) { + hst[hst_p].opsd1 = OPSD1; /* update the CC in opsd1 */ + hst[hst_p].npsd1 = PSD1; /* save new psd1 */ + hst[hst_p].npsd2 = PSD2; /* save new psd2 */ + hst[hst_p].modes = MODES; /* save current mode bits */ + hst[hst_p].modes |= (CPUSTATUS & BIT24); /* save blocking mode bit */ + for (ix=0; ix<8; ix++) { + hst[hst_p].reg[ix] = GPR[ix]; /* save reg */ + hst[hst_p].reg[ix+8] = BR[ix]; /* save breg */ + } + } + + /* DEBUG_INST support code */ + /* output mapped/unmapped */ + if (MODES & BASEBIT) + BM = 'B'; + else + BM = 'N'; + if (MODES & MAPMODE) + MM = 'M'; + else + MM = 'U'; + if (CPUSTATUS & BIT24) + BK = 'B'; + else + BK = 'U'; + sim_debug(DEBUG_INST, &cpu_dev, "%c%c%c %.8x %.8x %.8x ", + BM, MM, BK, OPSD1, PSD2, OIR); + if (cpu_dev.dctrl & DEBUG_INST) { + fprint_inst(sim_deb, OIR, 0); /* display instruction */ + sim_debug(DEBUG_INST, &cpu_dev, + "\n\tR0=%.8x R1=%.8x R2=%.8x R3=%.8x", GPR[0], GPR[1], GPR[2], GPR[3]); + sim_debug(DEBUG_INST, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + if (MODES & BASEBIT) { + sim_debug(DEBUG_INST, &cpu_dev, + "\tB0=%.8x B1=%.8x B2=%.8x B3=%.8x", BR[0], BR[1], BR[2], BR[3]); + sim_debug(DEBUG_INST, &cpu_dev, + " B4=%.8x B5=%.8x B6=%.8x B7=%.8x\n", BR[4], BR[5], BR[6], BR[7]); + } + } +#ifdef BAD_02102022 + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ +#endif + continue; /* keep running */ + +newpsd: +#ifndef BAD_02102022 + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ +#endif + /* Trap Context Block - 6 words */ + /* WD1 Old PSD Wd 1 */ + /* WD2 Old PSD Wd 2 */ + /* WD3 New PSD WD 1 */ + /* WD4 New PSD Wd 2 */ + /* WD5 Multi Use */ /* N/U for Interrupts */ + /* WD6 Multi Use */ /* N/U for Interrupts */ + + /* WD5 Multi Use */ /* IOCL address for I/O */ + /* WD6 Multi Use */ /* Status address for I/O */ + + /* WD5 Multi Use */ /* Secondary vector table for SVC */ + /* WD6 Multi Use */ /* N/U for SVC */ + + /* WD5 Multi Use */ /* Trap status word for traps */ + /* WD6 Multi Use */ /* N/U for traps */ + + /* WD5 Multi Use */ /* Trap status word for page faults */ + /* WD6 Multi Use */ /* Page fault status word */ + /* Bit 0 = 0 The map fault was caused by an instruction fetch */ + /* = 1 The mp fault was caused by an operand access */ + /* Bits 1-20 Always zero */ + /* Map register number (logical map block number) */ + + /* we get here from a LPSD, LPSDCM, INTR, or TRAP */ + if (TRAPME) { + /* SPAD location 0xf0 has trap vector base address */ + uint32 tta = SPAD[0xf0]; /* get trap table address in memory */ + uint32 tvl; /* trap vector location */ + if ((tta == 0) || ((tta&MASK24) == MASK24)) + tta = 0x80; /* if not set, assume 0x80 FIXME */ + /* Trap Table Address in memory is pointed to by SPAD 0xF0 */ + /* TODO update cpu status and trap status words with reason too */ + switch(TRAPME) { + case POWERFAIL_TRAP: /* 0x80 PL00/PL01 power fail trap */ + case POWERON_TRAP: /* 0x84 PL00/PL01 Power-On trap */ + case MEMPARITY_TRAP: /* 0x88 PL02 Memory Parity Error trap */ + case NONPRESMEM_TRAP: /* 0x8C PL03 Non Present Memory trap */ + case UNDEFINSTR_TRAP: /* 0x90 PL04 Undefined Instruction Trap */ + case PRIVVIOL_TRAP: /* 0x94 PL05 Privlege Violation Trap */ +//MOVED case SVCCALL_TRAP: /* 0x98 PL06 Supervisor Call Trap */ + case MACHINECHK_TRAP: /* 0x9C PL07 Machine Check Trap */ + case SYSTEMCHK_TRAP: /* 0xA0 PL08 System Check Trap */ + case MAPFAULT_TRAP: /* 0xA4 PL09 Map Fault Trap */ + case IPUUNDEFI_TRAP: /* 0xA8 PL0A IPU Undefined Instruction Trap */ +//MOVED case CALM_TRAP: /* 0xA8 PL0A Call Monitor Instruction Trap */ + case SIGNALIPU_TRAP: /* 0xAC PL0B Signal IPU/CPU Trap */ + case ADDRSPEC_TRAP: /* 0xB0 PL0C Address Specification Trap */ +//BAD HERE case CONSOLEATN_TRAP: /* 0xB4 PL0D Console Attention Trap */ + case PRIVHALT_TRAP: /* 0xB8 PL0E Privlege Mode Halt Trap */ + case AEXPCEPT_TRAP: /* 0xBC PL0F Arithmetic Exception Trap */ + case CACHEERR_TRAP: /* 0xC0 PL10 Cache Error Trap (V9 Only) */ + /* drop through */ + default: + sim_debug(DEBUG_TRAP, &cpu_dev, + "##TRAPME %02x LOAD MAPS PSD1 %08x PSD2 %08x CPUSTATUS %08x drop_nop %1x i_flags %04x\n", + TRAPME, PSD1, PSD2, CPUSTATUS, drop_nop, i_flags); + /* adjust PSD1 to next instruction */ + /* Update instruction pointer to next instruction */ + if ((i_flags & BT) == 0) { /* see if PSD was replaced on a branch instruction */ + /* branch not taken, so update the PC */ + if (EXM_EXR != 0) { /* special handling for EXM, EXR, EXRR */ + PSD1 = (PSD1 + 4) | (((PSD1 & 2) >> 1) & 1); + EXM_EXR = 0; /* reset PC increment for EXR */ + } else + if (i_flags & HLF) { /* if nop in rt hw, bump pc a word */ + if ((drop_nop) && ((CPU_MODEL == MODEL_67) || (CPU_MODEL == MODEL_V6))) { + PSD1 = (PSD1 + 4) | (((PSD1 & 2) >> 1) & 1); + } else { + PSD1 = (PSD1 + 2) | (((PSD1 & 2) >> 1) & 1); + } + drop_nop = 0; + } else { + PSD1 = (PSD1 + 4) | (((PSD1 & 2) >> 1) & 1); + //DIAG fix for test 34/10 in MMM diag, reset bit 31 + if ((CPU_MODEL == MODEL_87) || (CPU_MODEL == MODEL_97) || + (CPU_MODEL == MODEL_V9)) + PSD1 &= ~BIT31; /* force off last right */ + } + } else { + EXM_EXR = 0; /* reset PC increment for EXR */ + if ((drop_nop) && ((CPU_MODEL == MODEL_67) || (CPU_MODEL >= MODEL_V6))) + PSD1 &= ~BIT31; /* force off last right */ + drop_nop = 0; + sim_debug(DEBUG_TRAP, &cpu_dev, + "##GOT BT TRAPME %04x LOAD MAPS PSD1 %08x PSD2 %08x\n", + TRAPME, PSD1, PSD2); + } + /* fall through */ + /* do not update pc for page fault */ + case DEMANDPG_TRAP: /* 0xC4 Demand Page Fault Trap (V6&V9 Only) */ + if (TRAPME == DEMANDPG_TRAP) { /* 0xC4 Demand Page Fault Trap (V6&V9 Only) */ + /* Set map number */ + if (CPU_MODEL >= MODEL_V9) + PSD1 &= ~BIT31; /* force off last right */ + /* pfault will have 11 bit page number and bit 0 set if op fetch */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "##PAGEFAULT TRAPS %02x page# %04x LOAD MAPS PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", + TRAPME, pfault, PSD1, PSD2, CPUSTATUS); + } + /* Moved here 05/28/2021 so PC gets incremented incorrectly */ + /* This caused the 2nd instruction of an int service routine to be skipped */ + /* The attn trap had to be on 2nd instruction */ + case CONSOLEATN_TRAP: /* 0xB4 PL0D Console Attention Trap */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "At TRAPME %02x PSD1 %08x PSD2 %08x CPUSTATUS %08x drop_nop %02x\n", + TRAPME, PSD1, PSD2, CPUSTATUS, drop_nop); + sim_debug(DEBUG_TRAP, &cpu_dev, + "At TRAP %02x IR %08x PSD1 %08x PSD2 %08x CPUSTATUS %08x ovr %01x drop_nop %01x\n", + TRAPME, IR, PSD1, PSD2, CPUSTATUS, ovr, drop_nop); + sim_debug(DEBUG_TRAP, &cpu_dev, + "R0=%.8x R1=%.8x R2=%.8x R3=%.8x\n", GPR[0], GPR[1], GPR[2], GPR[3]); + sim_debug(DEBUG_TRAP, &cpu_dev, + "R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + + tta = tta + (TRAPME - 0x80); /* tta has mem addr of trap vector */ + if (MODES & (BASEBIT | EXTDBIT)) + tvl = M[tta>>2] & 0xFFFFFC; /* get 24 bit trap address from trap vector loc */ + else + tvl = M[tta>>2] & 0x7FFFC; /* get 19 bit trap address from trap vector loc */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "tvl %08x, tta %08x status %08x page# %04x\n", tvl, tta, CPUSTATUS, pfault); +#ifndef TEMP_CHANGE_FOR_MPX3X_DEBUG + if (tvl == 0 || (CPUSTATUS & 0x40) == 0) { +#else + /* next line changed to force halt on halt trap */ + /* TRIED 041320 for MPX3.X install and testing */ + if (((tvl == 0) || (CPUSTATUS & 0x40) == 0) || + (TRAPME == PRIVHALT_TRAP)) { /* 0xB8 PL0E Privlege Mode Halt Trap */ +#endif + /* vector is zero or software has not enabled traps yet */ + /* execute a trap halt */ + /* set the PSD to trap vector location */ + fprintf(stderr, "[][][][][][][][][][] HALT TRAP [][][][][][][][][][]\r\n"); + fprintf(stderr, "PSD1 %08x PSD2 %08x TRAPME %04x\r\n", PSD1, PSD2, TRAPME); + PSD1 = 0x80000000 + TRAPME; /* just priv and PC to trap vector */ + PSD2 = 0x00004000; /* unmapped, blocked interrupts mode */ + M[0x680>>2] = PSD1; /* store PSD 1 */ + M[0x684>>2] = PSD2; /* store PSD 2 */ + M[0x688>>2] = TRAPSTATUS; /* store trap status */ + M[0x68C>>2] = 0; /* This will be device table entry later TODO */ + for (ix=0; ix<8; ix+=2) { + fprintf(stderr, "GPR[%d] %08x GPR[%d] %08x\r\n", ix, GPR[ix], ix+1, GPR[ix+1]); + } + if (MODES & BASEBIT) { + for (ix=0; ix<8; ix+=2) { + fprintf(stderr, "BR[%d] %08x BR[%d] %08x\r\n", ix, BR[ix], ix+1, BR[ix+1]); + } + } + fprintf(stderr, "[][][][][][][][][][] HALT TRAP [][][][][][][][][][]\r\n"); + return STOP_HALT; /* exit to simh for halt */ + } else { + uint32 oldstatus = CPUSTATUS; /* keep for retain blocking state */ + /* valid vector, so store the PSD, fetch new PSD */ + bc = PSD2 & 0x3ff8; /* get copy of cpix */ + if ((TRAPME) && ((CPU_MODEL <= MODEL_27))) { + /* Traps on 27 have bit 31 reset */ + M[tvl>>2] = PSD1 & 0xfffffffe; /* store PSD 1 */ + } else + M[tvl>>2] = PSD1 & 0xffffffff; /* store PSD 1 */ + M[(tvl>>2)+1] = PSD2; /* store PSD 2 */ + PSD1 = M[(tvl>>2)+2]; /* get new PSD 1 */ + PSD2 = (M[(tvl>>2)+3] & ~0x3ff8) | bc; /* get new PSD 2 w/old cpix */ + M[(tvl>>2)+4] = TRAPSTATUS; /* store trap status */ + if (TRAPME == DEMANDPG_TRAP) { /* 0xC4 Demand Page Fault Trap (V6&V9 Only) */ + M[(tvl>>2)+5] = pfault; /* store page fault number */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "DPAGE tvl %06x PSD1 %08x PSD2 %08x TRAPME %04x TRAPSTATUS %08x\n", + tvl, PSD1, PSD2, TRAPME, pfault); + } + + /* set the mode bits and CCs from the new PSD */ + CC = PSD1 & 0x78000000; /* extract bits 1-4 from PSD1 */ + MODES = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ + CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */ + CPUSTATUS |= MODES; /* now insert into CPUSTATUS */ + + /* set new map mode and interrupt blocking state in CPUSTATUS */ + if (PSD2 & MAPBIT) { + CPUSTATUS |= BIT8; /* set bit 8 of cpu status */ + MODES |= MAPMODE; /* set mapped mode */ + } else { + CPUSTATUS &= ~BIT8; /* reset bit 8 of cpu status */ +/*TRY_01072022*/ MODES &= ~MAPMODE; /* reset mapped mode */ + } + + /* set interrupt blocking state */ + if ((PSD2 & RETBBIT) == 0) { /* is it retain blocking state */ + if (PSD2 & SETBBIT) { /* no, is it set blocking state */ + CPUSTATUS |= BIT24; /* yes, set blk state in cpu status bit 24 */ + MODES |= BLKMODE; /* set blocked mode */ + } else { + CPUSTATUS &= ~BIT24; /* no, reset blk state in cpu status bit 24 */ + MODES &= ~BLKMODE; /* reset blocked mode */ + } + } else { + /* handle retain blocking state */ + PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ + /* set new blocking state in PSD2 */ + PSD2 &= ~(SETBBIT|RETBBIT); /* clear bit 48 & 49 to be unblocked */ + MODES &= ~(BLKMODE|RETBLKM);/* reset blocked & retain mode bits */ + if (oldstatus & BIT24) { /* see if old mode is blocked */ + PSD2 |= SETBBIT; /* set to blocked state */ + MODES |= BLKMODE; /* set blocked mode */ + } + } + + SPAD[0xf5] = PSD2; /* save the current PSD2 */ + SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ + + sim_debug(DEBUG_TRAP, &cpu_dev, + "Process TRAPME %04x PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", + TRAPME, PSD1, PSD2, CPUSTATUS); + /* TODO provide page fault data to word 6 */ + if (TRAPME == DEMANDPG_TRAP) { /* 0xC4 Demand Page Fault Trap (V6&V9 Only) */ + /* Set map number */ + /* pfault will have 11 bit page number and bit 0 set if op fetch */ + sim_debug(DEBUG_TRAP, &cpu_dev, + "PAGE TRAP %04x TSTAT %08x LOAD MAPS PSD1 %08x PSD2 %08x CPUSTAT %08x pfault %08x\n", + TRAPME, TRAPSTATUS, PSD1, PSD2, CPUSTATUS, pfault); + } + TRAPSTATUS = CPUSTATUS & 0x57; /* clear all trap status except cpu type */ + break; /* Go execute the trap */ + } + break; + } + } + /* we have a new PSD loaded via a LPSD or LPSDCM */ + /* finish instruction history, then continue */ + /* update cpu status word too */ + OPSD1 &= 0x87FFFFFF; /* clear the old CC's */ + OPSD1 |= PSD1 & 0x78000000; /* update the CC's in the PSD */ + /* Update other history information for this instruction */ + if (hst_lnt) { + hst[hst_p].opsd1 = OPSD1; /* update the CC in opsd1 */ + hst[hst_p].npsd1 = PSD1; /* save new psd1 */ + hst[hst_p].npsd2 = PSD2; /* save new psd2 */ + hst[hst_p].modes = MODES; /* save current mode bits */ + hst[hst_p].modes |= (CPUSTATUS & BIT24); /* save blocking mode bit */ + for (ix=0; ix<8; ix++) { + hst[hst_p].reg[ix] = GPR[ix]; /* save reg */ + hst[hst_p].reg[ix+8] = BR[ix]; /* save breg */ + } + } + + /* DEBUG_INST support code */ + /* output mapped/unmapped */ + if (MODES & BASEBIT) + BM = 'B'; + else + BM = 'N'; + if (MODES & MAPMODE) + MM = 'M'; + else + MM = 'U'; + if (CPUSTATUS & BIT24) + BK = 'B'; + else + BK = 'U'; + sim_debug(DEBUG_INST, &cpu_dev, "%c%c%c %.8x %.8x %.8x ", + BM, MM, BK, OPSD1, PSD2, OIR); + if (cpu_dev.dctrl & DEBUG_INST) { + fprint_inst(sim_deb, OIR, 0); /* display instruction */ + sim_debug(DEBUG_INST, &cpu_dev, + "\n\tR0=%.8x R1=%.8x R2=%.8x R3=%.8x", GPR[0], GPR[1], GPR[2], GPR[3]); + sim_debug(DEBUG_INST, &cpu_dev, + " R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]); + if (MODES & BASEBIT) { + sim_debug(DEBUG_INST, &cpu_dev, + "\tB0=%.8x B1=%.8x B2=%.8x B3=%.8x", BR[0], BR[1], BR[2], BR[3]); + sim_debug(DEBUG_INST, &cpu_dev, + " B4=%.8x B5=%.8x B6=%.8x B7=%.8x\n", BR[4], BR[5], BR[6], BR[7]); + } + } + continue; /* single step cpu just for now */ + } /* end while */ + + /* Simulation halted */ + return reason; +} + +/* these are the default ipl devices defined by the CPU jumpers */ +/* they can be overridden by specifying IPL device at ipl time */ +uint32 def_disk = 0x0800; /* disk channel 8, device 0 */ +uint32 def_tape = 0x1000; /* tape device 10, device 0 */ +uint32 def_floppy = 0x7ef0; /* IOP floppy disk channel 7e, device f0 */ + +/* Reset routine */ +/* do any one time initialization here for cpu */ +t_stat cpu_reset(DEVICE *dptr) +{ + int i; + t_stat devs = SCPE_OK; + + /* leave regs alone so values can be passed to boot code */ + PSD1 = 0x80000000; /* privileged, non mapped, non extended, address 0 */ + PSD2 = 0x00004000; /* blocked interrupts mode */ + MODES = (PRIVBIT | BLKMODE); /* set modes to privileged and blocked interrupts */ + CC = 0; /* no CCs too */ + CPUSTATUS = CPU_MODEL; /* clear all cpu status except cpu type */ + CPUSTATUS |= PRIVBIT; /* set privleged state bit 0 */ + CPUSTATUS |= BIT24; /* set blocked mode state bit 24 */ + CPUSTATUS |= BIT22; /* set HS floating point unit not present bit 22 */ + TRAPSTATUS = CPU_MODEL; /* clear all trap status except cpu type */ + CMCR = 0; /* No Cache Enabled */ + SMCR = 0; /* No Shared Memory Enabled */ + CMSMC = 0x00ff0a10; /* No V9 Cache/Shadow Memory Configuration */ + CSMCW = 0; /* No V9 CPU Shadow Memory Configuration */ + ISMCW = 0; /* No V9 IPU Shadow Memory Configuration */ + RDYQIN = RDYQOUT = 0; /* initialize channel ready queue */ + + devs = chan_set_devs(); /* set up the defined devices on the simulator */ + + /* set default breaks to execution tracing */ + sim_brk_types = sim_brk_dflt = SWMASK('E'); + /* zero regs */ + for (i = 0; i < 8; i++) { + GPR[i] = BOOTR[i]; /* set boot register values */ + BR[i] = 0; /* clear the registers */ + } + + /* set console switch settings */ + M[0x780>>2] = CSW; /* set console switch settings */ + + /* zero interrupt status words */ + for (i = 0; i < 112; i++) + INTS[i] = 0; /* clear interrupt status flags */ + + /* add code here to initialize the SEL32 cpu scratchpad on initial start */ + /* see if spad setup by software, if yes, leave spad alone */ + /* otherwise set the default values into the spad */ + /* CPU key is 0xECDAB897, IPU key is 0x13254768 */ + /* Keys are loaded by the O/S software during the boot loading sequence */ + if (SPAD[0xf7] != 0xecdab897) + { + int ival = 0; /* init value for concept 32 */ + + if (CPU_MODEL < MODEL_27) + ival = 0xfffffff; /* init value for 32/7x int and dev entries */ + for (i = 0; i < 1024; i++) + MAPC[i] = 0; /* clear 2048 halfword map cache */ + for (i = 0; i < 224; i++) + SPAD[i] = ival; /* init 128 devices and 96 ints in the spad */ + for (i = 224; i < 256; i++) /* clear the last 32 extries */ + SPAD[i] = 0; /* clear the spad */ + SPAD[0xf0] = 0x80; /* default Trap Table Address (TTA) */ + SPAD[0xf1] = 0x100; /* Interrupt Table Address (ITA) */ + SPAD[0xf2] = 0x700; /* IOCD Base Address */ + SPAD[0xf3] = 0x788; /* Master Process List (MPL) table address */ + SPAD[0xf4] = def_tape; /* Default IPL address from console IPL command or jumper */ + SPAD[0xf5] = PSD2; /* current PSD2 defaults to blocked */ + SPAD[0xf6] = 0; /* reserved (PSD1 ??) */ + SPAD[0xf7] = 0xecdab897; /* load the CPU key */ + SPAD[0xf8] = 0x0000f000; /* set DRT to class f (anything else is E) */ + SPAD[0xf9] = CPUSTATUS; /* set default cpu type in cpu status word */ + SPAD[0xff] = 0x00ffffff; /* interrupt level 7f 1's complament */ + } +#if 0 + /* set low memory bootstrap code */ + /* moved to boot code in sel32_chan.c so we can reset system and not destroy memory */ + M[0] = 0x02000000; /* 0x00 IOCD 1 read into address 0 */ + M[1] = 0x60000078; /* 0x04 IOCD 1 CMD Chain, Suppress incor len, 120 bytes */ + M[2] = 0x53000000; /* 0x08 IOCD 2 BKSR or RZR to re-read boot code */ + M[3] = 0x60000001; /* 0x0C IOCD 2 CMD chain,Supress incor length, 1 byte */ + M[4] = 0x02000000; /* 0x10 IOCD 3 Read into address 0 */ + M[5] = 0x000006EC; /* 0x14 IOCD 3 Read 0x6EC bytes */ +#endif + loading = 0; /* not loading yet */ + /* we are good to go or error from device setup */ + if (devs != SCPE_OK) + return devs; + return SCPE_OK; +} + +/* Memory examine */ +/* examine a 32bit memory location and return a byte */ +t_stat cpu_ex(t_value *vptr, t_addr baddr, UNIT *uptr, int32 sw) +{ + uint32 status, realaddr, prot; + uint32 addr = (baddr & 0xfffffc) >> 2; /* make 24 bit byte address into word address */ + + if (sw & SWMASK('V')) { + /* convert address to real physical address */ + status = RealAddr(addr, &realaddr, &prot, MEM_RD); + sim_debug(DEBUG_CMD, &cpu_dev, "cpu_ex Mem_read status = %02x\n", status); + if (status == ALLOK) { + *vptr = (M[realaddr] >> (8 * (3 - (baddr & 0x3)))); /* return memory contents */ + return SCPE_OK; /* we are all ok */ + } + return SCPE_NXM; /* no, none existant memory error */ + } + /* MSIZE is in 32 bit words */ + if (!MEM_ADDR_OK(addr)) /* see if address is within our memory */ + return SCPE_NXM; /* no, none existant memory error */ + if (vptr == NULL) /* any address specified by user */ + return SCPE_OK; /* no, just ignore the request */ + *vptr = (M[addr] >> (8 * (3 - (baddr & 0x3)))); /* return memory contents */ + return SCPE_OK; /* we are all ok */ +} + +/* Memory deposit */ +/* modify a byte specified by a 32bit memory location */ +/* address is byte address with bits 30,31 = 0 */ +t_stat cpu_dep(t_value val, t_addr baddr, UNIT *uptr, int32 sw) +{ + uint32 addr = (baddr & 0xfffffc) >> 2; /* make 24 bit byte address into word address */ + static const uint32 bmasks[4] = {0x00FFFFFF, 0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00}; + + /* MSIZE is in 32 bit words */ + if (!MEM_ADDR_OK(addr)) /* see if address is within our memory */ + return SCPE_NXM; /* no, none existant memory error */ + val = (M[addr] & bmasks[baddr & 0x3]) | (val << (8 * (3 - (baddr & 0x3)))); + M[addr] = val; /* set new value */ + return SCPE_OK; /* all OK */ +} + +/* set the CPU memory size */ +/* table values are in words, not bytes */ +uint32 memwds [] = { + 0x008000, /* size index 0 - 128KB = 32KW */ + 0x010000, /* 1 - 256KB = 64KW */ + 0x020000, /* 2 - 512KB = 128KW */ + 0x040000, /* 3 - 1MB = 256KW */ + 0x080000, /* 4 - 2MB = 512KW */ + 0x0c0000, /* 5 - 3MB = 768KW */ + 0x100000, /* 6 - 4MB = 1MW */ + 0x180000, /* 7 - 6MB = 1.5MW */ + 0x200000, /* 8 - 8MB = 2MW */ + 0x300000, /* 9 - 12MB = 3MW */ + 0x400000, /* 10 - 16MB = 4MW */ +}; + +t_stat cpu_set_size(UNIT *uptr, int32 sval, CONST char *cptr, void *desc) +{ + uint32 i; + uint32 sz; + int32 val = (int32)sval; + t_addr msize; + + val >>= UNIT_V_MSIZE; /* shift index right 19 bits */ + if (val >= (int32)(sizeof(memwds)/sizeof(uint32))) /* is size valid */ + return SCPE_ARG; /* nope, argument error */ + sz = memwds[val]; /* (128KB/4) << index == memory size in KW */ + if ((sz <= 0) || (sz > MAXMEMSIZE)) /* is size valid */ + return SCPE_ARG; /* nope, argument error */ + msize = sz << 2; /* Convert to words */ + if (msize < MEMSIZE) { /* is size smaller */ + uint32 mc = 0; /* yes, see if larger memory was used */ + for (i = sz-1; i < (MEMSIZE>>2); i++) + mc = mc | M[i]; /* or in any bits we might find */ + if ((mc != 0) && (!get_yn ("Really truncate memory [N]?", FALSE))) + return SCPE_OK; /* forget update */ + } + for (i = (MEMSIZE>>2) - 1; i < sz; i++) + M[i] = 0; /* zero all of the new memory */ + cpu_unit.flags &= ~UNIT_MSIZE; /* clear old size value 0-31 */ + cpu_unit.flags |= val << UNIT_V_MSIZE; /* set new memory size index value (0-31) */ + cpu_unit.capac = (t_addr)msize; /* set new size */ + return SCPE_OK; /* we done */ +} + +/* Handle execute history */ + +/* Set history */ +t_stat +cpu_set_hist(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int32 i, lnt; + t_stat r; + + if (cptr == NULL) { /* check for any user options */ + for (i = 0; i < hst_lnt; i++) /* none, so just zero the history */ + hst[i].opsd1 = 0; /* just psd1 for now */ + hst_p = 0; /* start at the beginning */ + return SCPE_OK; /* all OK */ + } + /* the user has specified options, process them */ + lnt = (int32)get_uint(cptr, 10, HIST_MAX, &r); + if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN))) + return SCPE_ARG; /* arg error for bad input or too small a value */ + hst_p = 0; /* start at beginning */ + if (hst_lnt) { /* if a new length was input, resize history buffer */ + free(hst); /* out with the old */ + hst_lnt = 0; /* no length anymore */ + hst = NULL; /* and no pointer either */ + } + if (lnt) { /* see if new size specified, if so get new resized bfer */ + hst = (struct InstHistory *)calloc(sizeof(struct InstHistory), lnt); + if (hst == NULL) + return SCPE_MEM; /* allocation error, so tell user */ + hst_lnt = lnt; /* set new length */ + } + return SCPE_OK; /* we are good to go */ +} + +/* Show history */ +t_stat cpu_show_hist(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + int32 k, di, lnt; + char *cptr = (char *) desc; + t_stat r; + uint8 BM, MM, BK; /* basemode, mapped mode, blocked mode */ + struct InstHistory *h; + + if (hst_lnt == 0) /* see if show history is enabled */ + return SCPE_NOFNC; /* no, so we are out of here */ + if (cptr) { /* see if user provided a display count */ + lnt = (int32)get_uint(cptr, 10, hst_lnt, &r); /* get the count */ + if ((r != SCPE_OK) || (lnt == 0)) /* if error or 0 count */ + return SCPE_ARG; /* report argument error */ + } else + lnt = hst_lnt; /* dump all the entries */ + di = hst_p - lnt; /* work forward */ + if (di < 0) + di = di + hst_lnt; /* wrap */ + for (k = 0; k < lnt; k++) { /* print specified entries */ + h = &hst[(++di) % hst_lnt]; /* entry pointer */ + /* display the instruction and results */ + if (MODES & BASEBIT) + BM = 'B'; + else + BM = 'N'; + if (MODES & MAPMODE) + MM = 'M'; + else + MM = 'U'; + if (MODES & 0x80) /* get blocked bit */ + BK = 'B'; + else + BK = 'U'; + fprintf(st, "%c%c%c %.8x %.8x %.8x ", BM, MM, BK, h->opsd1, h->npsd2, h->oir); + if (h->modes & BASEBIT) + fprint_inst(st, h->oir, SWMASK('M')); /* display basemode instruction */ + else + fprint_inst(st, h->oir, SWMASK('N')); /* display non basemode instruction */ + fprintf(st, "\n"); + fprintf(st, "\tR0=%.8x R1=%.8x R2=%.8x R3=%.8x", h->reg[0], h->reg[1], h->reg[2], h->reg[3]); + fprintf(st, " R4=%.8x R5=%.8x R6=%.8x R7=%.8x", h->reg[4], h->reg[5], h->reg[6], h->reg[7]); + if (h->modes & BASEBIT) { + fprintf(st, "\n"); + fprintf(st, "\tB0=%.8x B1=%.8x B2=%.8x B3=%.8x", h->reg[8], h->reg[9], h->reg[10], h->reg[11]); + fprintf(st, " B4=%.8x B5=%.8x B6=%.8x B7=%.8x", h->reg[12], h->reg[13], h->reg[14], h->reg[15]); + } + fprintf(st, "\n"); + } /* end for */ + return SCPE_OK; /* all is good */ +} + +/* return description for the specified device */ +const char *cpu_description (DEVICE *dptr) +{ + return "SEL 32 CPU"; /* return description */ +} + +t_stat cpu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf(st, "The CPU can maintain a history of the most recently executed instructions.\n"); + fprintf(st, "This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:\n\n"); + fprintf(st, " sim> SET CPU HISTORY clear history buffer\n"); + fprintf(st, " sim> SET CPU HISTORY=0 disable history\n"); + fprintf(st, " sim> SET CPU HISTORY=n{:file} enable history, length = n\n"); + fprintf(st, " sim> SHOW CPU HISTORY print CPU history\n"); + return SCPE_OK; +} diff --git a/SEL32/sel32_defs.h b/SEL32/sel32_defs.h new file mode 100644 index 00000000..ce5574ab --- /dev/null +++ b/SEL32/sel32_defs.h @@ -0,0 +1,535 @@ +/* sel32_defs.h: SEL-32 Concept/32 simulator definitions + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers + + 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 + JAMES C. BEVIER 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 "sim_defs.h" /* simh simulator defns */ + +/* Simulator stop codes */ +#define STOP_IONRDY 1 /* I/O dev not ready */ +#define STOP_HALT 2 /* HALT */ +#define STOP_IBKPT 3 /* breakpoint */ +#define STOP_UUO 4 /* invalid opcode */ +#define STOP_INVINS 5 /* invalid instr */ +#define STOP_INVIOP 6 /* invalid I/O op */ +#define STOP_INDLIM 7 /* indirect limit */ +#define STOP_XECLIM 8 /* XEC limit */ +#define STOP_IOCHECK 9 /* IOCHECK */ +#define STOP_MMTRP 10 /* mm in trap */ +#define STOP_TRPINS 11 /* trap inst not BRM */ +#define STOP_RTCINS 12 /* rtc inst not MIN/SKR */ +#define STOP_ILLVEC 13 /* zero vector */ +#define STOP_CCT 14 /* runaway CCT */ + +/* I/O equates */ +/* Channel sense bytes set by device */ +#define SNS_BSY 0x80 /* Unit Busy */ +#define SNS_SMS 0x40 /* Status modified */ +#define SNS_CTLEND 0x20 /* Control unit end */ +#define SNS_ATTN 0x10 /* Unit attention */ +#define SNS_CHNEND 0x08 /* Channel end */ +#define SNS_DEVEND 0x04 /* Device end */ +#define SNS_UNITCHK 0x02 /* Unit check */ +#define SNS_UNITEXP 0x01 /* Unit exception */ + +/* Command masks */ +#define CCMDMSK 0xff000000 /* Mask for command */ +#define CMD_CHAN 0x00 /* Channel control */ +#define CMD_SENSE 0x04 /* Sense channel command */ +#define CMD_TIC 0x08 /* Transfer in channel */ +#define CMD_RDBWD 0x0c /* Read backward */ +/* operation types */ +#define CMD_TYPE 0x03 /* Type mask */ +#define CMD_WRITE 0x01 /* Write command */ +#define CMD_READ 0x02 /* Read command */ +#define CMD_CTL 0x03 /* Control command */ + +/* IOCD word 2 status bits */ +#define STATUS_ECHO 0x8000 /* Halt I/O and Stop I/O function */ +#define STATUS_PCI 0x4000 /* Program controlled interrupt */ +#define STATUS_LENGTH 0x2000 /* Incorrect length */ +#define STATUS_PCHK 0x1000 /* Channel program check */ +#define STATUS_CDATA 0x0800 /* Channel data check */ +#define STATUS_CCNTL 0x0400 /* Channel control check */ +#define STATUS_INTER 0x0200 /* Channel interface check */ +#define STATUS_CHAIN 0x0100 /* Channel chain check */ +#define STATUS_BUSY 0x0080 /* Device busy */ +#define STATUS_MOD 0x0040 /* Status modified */ +#define STATUS_CTLEND 0x0020 /* Controller end */ +#define STATUS_ATTN 0x0010 /* Device raised attention */ +#define STATUS_CEND 0x0008 /* Channel end */ +#define STATUS_DEND 0x0004 /* Device end */ +#define STATUS_CHECK 0x0002 /* Unit check */ +#define STATUS_EXPT 0x0001 /* Unit exception */ +#define STATUS_ERROR 0x3f03 /* bad errors */ +//#define STATUS_ERROR (STATUS_LENGTH|STATUS_PCHK|STATUS_CDATA|STATUS_CCNTL| +// STATUS_INTER|STATUS_CHAIN|STATUS_CHECK|STATUS_EXPT) + +/* Class F channel bits */ +/* bit 32 - 37 of IOCD word 2 (0-5) */ +/* ccw_flags bit assignment */ +#define FLAG_DC 0x8000 /* Data chain */ +#define FLAG_CC 0x4000 /* Chain command */ +#define FLAG_SLI 0x2000 /* Suppress length indicator */ +#define FLAG_SKIP 0x1000 /* Suppress memory write */ +#define FLAG_PCI 0x0800 /* Program controlled interrupt */ +#define FLAG_RTO 0x0400 /* Real-Time Option */ + +/* chan_byte bit assignments */ +#define BUFF_EMPTY 0x00 /* Buffer is empty */ +#define BUFF_BUSY 0x04 /* Channel program busy & empty */ +#define BUFF_NEXT 0x0C /* 0x08|0x04 Continue Channel with next IOCB */ +#define BUFF_CHNEND 0x14 /* 0x10|0x04 Channel end */ +#define BUFF_DONE 0x20 /* 0x20 Channel ready for new command */ +#define BUFF_POST 0x24 /* 0x20|0x04 Waiting for status to be posted */ + +/* chan_info bit flags */ +#define INFO_SIOCD 0x01 /* Initial IOCD from SIO if set */ +#define INFO_CEND 0x02 /* Channel End (chan_end) called if set */ +/* bits 0-5 unused */ + +#define MAX_CHAN 128 /* max channels that can be defined */ +#define SUB_CHANS 256 /* max sub channels that can be defined */ +#define MAX_DEV (MAX_CHAN * SUB_CHANS) /* max possible */ + +/* simulator devices configuration */ +#define NUM_DEVS_IOP 1 /* 1 device IOP channel controller */ +#define NUM_UNITS_IOP 1 /* 1 master IOP channel device */ +#define NUM_DEVS_MFP 1 /* 1 device MFP channel controller */ +#define NUM_UNITS_MFP 1 /* 1 master MFP channel device */ +#define NUM_DEVS_COM 2 /* 8-Line async controller */ +#define NUM_UNITS_COM 16 /* 8-Line async units */ +#define NUM_DEVS_CON 1 /* 1 I/O console controller */ +#define NUM_UNITS_CON 2 /* 2 console input & output */ +#define NUM_DEVS_MT 1 /* 1 mag tape controllers */ +#define NUM_UNITS_MT 4 /* 4 of 8 devices */ +#define NUM_DEVS_HSDP 1 /* 1 hspd disk drive controller */ +//#define NUM_UNITS_HSDP 2 /* 2 disk drive devices */ +#define NUM_UNITS_HSDP 4 /* 4 disk drive devices */ +#define NUM_DEVS_DISK 1 /* 1 dp02 disk drive controller */ +//#define NUM_UNITS_DISK 2 /* 2 disk drive devices */ +#define NUM_UNITS_DISK 4 /* 4 disk drive devices */ +#define NUM_DEVS_SCFI 1 /* 1 scfi (SCSI) disk drive units */ +//#define NUM_UNITS_SCFI 2 /* 1 of 4 disk drive devices */ +#define NUM_UNITS_SCFI 4 /* 1 of 4 disk drive devices */ +#define NUM_DEVS_SCSI 2 /* 2 scsi (MFP SCSI) scsi buss units */ +#define NUM_UNITS_SCSI 2 /* 2 scsi disk drive devices */ +#define NUM_DEVS_RTOM 1 /* 1 IOP RTOM channel */ +#define NUM_UNITS_RTOM 1 /* 1 IOP RTOM device (clock & interval timer) */ +#define NUM_DEVS_LPR 1 /* 1 IOP Line printer */ +#define NUM_UNITS_LPR 1 /* 1 IOP Line printer device */ +#define NUM_DEVS_ETHER 1 /* 1 Ethernet controller */ +#define NUM_UNITS_ETHER 16 /* 16 Ethernet devices */ + +extern DEVICE cpu_dev; /* cpu device */ +extern UNIT cpu_unit; /* the cpu unit */ +#ifdef NUM_DEVS_IOP +extern DEVICE iop_dev; /* IOP channel controller */ +#endif +#ifdef NUM_DEVS_MFP +extern DEVICE mfp_dev; /* MFP channel controller */ +#endif +#ifdef NUM_DEVS_RTOM +extern DEVICE rtc_dev; /* RTOM rtc */ +extern DEVICE itm_dev; /* RTOM itm */ +#endif +#ifdef NUM_DEVS_CON +extern DEVICE con_dev; +#endif +#ifdef NUM_DEVS_MT +extern DEVICE mta_dev; +#endif +#if NUM_DEVS_MT > 1 +extern DEVICE mtb_dev; +#endif +#ifdef NUM_DEVS_DISK +extern DEVICE dda_dev; +#endif +#if NUM_DEVS_DISK > 1 +extern DEVICE ddb_dev; +#endif +#ifdef NUM_DEVS_HSDP +extern DEVICE dpa_dev; +#endif +#if NUM_DEVS_HSDP > 1 +extern DEVICE dpb_dev; +#endif +#ifdef NUM_DEVS_SCFI +extern DEVICE sda_dev; +#endif +#if NUM_DEVS_SCFI > 1 +extern DEVICE sdb_dev; +#endif +#ifdef NUM_DEVS_SCSI +extern DEVICE sba_dev; +#endif +#if NUM_DEVS_SCSI > 1 +extern DEVICE sbb_dev; +#endif +#ifdef NUM_DEVS_COM +extern DEVICE coml_dev; +extern DEVICE com_dev; +#endif +#ifdef NUM_DEVS_LPR +extern DEVICE lpr_dev; +#endif +#ifdef NUM_DEVS_ETHER +extern DEVICE ec_dev; +#endif + +/* Memory */ + +#define MAXMEMSIZE ((16*1024*1024)/4) /* max memory size in 32bit words */ +#define MEMSIZE (cpu_unit.capac) /* actual memory size */ +#define MEM_ADDR_OK(x) (((x)) < MEMSIZE) + +/* channel program data for a chan/sub-address */ +typedef struct chp { + /* channel program values */ + UNIT *unitptr; /* Back pointer to units structure */ + uint32 chan_inch_addr; /* Current channel status dw addr in memory */ + uint32 base_inch_addr; /* Original channel status dw addr in memory */ + uint16 max_inch_addr; /* maximum inch buffer pointer */ + uint32 chan_caw; /* Channel command address word */ + uint32 ccw_addr; /* Channel address */ +#ifdef TEST_FOR_IOCL_CHANGE + uint32 new_iocla; /* start iocl address */ + uint32 new_iocd1; /* start word 1 of iocd */ + uint32 new_iocd2; /* start word 2 of iocd */ +#endif + uint32 chan_buf; /* Channel data buffer */ + uint16 ccw_count; /* Channel count */ + uint16 ccw_flags; /* Channel flags */ + uint16 chan_status; /* Channel status */ + uint16 chan_dev; /* Device on channel */ + uint8 ccw_cmd; /* Channel command and flags */ + uint8 chan_byte; /* Current byte, empty/full */ + uint8 chan_int; /* channel interrupt level */ + uint8 chan_info; /* misc flags for channel */ +} CHANP; + +/* Device information block */ +#define FIFO_SIZE 256 /* fifo to hold 128 double words of status */ +extern int32 FIFO_Put(uint16 chsa, uint32 entry); +extern int32 FIFO_Get(uint16 chsa, uint32 *old); +extern int32 FIFO_Num(uint16 chsa); + +#define IOCLQ_SIZE 32 /* fifo to hold 32 iocl cmds */ + +typedef struct ioclq { + uint32 ioclq_fifo[IOCLQ_SIZE]; + int16 ioclq_in; + int16 ioclq_out; +} IOCLQ; + +extern int32 IOCLQ_Put(IOCLQ *qptr, uint32 entry); +extern int32 IOCLQ_Get(IOCLQ *qptr, uint32 *old); +extern int32 IOCLQ_Num(IOCLQ *qptr); + +typedef struct dib { + /* Pre start I/O operation */ + t_stat (*pre_io)(UNIT *uptr, uint16 chan); + /* Start a channel command SIO */ + t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd); + /* Halt I/O HIO */ + t_stat (*halt_io)(UNIT *uptr); /* Halt I/O */ + /* Test I/O STOPIO */ + t_stat (*stop_io)(UNIT *uptr); /* Stop I/O */ + /* Test I/O TESTIO */ + t_stat (*test_io)(UNIT *uptr); /* Test I/O */ + /* Reset Controller RSCTL */ + t_stat (*rsctl_io)(UNIT *uptr); /* Reset Controller */ + /* Reset Controller RSCHNL */ + t_stat (*rschnl_io)(UNIT *uptr); /* Reset Channel */ + /* Post I/O processing */ + t_stat (*iocl_io)(CHANP *chp, int32 tic_ok); /* IOCL processing */ + /* Controller init */ + void (*dev_ini)(UNIT *, t_bool); /* init function */ + UNIT *units; /* Pointer to units structure */ + CHANP *chan_prg; /* Pointer to channel program */ + IOCLQ *ioclq_ptr; /* pointer to array of IOCLQ entries */ + uint8 numunits; /* number of units */ + uint8 mask; /* device mask */ + uint16 chan_addr; /* parent channel address */ + uint32 chan_fifo_in; /* fifo input index */ + uint32 chan_fifo_out; /* fifo output index */ + uint32 chan_fifo[FIFO_SIZE]; /* interrupt status fifo for each channel */ +} DIB; + +extern DIB *dib_unit[MAX_DEV]; /* Pointer to Device info block */ +extern DIB *dib_chan[MAX_CHAN]; /* Pointer to channel mux dib */ + +/* defined in upper 16 bits of dptr->flags */ +#define DEV_CHAN (1 << DEV_V_UF) /* Device is channel mux if set */ +#define DEV_V_UF2 (DEV_V_UF+1) /* current usage */ +#define DEV_BUF_NUM(x) (((x) & 07) << DEV_V_UF2) +#define GET_DEV_BUF(x) (((x) >> DEV_V_UF2) & 07) + +#ifdef NOT_USED_NOW +//#define DEV_V_ADDR DEV_V_UF /* Pointer to device address (16) */ +//#define DEV_V_DADDR (DEV_V_UF + 8) /* Device address */ +//#define DEV_ADDR_MASK (0x7f << DEV_V_DADDR) /* 24 bits shift */ +//#define DEV_V_UADDR (DEV_V_UF) /* Device address in Unit */ +//#define DEV_UADDR (1 << DEV_V_UADDR) +//#define GET_DADDR(x) (0x7f & ((x) >> DEV_V_ADDR)) +//#define DEV_ADDR(x) ((x) << DEV_V_ADDR) +//#define PROTECT_V UNIT_V_UF+15 +//#define PROTECT (1 << PROTECT_V) +#endif + +/* defined in rightmost 8 bits of upper 16 bits of uptr->flags */ +/* allow 255 type disks */ +#define UNIT_SUBCHAN (1 << (UNIT_V_UF_31)) +#define UNIT_V_TYPE (UNIT_V_UF + 0) +#define UNIT_TYPE (0xff << UNIT_V_TYPE) +/* get & set disk types */ +#define GET_TYPE(x) ((UNIT_TYPE & (x)) >> UNIT_V_TYPE) +#define SET_TYPE(x) (UNIT_TYPE & ((x) << UNIT_V_TYPE)) + +/* defined in uptr->u3 upper 16 bits */ +/* DEV 0x7F000000 UNIT 0x00ff0000 */ +#define UNIT_V_ADDR 16 +#define UNIT_ADDR_MASK (0x7fff << UNIT_V_ADDR) +#define GET_UADDR(x) ((UNIT_ADDR_MASK & x) >> UNIT_V_ADDR) +#define UNIT_ADDR(x) ((x) << UNIT_V_ADDR) + +/* Debugging controls */ +#define DEBUG_CMD 0x0000001 /* Show device commands */ +#define DEBUG_DATA 0x0000002 /* Show data transfers */ +#define DEBUG_DETAIL 0x0000004 /* Show details */ +#define DEBUG_INFO 0x0000004 /* Show details */ +#define DEBUG_EXP 0x0000008 /* Show error conditions */ +#define DEBUG_INST 0x0000010 /* Show instructions */ +#define DEBUG_XIO 0x0000020 /* Show XIO I/O instructions */ +#define DEBUG_IRQ 0x0000040 /* Show IRQ requests */ +#define DEBUG_TRAP 0x0000080 /* Show TRAP requests */ + +extern DEBTAB dev_debug[]; + +/* defines for all programs */ +#define RMASK 0x0000FFFF /* right hw 16 bit mask */ +#define LMASK 0xFFFF0000 /* left hw 16 bit mask */ +#define FMASK 0xFFFFFFFF /* 32 bit mask */ +#define DMASK 0xFFFFFFFFFFFFFFFFLL /* 64 bit all bits mask */ +#define D48LMASK 0xFFFFFFFFFFFF0000LL /* 64 bit left 48 bits mask */ +#define D32LMASK 0xFFFFFFFF00000000LL /* 64 bit left 32 bits mask */ +#define D32RMASK 0x00000000FFFFFFFFLL /* 64 bit right 32 bits mask */ +#define MSIGN 0x80000000 /* 32 bit minus sign */ +#define DMSIGN 0x8000000000000000LL /* 64 bit minus sign */ +#define FSIGN 0x80000000 /* 32 bit minus sign */ +/* sign extend 16 bit value to uint32 */ +#define SEXT16(x) (x&0x8000?(uint32)(((uint32)x&RMASK)|LMASK):(uint32)x) +/* sign extend 16 bit value to uint64 */ +#define DSEXT16(x) (x&0x8000?(l_uint64)(((l_uint64)x&RMASK)|D48LMASK):(t_uint64)x) +/* sign extend 32 bit value to uint64 */ +#define DSEXT32(x) (x&0x8000?(l_uint64)(((l_uint64)x&D32RMASK)|D32LMASK):(t_uint64)x) +#define NEGATE32(val) ((~val) + 1) /* negate a value 16/32/64 bits */ + +/* defined in rightmost 8 bits of upper 16 bits of uptr->flags */ +#define UNIT_V_MODEL (UNIT_V_UF + 0) +#define UNIT_MODEL (7 << UNIT_V_MODEL) +#define MODEL(x) (x << UNIT_V_MODEL) +#define UNIT_V_MSIZE (UNIT_V_MODEL + 3) +#define UNIT_MSIZE (0x1F << UNIT_V_MSIZE) +#define MEMAMOUNT(x) (x << UNIT_V_MSIZE) +#define CPU_MODEL ((cpu_unit.flags >> UNIT_V_MODEL) & 0x7) /* cpu model 0-7 */ + +#define MODEL_55 0 /* 512K Mode Only */ +#define MODEL_75 1 /* Extended */ +#define MODEL_27 2 /* */ +#define MODEL_67 3 /* */ +#define MODEL_87 4 /* */ +#define MODEL_97 5 /* */ +#define MODEL_V6 6 /* V6 CPU */ +#define MODEL_V9 7 /* V9 CPU */ + +#define TMR_RTC 1 /* RTC will not work if set to 0!! */ +//#define TMR_RTC 0 + +#define HIST_MIN 64 +#define HIST_MAX 10000 +#define HIST_PC 0x80000000 + +/* CC defs Held in CC */ +#define CC1BIT 0x40000000 /* CC1 in PSD1 */ +#define CC2BIT 0x20000000 /* CC2 in PSD1 */ +#define CC3BIT 0x10000000 /* CC3 in PSD1 */ +#define CC4BIT 0x08000000 /* CC4 in PSD1 */ + +#define MAPMODE 0x40 /* Map mode, PSD 2 bit 0 */ +#define RETMODE 0x20 /* Retain current maps, PSD 2 bit 15 */ +#define RETBLKM 0x10 /* Set retain blocked mode, PSD 2 bit 16 */ +#define BLKMODE 0x08 /* Set blocked mode, PSD 2 bit 17 */ + +/* PSD mode bits in PSD words 1&2 variable */ +#define PRIVBIT 0x80000000 /* Privileged mode PSD 1 bit 0 */ +#define EXTDBIT 0x04000000 /* Extended Addressing PSD 1 bit 5 */ +#define BASEBIT 0x02000000 /* Base Mode PSD 1 bit 6 */ +#define AEXPBIT 0x01000000 /* Arithmetic exception PSD 1 bit 7 */ + +#define MAPBIT 0x80000000 /* Map mode, PSD 2 bit 0 */ +#define RETMBIT 0x00010000 /* Retain current maps, PSD 2 bit 15 */ +#define RETBBIT 0x00008000 /* Retain current blocking state, PSD 2 bit 16 */ +#define SETBBIT 0x00004000 /* Set blocked mode, PSD 2 bit 17 */ + +/* Trap Table Address in memory is pointed to by SPAD 0xF0 */ +#define POWERFAIL_TRAP 0x80 /* Power fail trap */ +#define POWERON_TRAP 0x84 /* Power-On trap */ +#define MEMPARITY_TRAP 0x88 /* Memory Parity Error trap */ +#define NONPRESMEM_TRAP 0x8C /* Non Present Memory trap */ +#define UNDEFINSTR_TRAP 0x90 /* Undefined Instruction Trap */ +#define PRIVVIOL_TRAP 0x94 /* Privlege Violation Trap */ +#define SVCCALL_TRAP 0x98 /* Supervisor Call Trap */ +#define MACHINECHK_TRAP 0x9C /* Machine Check Trap */ +#define SYSTEMCHK_TRAP 0xA0 /* System Check Trap */ +#define MAPFAULT_TRAP 0xA4 /* Map Fault Trap */ +#define IPUUNDEFI_TRAP 0xA8 /* IPU Undefined Instruction Trap */ +#define SIGNALIPU_TRAP 0xAC /* Signal IPU/CPU Trap */ +#define ADDRSPEC_TRAP 0xB0 /* Address Specification Trap */ +#define CONSOLEATN_TRAP 0xB4 /* Console Attention Trap */ +#define PRIVHALT_TRAP 0xB8 /* Privlege Mode Halt Trap */ +#define AEXPCEPT_TRAP 0xBC /* Arithmetic Exception Trap */ +#define CACHEERR_TRAP 0xC0 /* Cache Error Trap (V9 Only) */ +#define DEMANDPG_TRAP 0xC4 /* Demand Page Fault Trap (V6&V9 Only) */ + +/* Errors returned from various functions */ +#define ALLOK 0x0000 /* no error, all is OK */ +#define MAPFLT MAPFAULT_TRAP /* map fault error */ +#define NPMEM NONPRESMEM_TRAP /* non present memory */ +#define MPVIOL PRIVVIOL_TRAP /* memory protection violation */ +#define DMDPG DEMANDPG_TRAP /* Demand Page Fault Trap (V6&V9 Only) */ + +/* general instruction decode equates */ +#define IND 0x00100000 /* indirect bit in instruction, bit 11 */ +#define F_BIT 0x00080000 /* byte flag addressing bit 11 in instruction */ +#define C_BITS 0x00000003 /* byte number or hw, dw, dw flags bits 30 & 31 */ +#define BIT0 0x80000000 /* general use for bit 0 testing */ +#define BIT1 0x40000000 /* general use for bit 1 testing */ +#define BIT2 0x20000000 /* general use for bit 2 testing */ +#define BIT3 0x10000000 /* general use for bit 3 testing */ +#define BIT4 0x08000000 /* general use for bit 4 testing */ +#define BIT5 0x04000000 /* general use for bit 5 testing */ +#define BIT6 0x02000000 /* general use for bit 6 testing */ +#define BIT7 0x01000000 /* general use for bit 7 testing */ +#define BIT8 0x00800000 /* general use for bit 8 testing */ +#define BIT9 0x00400000 /* general use for bit 9 testing */ +#define BIT10 0x00200000 /* general use for bit 10 testing */ +#define BIT11 0x00100000 /* general use for bit 11 testing */ +#define BIT12 0x00080000 /* general use for bit 12 testing */ +#define BIT13 0x00040000 /* general use for bit 13 testing */ +#define BIT14 0x00020000 /* general use for bit 14 testing */ +#define BIT15 0x00010000 /* general use for bit 15 testing */ +#define BIT16 0x00008000 /* general use for bit 16 testing */ +#define BIT17 0x00004000 /* general use for bit 17 testing */ +#define BIT18 0x00002000 /* general use for bit 18 testing */ +#define BIT19 0x00001000 /* general use for bit 19 testing */ +#define BIT20 0x00000800 /* general use for bit 20 testing */ +#define BIT21 0x00000400 /* general use for bit 21 testing */ +#define BIT22 0x00000200 /* general use for bit 22 testing */ +#define BIT23 0x00000100 /* general use for bit 23 testing */ +#define BIT24 0x00000080 /* general use for bit 24 testing */ +#define BIT25 0x00000040 /* general use for bit 25 testing */ +#define BIT26 0x00000020 /* general use for bit 26 testing */ +#define BIT27 0x00000010 /* general use for bit 27 testing */ +#define BIT28 0x00000008 /* general use for bit 28 testing */ +#define BIT29 0x00000004 /* general use for bit 29 testing */ +#define BIT30 0x00000002 /* general use for bit 30 testing */ +#define BIT31 0x00000001 /* general use for bit 31 testing */ +#define MASK16 0x0000FFFF /* 16 bit address mask */ +#define MASK19 0x0007FFFF /* 19 bit address mask */ +#define MASK20 0x000FFFFF /* 20 bit address mask */ +#define MASK24 0x00FFFFFF /* 24 bit address mask */ +#define MASK32 0xFFFFFFFF /* 32 bit address mask */ + +/* SPAD int entry equates, entries accessed by interrupt level number */ +#define SINT_RAML 0x80000000 /* ram loaded (n/u) */ +#define SINT_EWCS 0x40000000 /* Enabled channel WCS executed (XIO) */ +#define SINT_ACT 0x20000000 /* Interrupt active when set (copy is in INTS */ +#define SINT_ENAB 0x10000000 /* Interrupt enabled when set (copy is in INTS */ +#define SINT_EXTL 0x00800000 /* IOP/RTOM ext interrupt if set, I/O if not set (copy in INTS) */ + +/* INTS int entry equates, entries accessed by interrupt level number */ +#define INTS_NU1 0x80000000 /* Not used */ +#define INTS_REQ 0x40000000 /* Interrupt is requesting (use bit 1) */ +#define INTS_ACT 0x20000000 /* Interrupt active when set (copy is of SPAD */ +#define INTS_ENAB 0x10000000 /* Interrupt enabled when set (copy is of SPAD */ +#define INTS_EXTL 0x00800000 /* IOP/RTOM ext interrupt if set, I/O if not set (copy of SPAD) */ + +/* ReadAddr memory access requested */ +#define MEM_RD 0x0 /* read memory */ +#define MEM_WR 0x1 /* write memory */ +#define MEM_EX 0x2 /* execute memory */ + +/* Rename of global PC variable to avoid namespace conflicts on some platforms */ +#define PC PC_Global + +/* memory access macros */ +/* The RMW and WMW macros are used to read/write memory words */ +/* RMW(addr) or WMW(addr, data) where addr is a byte alligned word address */ + +#define RMB(a) ((M[(a)>>2]>>(8*(3-(a&3))))&0xff) /* read memory addressed byte */ +#define RMH(a) ((a)&2?(M[(a)>>2]&RMASK):(M[(a)>>2]>>16)&RMASK) /* read memory addressed halfword */ +#define RMW(a) (M[((a)&MASK24)>>2]) /* read memory addressed word */ +#define WMW(a,d) (M[((a)&MASK24)>>2]=d) /* write memory addressed word */ +/* write halfword to memory address */ +#define WMH(a,d) ((a)&2?(M[(a)>>2]=(M[(a)>>2]&LMASK)|((d)&RMASK)):(M[(a)>>2]=(M[(a)>>2]&RMASK)|((d)<<16))) +/* write byte to memory */ +#define WMB(a,d) (M[(a)>>2]=(((M[(a)>>2])&(~(0xff<<(8*(3-(a&3))))))|((d&0xff)<<(8*(3-(a&3)))))) + +/* map register access macros */ +/* The RMR and WMR macros are used to read/write the MAPC cache registers */ +/* RMR(addr) or WMR(addr, data) where addr is a half word alligned address */ +/* read map register halfword from cache address */ +#define RMR(a) ((a)&2?(MAPC[(a)>>2]&RMASK):(MAPC[(a)>>2]>>16)&RMASK) +/* write halfword map register to MAP cache address */ +#define WMR(a,d) ((a)&2?(MAPC[(a)>>2]=(MAPC[(a)>>2]&LMASK)|((d)&RMASK)):(MAPC[(a)>>2]=(MAPC[(a)>>2]&RMASK)|((d)<<16))) + +/* Definitions for commonly used functions */ +extern t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +extern t_stat show_dev_addr(FILE * st, UNIT *uptr, int32 v, CONST void *desc); +extern void chan_end(uint16 chan, uint16 flags); +extern int chan_read_byte(uint16 chsa, uint8 *data); +extern int chan_write_byte(uint16 chsa, uint8 *data); +extern void set_devattn(uint16 addr, uint16 flags); +extern void set_devwake(uint16 chsa, uint16 flags); +extern t_stat chan_boot(uint16 addr, DEVICE *dptr); +extern int test_write_byte_end(uint16 chsa); +extern DEVICE *get_dev(UNIT *uptr); +extern t_stat set_inch(UNIT *uptr, uint32 inch_addr, uint32 num_inch); /* set inch addr */ +extern CHANP *find_chanp_ptr(uint16 chsa); /* find chanp pointer */ + +extern uint32 M[]; /* our memory */ +extern uint32 SPAD[]; /* cpu SPAD memory */ +extern uint32 attention_trap; +extern uint32 RDYQ[]; /* ready queue */ +extern uint32 RDYQIN; /* input index */ +extern uint32 RDYQOUT; /* output index */ +#define RDYQ_SIZE 128 +extern int32 RDYQ_Put(uint32 entry); +extern int32 RDYQ_Get(uint32 *old); +extern int32 RDYQ_Num(void); + +extern char *dump_mem(uint32 mp, int cnt); +extern char *dump_buf(uint8 *mp, int32 off, int cnt); + +#define get_chan(chsa) ((chsa>>8)&0x7f) /* get channel number from ch/sa */ + diff --git a/SEL32/sel32_disk.c b/SEL32/sel32_disk.c new file mode 100644 index 00000000..ca66aad9 --- /dev/null +++ b/SEL32/sel32_disk.c @@ -0,0 +1,3482 @@ +/* sel32_disk.c: SEL-32 2311/2314 Disk Processor II + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell and other SIMH contributers + + 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 + JAMES C. BEVIER 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 "sel32_defs.h" + +/* uncomment to use fast sim_activate times when running UTX */ +/* UTX gets an ioi error for dm0801 if slow times are used */ +/* dm0801 is not even a valid unit number for UDP controller */ +#define FAST_FOR_UTX + +#if NUM_DEVS_DISK > 0 + +#define UNIT_DISK UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE + +/* useful conversions */ +/* Fill STAR value from cyl, trk, sec data */ +#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff)) +/* convert STAR value to number of sectors */ +#define STAR2SEC(star,spt,spc) ((star&0xff)+(((star>>8)&0xff)*spt)+(((star>>16)&0xffff)*spc)) +/* convert STAR value to number of heads or tracks */ +#define STAR2TRK(star,tpc) (((star>>16)&0xffff)*tpc+((star>>8)&0x0ff)) +/* convert STAR value to number of cylinders */ +#define STAR2CYL(star) ((star>>16)&RMASK) +/* convert byte value to number of sectors mod sector size */ +#define BYTES2SEC(bytes,ssize) (((bytes) + (ssize-1)) >> 10) +/* get sectors per track for specified type */ +#define SPT(type) (disk_type[type].spt) +/* get sectors per cylinder for specified type */ +#define SPC(type) (disk_type[type].spt*disk_type[type].nhds) +/* get number of tracks for specified type */ +#define TRK(type) (disk_type[type].cyl*disk_type[type].nhds) +/* get number of cylinders for specified type */ +#define CYL(type) (disk_type[type].cyl) +/* get number of heads for specified type */ +#define HDS(type) (disk_type[type].nhds) +/* get disk capacity in sectors for specified type */ +#define CAP(type) (CYL(type)*HDS(type)*SPT(type)) +/* get number of bytes per sector for specified type */ +#define SSB(type) (disk_type[type].ssiz*4) +/* get disk capacity in bytes for specified type */ +#define CAPB(type) (CAP(type)*SSB(type)) +/* get disk geometry as STAR value for specified type */ +#define GEOM(type) (CHS2STAR(CYL(type),HDS(type),SPT(type))) + +/* INCH command information */ +/* +WD 0 - Data address +WD 1 - Flags - 0 -36 byte count + +Data - 224 word INCH buffer address (SST) +WD 1 Drive 0 Attribute register +WD 2 Drive 1 Attribute register +WD 3 Drive 2 Attribute register +WD 4 Drive 3 Attribute register +WD 5 Drive 4 Attribute register +WD 6 Drive 5 Attribute register +WD 7 Drive 6 Attribute register +WD 8 Drive 7 Attribute register + +Memory attribute register layout +bits 0-7 - Flags + bits 0&1 - 00=Reserved, 01=MHD, 10=FHD, 11=MHD with FHD option + bit 2 - 1=Cartridge module drive + bit 3 - 0=Reserved + bit 4 - 1=Drive not present + bit 5 - 1=Dual Port + bit 6&7 - 0=Blk size 00=768 byte blk + 01=1024 byte blk + 10=2048 byte blk + 11=Unassigned +bits 8-15 - sector count (sectors per track)(F16=16, F20=20) +bits 16-23 - MHD Head count (number of heads on MHD) +bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option of + mini-module) +*/ + +/* 224 word INCH Buffer layout */ +/* 128 word subchannel status storage (SST) */ +/* 66 words of program status queue (PSQ) */ +/* 26 words of scratchpad */ +/* 4 words of label buffer registers */ + +/************************************/ +/* track label definations 34 bytes */ + /* for track 0, write max cyl/head/sec values in 0-3 */ + /* otherwise write current values */ +/* +0 short lcyl; cylinder +2 char ltkn; head or track number +3 char lid; track label id (0xff means last track) +4 char lflg1; track status flags + bit 0 good trk + 1 alternate trk + 2 spare trk + 3 reserved trk + 4 defective trk + 5 last track + 6-7 n/u = 0 +5 char lflg2; + bit 0 write lock + 1 write protected + 2-7 n/u = 0 +6 short lspar1; n/u = 0 +8 short lspar2; n/u = 0 +10 short ldef1; defect #1 sec and byte position + * for track 0 write DMAP + * write sector number of cyl-4, hds-2, sec 0 value in 12-15 + * otherwise write current values +12 short ldef2; defect #2 sec and byte position +14 short ldef3; defect #3 sec and byte position + * for track 0 write UMAP which is DMAP - 2 * SPT + * write sector number of cyl-4, hds-3, sec 0 value in 16-19 + * otherwise write current values +16 short ladef1; defect #1 abs position +18 short ladef2; defect #2 abs position +20 short ladef3; defect #3 abs position +22 short laltcyl; alternate cylinder number or return cyl num +24 char lalttk; alrernate track number or return track num +25 char ldscnt; data sector count 16/20 +26 char ldatrflg; device attributes + bit 0 n/u + 1 disk is mhd + 2 n/u + 3 n/u + 4 n/u + 5 dual ported + 6/7 00 768 bytes/blk + 01 1024 bytes/blk + 10 2048 bytes/blk +27 char ldatrscnt; sectors per track (again) +28 char ldatrmhdc; MHD head count +29 char ldatrfhdc; FHD head count +30 uint32 lcrc; Label CRC-32 value + */ + +/*************************************/ +/* sector label definations 34 bytes */ +/* +0 short lcyl; cylinder number +2 char lhd; head number +3 char lsec; sec # 0-15 or 0-19 for 16/20 format +4 char lflg1; track/sector status flags + bit 0 good sec + 1 alternate sec + 2 spare sec + 3 reserved sec + 4 defective sec + 5 last sec + 6-7 n/u = 0 +5 char lflg2; + bit 0 write lock + 1 write protected + 2-7 n/u = 0 +6 short lspar1; n/u = 0 +8 short lspar2; n/u = 0 +10 short ldef1; defect #1 sec and byte position +12 short ldef2; defect #2 sec and byte position +14 short ldef3; defect #3 sec and byte position + * for sec 1 UTX prep will write UMAP, which is DMAP - 1 * SPT + * write sector number of cyl-4, hds-3, sec 0 value in 16-19 + * otherwise write zeros +16 short lspar3; n/u = 0 +18 short lspar4; n/u = 0 +20 short lspar5; n/u = 0 +22 short laltcyl; alternate cylinder number or return cyl num +24 char lalttk; alrernate track number or return track num +25 char ldscnt; data sector count 16/20 +26 char ldatrflg; device attributes + bit 0 n/u + 1 disk is mhd + 2 n/u + 3 n/u + 4 n/u + 5 dual ported + 6/7 00 768 bytes/blk + 01 1024 bytes/blk + 10 2048 bytes/blk +27 char ldatrscnt; sectors per track (again) +28 char ldatrmhdc; MHD head count +29 char ldatrfhdc; FHD head count +30 uint32 lcrc; Label CRC-32 value + */ + +#define CMD u3 +/* u3 */ +/* in u3 is device command code and status */ +#define DSK_CMDMSK 0x00ff /* Command being run */ +#define DSK_STAR 0x0100 /* STAR value in u4 */ +#define DSK_NU2 0x0200 /* */ +#define DSK_READDONE 0x0400 /* Read finished, end channel */ +#define DSK_ENDDSK 0x0800 /* Sensed end of disk */ +#define DSK_SEEKING 0x1000 /* Disk is currently seeking */ +#define DSK_READING 0x2000 /* Disk is reading data */ +#define DSK_WRITING 0x4000 /* Disk is writing data */ +#define DSK_BUSY 0x8000 /* Disk is busy */ +/* commands */ +#define DSK_INCH 0x00 /* Initialize channel */ +#define DSK_INCH2 0xF0 /* Initialize channel for processing */ +#define DSK_WD 0x01 /* Write data */ +#define DSK_RD 0x02 /* Read data */ +#define DSK_NOP 0x03 /* No operation */ +#define DSK_SNS 0x04 /* Sense */ +#define DSK_SCK 0x07 /* Seek cylinder, track, sector */ +#define DSK_TIC 0x08 /* Transfer in channel */ +#define DSK_FNSK 0x0B /* Format for no skip */ +#define DSK_LPL 0x13 /* Lock protected label */ +#define DSK_LMR 0x1F /* Load mode register */ +#define DSK_RES 0x23 /* Reserve */ +#define DSK_WSL 0x31 /* Write sector label */ +#define DSK_RSL 0x32 /* Read sector label */ +#define DSK_REL 0x33 /* Release */ +#define DSK_XEZ 0x37 /* Rezero */ +#define DSK_POR 0x43 /* Priority Override */ +#define DSK_IHA 0x47 /* Increment head address */ +#define DSK_SRM 0x4F /* Set reserve track mode */ +#define DSK_WTL 0x51 /* Write track label */ +#define DSK_RTL 0x52 /* Read track label */ +#define DSK_XRM 0x5F /* Reset reserve track mode */ +#define DSK_RAP 0xA2 /* Read angular positions */ +#define DSK_TESS 0xAB /* Test STAR (subchannel target address register) */ +#define DSK_REC 0xB2 /* Read ECC correction mask */ +#define DSK_ICH 0xFF /* Initialize controller */ + +#define STAR u4 +/* u4 - sector target address register (STAR) */ +/* Holds the current cylinder, head(track), sector */ +#define DISK_CYL 0xFFFF0000 /* cylinder mask */ +#define DISK_TRACK 0x0000FF00 /* track mask */ +#define DISK_SECTOR 0x000000ff /* sector mask */ + +#define SNS u5 +/* u5 */ +/* Sense byte 0 - mode register */ +#define SNS_DROFF 0x80000000 /* Drive Carriage will be offset */ +#define SNS_TRKOFF 0x40000000 /* Track offset: 0=positive, 1=negative */ +#define SNS_RDTMOFF 0x20000000 /* Read timing offset = 1 */ +#define SNS_RDSTRBT 0x10000000 /* Read strobe timing: 1=positive, 0=negative */ +#define SNS_DIAGMOD 0x08000000 /* Diagnostic Mode ECC Code generation and checking */ +#define SNS_RSVTRK 0x04000000 /* Reserve Track mode: 1=OK to write, 0=read only */ +#define SNS_FHDOPT 0x02000000 /* FHD or FHD option = 1 */ +#define SNS_RESERV 0x01000000 /* Reserved */ + +/* Sense byte 1 */ +#define SNS_CMDREJ 0x800000 /* Command reject */ +#define SNS_INTVENT 0x400000 /* Unit intervention required */ +#define SNS_SPARE1 0x200000 /* Spare */ +#define SNS_EQUCHK 0x100000 /* Equipment check */ +#define SNS_DATCHK 0x080000 /* Data Check */ +#define SNS_OVRRUN 0x040000 /* Data overrun/underrun */ +#define SNS_DSKFERR 0x020000 /* Disk format error */ +#define SNS_DEFTRK 0x010000 /* Defective track encountered */ + +/* Sense byte 2 */ +#define SNS_LAST 0x8000 /* Last track flag encountered */ +#define SNS_AATT 0x4000 /* At Alternate track */ +#define SNS_WPER 0x2000 /* Write protection error */ +#define SNS_WRL 0x1000 /* Write lock error */ +#define SNS_MOCK 0x0800 /* Mode check */ +#define SNS_INAD 0x0400 /* Invalid memory address */ +#define SNS_RELF 0x0200 /* Release fault */ +#define SNS_CHER 0x0100 /* Chaining error */ + +/* Sense byte 3 */ +#define SNS_REVL 0x80 /* Revolution lost */ +#define SNS_DADE 0x40 /* Disc addressing or seek error */ +#define SNS_BUCK 0x20 /* Buffer check */ +#define SNS_ECCS 0x10 /* ECC error in sector label */ +#define SNS_ECCD 0x08 /* ECC error in data */ +#define SNS_ECCT 0x04 /* ECC error in track label */ +#define SNS_RTAE 0x02 /* Reserve track access error */ +#define SNS_UESS 0x01 /* Uncorrectable ECC error */ + +#define SNS2 us9 +/* us9 */ +/* us9 holds bytes 4 & 5 of the status for the drive */ + +#define LASTCNT us10 +/* us10 */ +/* us10 holds original read/write byte count from iocd */ + +/* Sense byte 4 */ +#define SNS_SEND 0x8000 /* Seek End */ +#define SNS_USEL 0x4000 /* Unit Selected */ +#define SNS_SPC0 0x2000 /* Sector Pulse Count B0 */ +#define SNS_SPC1 0x1000 /* Sector Pulse Count B1 */ +#define SNS_SPC2 0x0800 /* Sector Pulse Count B2 */ +#define SNS_SPC3 0x0400 /* Sector Pulse Count B3 */ +#define SNS_SPC4 0x0200 /* Sector Pulse Count B4 */ +#define SNS_SPC5 0x0100 /* Sector Pulse Count B5 */ + +/* Sense byte 5 */ +#define SNS_FLT 0x80 /* Disk Drive fault */ +#define SNS_SKER 0x40 /* Seek error */ +#define SNS_ONC 0x20 /* On Cylinder */ +#define SNS_UNR 0x10 /* Unit Ready */ +#define SNS_WRP 0x08 /* Write Protected */ +#define SNS_BUSY 0x04 /* Drive is busy */ +#define SNS_NU1 0x02 /* Spare 1 */ +#define SNS_NU2 0x01 /* Spare 2 */ + +#define CHS u6 +/* u6 */ +/* u6 holds the current cyl, hd, sec for the drive */ + +/* this attribute information is provided by the INCH command */ +/* for each device and is not used. It is reconstructed from */ +/* the disk_t structure data for the assigned disk */ +/* +bits 0-7 - Flags + bits 0&1 - 00=Reserved, 01=MHD, 10=FHD, 11=MHD with FHD option + bit 2 - 1=Cartridge module drive + bit 3 - 0=Reserved + bit 4 - 1=Drive not present + bit 5 - 1=Dual Port + bit 6 - 0=Reserved 00 768 byte sec + bit 7 - 0=Reserved 01 1024 byte sec +bits 8-15 - sector count (sectors per track)(F16=16, F20=20) +bits 16-23 - MHD Head count (number of heads on MHD) +bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option of + mini-module) +*/ + +/* Not Used up7 */ + +static uint8 obuf[1024], bbuf[1024]; +static uint32 decc[512] = {0}; + +/* disk definition structure */ +struct disk_t +{ + const char *name; /* Device ID Name */ + uint16 nhds; /* Number of heads */ + uint16 ssiz; /* sector size in words */ + uint16 spt; /* # sectors per track(head) */ + uint16 ucyl; /* Number of cylinders used */ + uint16 cyl; /* Number of cylinders on disk */ + uint8 type; /* Device type code */ + /* bit 1 mhd */ + /* bits 6/7 = 0 768 byte blk */ /* not used on UDP/DPII */ + /* = 1 1024 byte blk */ /* not used on UDP/DPII */ +} + +disk_type[] = +{ + /* Class F Disc Devices */ + /* For MPX */ +#ifndef NOTFORMPX1X + {"MH040", 5, 192, 20, 407, 411, 0x40}, /* 0 411 40M XXXX */ + {"MH080", 5, 192, 20, 819, 823, 0x40}, /* 1 823 80M 8138 */ + {"MH160", 10, 192, 20, 819, 823, 0x40}, /* 2 823 160M 8148 */ + {"MH300", 19, 192, 20, 819, 823, 0x40}, /* 3 823 300M 8127 */ + {"MH600", 40, 192, 20, 839, 843, 0x40}, /* 4 843 600M 8155 */ +#else + {"MH040", 5, 192, 20, 400, 411, 0x40}, /* 0 411 40M XXXX */ + {"MH080", 5, 192, 20, 800, 823, 0x40}, /* 1 823 80M 8138 */ + {"MH160", 10, 192, 20, 800, 823, 0x40}, /* 2 823 160M 8148 */ + {"MH300", 19, 192, 20, 800, 823, 0x40}, /* 3 823 300M 8127 */ + {"MH600", 40, 192, 20, 800, 843, 0x40}, /* 4 843 600M 8155 */ +#endif + /* For UTX */ + {"9342", 5, 256, 16, 819, 823, 0x41}, /* 5 823 80M XXXX */ + {"8148", 10, 256, 16, 819, 823, 0x41}, /* 6 823 160M 8148 */ + {"9346", 19, 256, 16, 819, 823, 0x41}, /* 7 823 300M */ + {"8858", 24, 256, 16, 707, 711, 0x41}, /* 8 711 340M */ + {"8887", 10, 256, 35, 819, 823, 0x41}, /* 9 823 340M */ + {"8155", 40, 256, 16, 839, 843, 0x41}, /* 10 843 675M */ + {"8888", 16, 256, 43, 861, 865, 0x41}, /* 11 823 674M 8888 DP689 */ + {NULL, 0} +}; + +t_stat disk_preio(UNIT *uptr, uint16 chan) ; +t_stat disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ; +t_stat disk_haltio(UNIT *uptr); +t_stat disk_iocl(CHANP *chp, int32 tic_ok); +t_stat disk_srv(UNIT *uptr); +t_stat disk_boot(int32 unitnum, DEVICE *dptr); +void disk_ini(UNIT *, t_bool); +t_stat disk_rschnlio(UNIT *uptr); +t_stat disk_reset(DEVICE *); +t_stat disk_attach(UNIT *, CONST char *); +t_stat disk_detach(UNIT *); +t_stat disk_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat disk_get_type(FILE *st, UNIT *uptr, int32 v, CONST void *desc); +t_stat disk_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *disk_description (DEVICE *dptr); +extern uint32 inbusy; +extern uint32 outbusy; +extern uint32 readfull(CHANP *chp, uint32 maddr, uint32 *word); +extern int irq_pend; /* go scan for pending int or I/O */ +extern UNIT itm_unit; +extern uint32 PSD[]; /* PSD */ +extern uint32 cont_chan(uint16 chsa); + +/* channel program information */ +CHANP dda_chp[NUM_UNITS_DISK] = {0}; + +#define TRK_CACHE 10 +/* track label queue */ +struct _trk_data +{ + int32 age; + uint32 track; + uint8 label[30]; +}; + +struct _trk_label +{ + struct _trk_data tkl[TRK_CACHE]; +}; + +static struct _trk_label tkl_label[NUM_UNITS_DISK] = {0}; + +MTAB disk_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "TYPE", "TYPE", + &disk_set_type, &disk_get_type, NULL, "Type of disk"}, + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, + &show_dev_addr, NULL, "Device channel address"}, + {0}, +}; + +UNIT dda_unit[] = { +/* SET_TYPE(3) DM300 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0x800)}, /* 0 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0x802)}, /* 1 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0x804)}, /* 2 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0x806)}, /* 3 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0x808)}, /* 4 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80A)}, /* 5 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80C)}, /* 6 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80E)}, /* 7 */ +}; + +DIB dda_dib = { + disk_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + disk_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + disk_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + disk_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + disk_iocl, /* t_stat (*iocl_io)(CHANP *chp, int32 tik_ok)) */ /* Process IOCL */ + disk_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + dda_unit, /* UNIT* units */ /* Pointer to units structure */ + dda_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_DISK, /* uint8 numunits */ /* number of units defined */ + 0x0F, /* uint8 mask */ /* 8 devices - device mask */ + 0x0800, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE dda_dev = { + "DMA", dda_unit, NULL/*dda_reg*/, disk_mod, + NUM_UNITS_DISK, 16, 24, 4, 16, 32, + NULL, NULL, &disk_reset, &disk_boot, &disk_attach, &disk_detach, + /* ctxt is the DIB pointer */ + &dda_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &disk_help, NULL, NULL, &disk_description +}; + +#if NUM_DEVS_DISK > 1 +/* channel program information */ +CHANP ddb_chp[NUM_UNITS_DISK] = {0}; + +UNIT ddb_unit[] = { +/* SET_TYPE(3) DM300 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC00)}, /* 0 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC02)}, /* 1 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC04)}, /* 2 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC06)}, /* 3 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC08)}, /* 4 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0A)}, /* 5 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0C)}, /* 6 */ + {UDATA(&disk_srv, UNIT_DISK|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0E)}, /* 7 */ +}; + +DIB ddb_dib = { + disk_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + disk_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + disk_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + disk_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + disk_iocl, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + disk_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + ddb_unit, /* UNIT* units */ /* Pointer to units structure */ + ddb_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_DISK, /* uint8 numunits */ /* number of units defined */ + 0x0F, /* uint8 mask */ /* 8 devices - device mask */ + 0x0C00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE ddb_dev = { + "DMB", ddb_unit, NULL, /*ddb_reg*/, disk_mod, + NUM_UNITS_DISK, 16, 24, 4, 16, 32, + NULL, NULL, &disk_reset, &disk_boot, &disk_attach, &disk_detach, + /* ctxt is the DIB pointer */ + &ddb_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &disk_help, NULL, NULL, &disk_description +}; +#endif + +uint32 dmle_ecc32(uint8 *str, int32 len) +{ + int i, j; + uint32 ch, ecc = 0; + uint32 pmask = 0x7e11f439; /* SEL LE poly mask */ + + ecc = (~ecc & MASK32); /* initialize ecc to all bits (~0) */ + for (j=0; j>= 1; /* just shift out the bit */ + ecc ^= pmask; /* eor with poly mask */ + } else + ecc >>= 1; /* just shift out the bit */ + ch >>= 1; /* next bit */ + } + } + return (~ecc & MASK32); /* return ecc value */ +} + +uint32 dmbe_ecc32(uint8 *str, int32 len) +{ + int i, j; + uint32 ch, ecc = 0; + uint32 pmask = 0x9C2F887E; /* SEL BE poly mask */ + + ecc = (~ecc & MASK32); /* initialize ecc to all bits (~0) */ + for (j=0; jflags); + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); /* get the UNIT number */ + int len, i, cn, found = -1; + + int ds = ((CYL(type) - 3) * HDS(type)) * SPT(type); /* diag start */ + /* get file offset in sectors */ + tstart = STAR2SEC(star, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + nstar = disksec2star(tstart, type); + if (ds >= (int)tstart) { + /* zero the Track Label flags */ + buf[4] = 0; + return nstar; /* not in diag track, return */ + } + + cyl = (nstar >> 16) & 0xffff; /* get the cylinder */ + trk = (nstar >> 8) & 0xff; /* get the track */ + sec = nstar & 0xff; /* save sec if any */ + + /* get track number */ + tstart = (cyl * HDS(type)) + trk; + sim_debug(DEBUG_DETAIL, dptr, + "get_dmatrk RTL star %08x nstar %08x cyl %4x(%d) trk %x sec# %06x\n", + star, nstar, cyl, cyl, trk, tstart); + + /* calc offset in file to track label */ + offset = CAPB(type) + (tstart * 30); + + /* zero the Track Label Buffer */ + for (i = 0; i < 30; i++) + buf[i] = 0; + + /* see if track label is in cache */ + for (cn=0; cnfileref, offset, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, + "get_dpatrk RTL, Error on seek to %04x\n", offset); + return 0; + } + + /* read in a track label from disk */ + if ((len=sim_fread(buf, 1, 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_EXP, dptr, + "get_dpatrk Error %08x on read %04x of diskfile cyl %04x hds %02x sec 00\n", + len, 30, cyl, trk); + return 0; + } + } + + /* now write track label data to log */ + sim_debug(DEBUG_DETAIL, dptr, "Track %08x label", nstar); + for (i = 0; i < 30; i++) { + if (i == 16) + sim_debug(DEBUG_DETAIL, dptr, "\nTrack %08x label", nstar); + sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_DETAIL, dptr, "\n"); + + if (buf[4] == 0x08) { /* see if defective track */ + uptr->SNS |= SNS_DEFTRK; /* flag as defective */ + tstart = nstar; /* save orginal track */ + /* get the alternate track address */ + cyl = (buf[22] << 8) | buf[23]; /* get the cylinder */ + trk = buf[24]; /* get the track */ + nstar = CHS2STAR(cyl, trk, sec); + sim_debug(DEBUG_DETAIL, dptr, + "Track %08x is defective, new track %08x\n", tstart, nstar); + } + /* see if we had it in our cache */ + if (found == -1) { + /* not in our cache, save the new track label */ + int32 na = 0; + for (cn=0; cn na) + continue; /* older */ + /* this is less used, so replace it */ + na = cn; + } + /* use na entry */ + for (i=0; i<30; i++) + tkl_label[unit].tkl[na].label[i] = buf[i]; + tkl_label[unit].tkl[na].age = 1; + tkl_label[unit].tkl[cn].track = offset; + } + return nstar; /* return track address */ +} + +/* start a disk operation */ +t_stat disk_preio(UNIT *uptr, uint16 chan) +{ + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int unit = (uptr - dptr->units); + + sim_debug(DEBUG_DETAIL, dptr, "disk_preio CMD %08x unit %02x\n", uptr->CMD, unit); + if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */ + return SNS_BSY; + } + + sim_debug(DEBUG_DETAIL, dptr, "disk_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + +/* load in the IOCD and process the commands */ +/* return = 0 OK */ +/* return = 1 error, chan_status will have reason */ +t_stat disk_iocl(CHANP *chp, int32 tic_ok) +{ + uint32 word1 = 0; + uint32 word2 = 0; + int32 docmd = 0; + UNIT *uptr = chp->unitptr; /* get the unit ptr */ + uint16 chan = get_chan(chp->chan_dev); /* our channel */ + uint16 chsa = chp->chan_dev; /* our chan/sa */ + uint16 devstat = 0; + DEVICE *dptr = get_dev(uptr); + + /* check for valid iocd address if 1st iocd */ + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + if (chp->chan_caw & 0x3) { /* must be word bounded */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl iocd bad address chsa %02x caw %06x\n", + chsa, chp->chan_caw); + chp->ccw_addr = chp->chan_caw; /* set the bad iocl address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + return 1; /* error return */ + } + } +loop: + sim_debug(DEBUG_EXP, dptr, + "disk_iocl @%06x entry PSD %08x chan_status[%04x] %04x\n", + chp->chan_caw, PSD[0], chan, chp->chan_status); + + /* Abort if we have any errors */ + if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl ERROR1 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* return error */ + } + + /* Read in first CCW */ + if (readfull(chp, chp->chan_caw, &word1) != 0) { /* read word1 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl ERROR2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Read in second CCW */ + if (readfull(chp, chp->chan_caw+4, &word2) != 0) { /* read word2 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl ERROR3 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + sim_debug(DEBUG_CMD, dptr, + "disk_iocl @%06x read ccw chan %02x IOCD wd 1 %08x wd 2 %08x\n", + chp->chan_caw, chan, word1, word2); + + chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */ + + /* Check if we had data chaining in previous iocd */ + /* if we did, use previous cmd value */ + if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + (chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "disk_iocl @%06x DO DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + } else + chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ + + if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl bad IOCD1 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2 */ + + /* validate the commands for the disk */ + switch (chp->ccw_cmd) { + case DSK_WD: case DSK_RD: case DSK_INCH: case DSK_NOP: + case DSK_SCK: case DSK_XEZ: case DSK_LMR: case DSK_WSL: case DSK_RSL: + case DSK_IHA: case DSK_WTL: case DSK_RTL: case DSK_RAP: case DSK_TESS: + case DSK_FNSK: case DSK_REL: case DSK_RES: case DSK_POR: case DSK_TIC: + case DSK_REC: + case DSK_SNS: + break; + case DSK_ICH: + if (chp->ccw_count == 896) /* count must be 896 to be valid */ + break; + /* drop through */ + default: + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl bad cmd chan_status[%04x] %04x cmd %02x\n", + chan, chp->chan_status, chp->ccw_cmd); + return 1; /* error return */ + } + + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + /* 1st command can not be a TIC or NOP */ + if ((chp->ccw_cmd == DSK_NOP) || (chp->ccw_cmd == CMD_TIC)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl TIC/NOP bad cmd chan_status[%04x] %04x cmd %02x\n", + chan, chp->chan_status, chp->ccw_cmd); + return 1; /* error return */ + } + } + + /* TIC can't follow TIC or be first in command chain */ + /* diags send bad commands for testing. Use all of op */ + if (chp->ccw_cmd == CMD_TIC) { + if (tic_ok) { + if (((word1 & MASK24) == 0) || (word1 & 0x3)) { + sim_debug(DEBUG_EXP, dptr, + "disk_iocl tic cmd bad address chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + return 1; /* error return */ + } + tic_ok = 0; /* another tic not allowed */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + sim_debug(DEBUG_CMD, dptr, + "disk_iocl tic cmd ccw chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + goto loop; /* restart the IOCD processing */ + } + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + if (((word1 & MASK24) == 0) || (word1 & 0x3)) + uptr->SNS |= SNS_INAD; /* invalid address status */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl TIC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Check if we had data chaining in previous iocd */ + if ((chp->chan_info & INFO_SIOCD) || /* see if 1st IOCD in channel prog */ + (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + ((chp->ccw_flags & FLAG_DC) == 0))) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "disk_iocl @%06x DO CMD No DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + docmd = 1; /* show we have a command */ + } + + /* Set up for this command */ + chp->ccw_flags = (word2 >> 16) & 0xf000; /* get flags from bits 0-4 of WD 2 of IOCD */ + chp->chan_status = 0; /* clear status for next IOCD */ + /* make a 24 bit address */ + chp->ccw_addr = word1 & MASK24; /* set the data/seek address */ + + /* validate parts of IOCD2 that are reserved */ + if (word2 & 0x0fff0000) { /* bits 5-15 must be zero */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl IOCD2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* DC can only be used with a read/write cmd */ + if (chp->ccw_flags & FLAG_DC) { + if ((chp->ccw_cmd != DSK_RD) && (chp->ccw_cmd != DSK_WD)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid DC */ + uptr->SNS |= SNS_CHER; /* chaining error */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl DC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + } + + chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ + + sim_debug(DEBUG_XIO, dptr, + "disk_iocl @%06x read docmd %01x addr %06x count %04x chan %04x ccw_flags %04x\n", + chp->chan_caw, docmd, chp->ccw_addr, chp->ccw_count, chan, chp->ccw_flags); + + if (docmd) { /* see if we need to process a command */ + DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ + + uptr = chp->unitptr; /* get the unit ptr */ + if (dibp == 0 || uptr == 0) { + chp->chan_status |= STATUS_PCHK; /* program check if it is */ + return 1; /* if none, error */ + } + + sim_debug(DEBUG_DETAIL, dptr, + "disk_iocl @%06x before start_cmd chan %04x status %04x count %04x SNS %08x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, uptr->u5); + + /* call the device startcmd function to process the current command */ + /* just replace device status bits */ + chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ + devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd); + chp->chan_status = (chp->chan_status & 0xff00) | devstat; + chp->chan_info &= ~INFO_SIOCD; /* show not first IOCD in channel prog */ + + sim_debug(DEBUG_DETAIL, dptr, + "disk_iocl @%06x after start_cmd chan %04x status %08x count %04x byte %02x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, chp->chan_byte); + + /* see if bad status */ + if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) { + chp->chan_status |= STATUS_CEND; /* channel end status */ + chp->ccw_flags = 0; /* no flags */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + sim_debug(DEBUG_EXP, dptr, + "disk_iocl bad status chan %04x status %04x cmd %02x\n", + chan, chp->chan_status, chp->ccw_cmd); + /* done with command */ + sim_debug(DEBUG_EXP, &cpu_dev, + "load_ccw ERROR return chsa %04x status %08x\n", + chp->chan_dev, chp->chan_status); + return 1; /* error return */ + } + /* NOTE this code needed for MPX 1.X to run! */ + /* see if command completed */ + /* we have good status */ + if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_DETAIL, dptr, + "disk_iocl @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n", + chp->chan_caw, FIFO_Num(chsa), chan, chp->chan_status, chp->ccw_count); + } + } + /* the device processor returned OK (0), so wait for I/O to complete */ + /* nothing happening, so return */ + sim_debug(DEBUG_DETAIL, dptr, + "disk_iocl @%06x return, chan %04x status %04x count %04x irq_pend %1x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, irq_pend); + return 0; /* good return */ +} + +t_stat disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int32 unit = (uptr - dptr->units); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_DETAIL, dptr, + "disk_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n", + chsa, unit, cmd, uptr->CMD); + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + sim_debug(DEBUG_EXP, dptr, "disk_startcmd unit %02x not attached\n", unit); + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + if (cmd != DSK_SNS) /* we are completed with unit check status */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; + } + + if ((uptr->CMD & DSK_CMDMSK) != 0) { + sim_debug(DEBUG_EXP, dptr, "disk_startcmd unit %02x busy\n", unit); + uptr->CMD |= DSK_BUSY; /* Flag we are busy */ + return SNS_BSY; + } + uptr->SNS2 |= SNS_USEL; /* unit selected */ + sim_debug(DEBUG_DETAIL, dptr, + "disk_startcmd CMD continue unit=%02x cmd %02x iocla %06x cnt %04x\n", + unit, cmd, chp->chan_caw, chp->ccw_count); + + /* Unit is online, so process a command */ + switch (cmd) { + + case DSK_INCH: /* INCH cmd 0x0 */ + sim_debug(DEBUG_CMD, dptr, + "disk_startcmd starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n", + chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count); + + uptr->SNS &= ~SNS_CMDREJ; /* not rejected yet */ + uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */ +#ifdef FAST_FOR_UTX + sim_activate(uptr, 30); /* start things off */ +#else + sim_activate(uptr, 250); /* start things off */ +#endif + return SCPE_OK; /* good to go */ + break; + + case DSK_NOP: /* NOP 0x03 */ + if ((cmd == DSK_NOP) && + (chp->chan_info & INFO_SIOCD)) { /* is NOP 1st IOCD? */ + chp->chan_caw -= 8; /* backup iocd address for diags */ + break; /* yes, can't be 1st */ + } + case DSK_ICH: /* 0xFF Initialize controller */ + if ((cmd == DSK_ICH) && + (chp->ccw_count != 896)) { /* count must be 896 to be valid */ + break; + } + case DSK_SCK: /* Seek command 0x07 */ + case DSK_XEZ: /* Rezero & Read IPL record 0x37 */ + case DSK_WD: /* Write command 0x01 */ + case DSK_RD: /* Read command 0x02 */ + case DSK_LMR: /* read mode register 0x1F */ + case DSK_WSL: /* WSL 0x31 */ + case DSK_RSL: /* RSL 0x32 */ + case DSK_IHA: /* 0x47 Increment head address */ + case DSK_WTL: /* WTL 0x51 */ + case DSK_RTL: /* RTL 0x52 */ + case DSK_RAP: /* 0xA2 Read angular positions */ + case DSK_TESS: /* TESS 0xAB Test STAR */ + case DSK_FNSK: /* 0x0B Format for no skip */ + case DSK_REC: /* 0xB2 Read ECC correction mask */ + case DSK_RES: /* 0x23 Reserve */ + case DSK_REL: /* 0x33 Release */ + uptr->SNS &= ~MASK24; /* clear data & leave mode */ + uptr->SNS2 = (SNS_UNR|SNS_ONC|SNS_USEL);/* reset status to on cyl & ready */ + case DSK_SNS: /* Sense 0x04 */ + uptr->CMD |= cmd; /* save cmd */ + uptr->LASTCNT = chp->ccw_count; /* save cmd count for diags */ + sim_debug(DEBUG_CMD, dptr, + "disk_startcmd starting disk cmd %02x chsa %04x cnt %04x \n", + cmd, chsa, chp->ccw_count); +#ifdef FAST_FOR_UTX + /* when value was 50, UTX would get a spontainous interrupt */ + /* when value was 30, UTX would get a spontainous interrupt */ + /* changed to 25 from 30 121420 */ +//utx21a sim_activate(uptr, 20); /* start things off */ + /* changed to 15 from 20 12/17/2021 to fix utx21a getting */ + /* "panic: ioi: tis_busy - bad cc" during root fsck on boot */ + /* changed back to 20 from 15 12/18/2021 to refix utx21a getting */ + /* "panic: ioi: tis_busy - bad cc" during root fsck on boot */ + sim_activate(uptr, 20); /* start things off */ + /* when using 500, UTX gets "ioi: sio at 801 failed, cc3, retry=0" */ +#else + sim_activate(uptr, 500); /* start things off */ +#endif + return SCPE_OK; /* good to go */ + break; + } + + sim_debug(DEBUG_EXP, dptr, + "disk_startcmd done with bad disk cmd %02x chsa %04x SNS %08x\n", + cmd, chsa, uptr->SNS); + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* return error */ +} + +/* Handle haltio transfers for disk */ +t_stat disk_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int cmd = uptr->CMD & DSK_CMDMSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_DETAIL, dptr, + "disk_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + /* stop any I/O and post status and return error status */ + sim_debug(DEBUG_EXP, dptr, + "disk_haltio HIO I/O stop chsa %04x cmd = %02x CHS %08x STAR %08x\n", + chsa, cmd, uptr->CHS, uptr->STAR); + if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_EXP, dptr, + "disk_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + sim_cancel(uptr); /* clear the input timer */ + chp->ccw_count = 0; /* zero the count */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* stop any chaining */ + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force end */ + return CC1BIT | SCPE_IOERR; /* DIAGS want just an interrupt */ + } + sim_debug(DEBUG_DETAIL, dptr, + "disk_haltio HIO I/O not busy chsa %04x cmd = %02x\n", chsa, cmd); + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + return CC1BIT | SCPE_OK; /* not busy return */ +} + +/* Handle processing of disk requests. */ +t_stat disk_srv(UNIT *uptr) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + int cmd = uptr->CMD & DSK_CMDMSK; + int type = GET_TYPE(uptr->flags); + uint32 tcyl=0, trk=0, cyl=0, sec=0, tempt=0; + int unit = (uptr - dptr->units); + int len = chp->ccw_count; + int i,j,k; + uint32 mema, ecc, cecc; /* memory address / ecc */ + uint8 ch; + uint16 ssize = disk_type[type].ssiz * 4; /* disk sector size in bytes */ + uint32 tstart; + char *bufp; + uint8 lbuf[32]; + uint8 buf[1024]; + uint8 buf2[1024]; + + sim_debug(DEBUG_CMD, dptr, + "disk_srv entry unit %02x CMD %08x chsa %04x count %04x %x/%x/%x \n", + unit, uptr->CMD, chsa, chp->ccw_count, + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + if (cmd != DSK_SNS) { /* we are completed with unit check status */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + } + + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv cmd=%02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count); + + switch (cmd) { + case 0: /* No command, stop disk */ + break; + + case DSK_ICH: /* 0xFF Initialize controller */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv cmd CONT INCH %06x chsa %04x addr %06x count %04x completed\n", + chp->chan_inch_addr, chsa, mema, chp->ccw_count); + /* to use this inch method, byte count must be 896 */ + if (len != 896) { + /* we have invalid count, error, bail out */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* now call set_inch() function to write and test inch buffer addresses */ + /* 1-224 wd buffer is provided, status is 128 words offset from start */ + mema += (128*4); /* offset to inch buffers */ + tstart = set_inch(uptr, mema, 33); /* new address of 33 entries */ + if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_INCH2: /* use 0xF0 for inch, just need int */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n", + chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count); + + /* mema has IOCD word 1 contents. For the disk processor it contains */ + /* a pointer to the INCH buffer followed by 8 drive attribute words that */ + /* contains the flags, sector count, MHD head count, and FHD count */ + /* len has the byte count from IOCD wd2 and should be 0x24 (36) */ + /* the INCH buffer address must be set for the parent channel as well */ + /* as all other devices on the channel. Call set_inch() to do this for us */ + /* just return OK and channel software will use u4 as status buffer addr */ + + if (len != 36) { + /* we have invalid count, error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* read all 36 bytes, stopping every 4 bytes to make words */ + /* the first word has the inch buffer address */ + /* the next 8 words have drive data for each unit */ + /* WARNING 8 drives must be defined for this controller */ + /* so we will not have a map fault */ + for (i=0; i < 36; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (((i+1)%4) == 0) { /* see if we have a word yet */ + if (i == 3) + /* inch buffer address */ + mema = (buf[0]<<24) | (buf[1]<<16) | + (buf[2]<<8) | (buf[3]); + else + /* drive attribute registers */ + /* may want to use this later */ + /* clear warning errors */ + tstart = (buf[i-3]<<24) | (buf[i-2]<<16) + | (buf[i-1]<<8) | (buf[i]); + } + } + /* now call set_inch() function to write and test inch buffer addresses */ + /* 1-224 wd buffer is provided, status is 128 words offset from start */ + mema += (128*4); /* offset to inch buffers */ + i = set_inch(uptr, mema, 33); /* new address of 33 entries */ + if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv cmd INCH %06x chsa %04x addr %06x count %04x completed\n", + chp->chan_inch_addr, chsa, mema, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_RES: /* 0x23 Reserve */ + case DSK_REL: /* 0x33 Release */ + case DSK_NOP: /* NOP 0x03 */ + /* diags want chan prog check and cmd reject if 1st cmd of IOCL */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv cmd NOP chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_RAP: /* 0xA2 Read angular positions */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* get STAR (target sector) data in STAR */ + cyl = STAR2CYL(uptr->CHS); /* get current cyl */ + trk = (uptr->CHS >> 8) & 0xff; /* get trk/head */ + sec = uptr->CHS & 0xff; /* set sec */ + + ch = ((2*SPT(type))-1) & 0x3f; /* get index cnt */ + uptr->SNS2 = (uptr->SNS2 & 0xc0ff) | ((((uint32)ch) & 0x3f) << 8); + sim_debug(DEBUG_CMD, dptr, + "disk_srv RAP %02x cyl %04x trk %02x sec %02x\n", + ch, cyl&0xffff, trk, sec); + + if (chan_write_byte(chsa, &ch)) { /* put a byte to memory */ + sim_debug(DEBUG_CMD, dptr, + "DISK RAP %02x for addr /%04x/%02x/%02x\n", + ch, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + if (chp->chan_status & STATUS_PCHK) { /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + } else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_IHA: /* 0x47 Increment head address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* get STAR (target sector) data in STAR */ + cyl = STAR2CYL(uptr->CHS); /* get current cyl */ + trk = (uptr->CHS >> 8) & 0xff; /* get trk/head */ + sec = 0; /* set sec to zero for this head */ + + sim_debug(DEBUG_CMD, dptr, + "disk_srv IHA cyl %04x trk %02x sec %02x unit=%02x\n", + cyl&0xffff, trk, sec, unit); + + /* Check if head increment valid */ + trk += 1; /* increment the head # */ + if (trk >= disk_type[type].nhds) { /* see if too big */ + trk = 0; /* back to trk 0 */ + cyl += 1; /* next cylinder */ + if (cyl >= disk_type[type].cyl) { /* see if too big */ + /* set new STAR value using new values */ + uptr->CHS = CHS2STAR(cyl, trk, sec); + sim_debug(DEBUG_EXP, dptr, + "disk_srv IHA ERROR cyl %04x trk %02x sec %02x unit=%02x\n", + cyl, trk, sec, unit); + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* error */ + break; + } + } + + /* set new STAR value using new values */ + uptr->CHS = CHS2STAR(cyl, trk, sec); + /* get alternate track if this one is defective */ + tempt = get_dmatrk(uptr, uptr->CHS, lbuf); + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(tempt, SPT(type), SPC(type)) * SSB(type); + + if ((tempt == 0) && (uptr->CHS != 0)) { + /* we have error */ + sim_debug(DEBUG_EXP, dptr, + "disk_srv IHA get_dmatrk return error tempt %06x tstart %06x CHS %08x\n", + tempt, tstart, uptr->CHS); + goto iha_error; + } + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ +iha_error: + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + sim_debug(DEBUG_EXP, dptr, "disk_srv IHA error on seek to %04x\n", tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_REC: /* 0xB2 */ /* Read ECC correction code */ + sim_debug(DEBUG_CMD, dptr, "disk_srv CMD REC Read ECC\n"); + /* count must be 4, if not prog check */ + if (len != 4) { + sim_debug(DEBUG_CMD, dptr, + "disk_srv REC bad count unit=%02x count%04x CHS %08x\n", + unit, len, uptr->CHS); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK|STATUS_LENGTH); + break; + } + /* create offset and mask */ + ecc = dmle_ecc32(obuf, ssize); /* calc ecc for original sector */ + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv DEC old obuf data %02x%02x%02x%02x %02x%02x%02x%02x\n", + obuf[1016], obuf[1017], obuf[1018], obuf[1019], + obuf[1020], obuf[1021], obuf[1022], obuf[1023]); + cecc = dmle_ecc32(bbuf, ssize); /* calc ecc for bad sector */ + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv DEC bad bbuf data %02x%02x%02x%02x %02x%02x%02x%02x\n", + bbuf[1016], bbuf[1017], bbuf[1018], bbuf[1019], + bbuf[1020], bbuf[1021], bbuf[1022], bbuf[1023]); + mema = 0; + for (i=0, j=0; i>= 1; /* move mask right */ + } + tcyl = (k * 8) + sec; /* starting bit# */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv REC sb# %04x byte# %04x mask %06x start %08x\n", + sec, k, mema, tcyl); + /* 16 bit sector offset and 9 of 16 bit mask */ + /* tcyl - fake 14 bit offset */ + /* mema - fake 9 bit mask */ + buf[0] = (tcyl & 0x3f00) >> 8; /* upper 6 bits */ + buf[1] = tcyl & 0xff; /* lower 8 bits */ + buf[2] = (mema & 0x100) >> 8; /* upper 1 bits */ + buf[3] = mema & 0xff; /* lower 8 bits */ + /* write the offset and mask data */ + for (i=0; i<4; i++) { + ch = buf[i]; /* get a char from buffer */ + if (chan_write_byte(chsa, &ch)) { /* put a byte to memory */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv DEC read %04x bytes of %04x\n", + i, chp->ccw_count); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + } + sim_debug(DEBUG_CMD, dptr, + "disk_srv wrote DEC offset %04x mask %04x CHS %08x\n", + tcyl & 0x3fff, mema & 0x1ff, uptr->CHS); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_SNS: /* 0x04 */ /* Sense */ + sim_debug(DEBUG_CMD, dptr, "disk_srv CMD sense\n"); + + /* count must be 12 or 14, if not prog check */ + if (len != 12 && len != 14) { + sim_debug(DEBUG_EXP, dptr, + "disk_srv Sense bad count unit=%02x count%04x\n", unit, len); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK|STATUS_LENGTH); + break; + } + /* bytes 0,1 - Cyl entry from CHS reg */ + ch = (uptr->CHS >> 24) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "disk_srv sense CHS b0 unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->CHS >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "disk_srv sense CHS b1 unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 2 - Track entry from CHS reg */ + ch = (uptr->CHS >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "disk_srv sense CHS b2 unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 3 - Sector entry from CHS reg */ + ch = (uptr->CHS) & 0xff; + sec = ch; + sim_debug(DEBUG_DETAIL, dptr, "disk_srv sense CHS b3 unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 4 - mode reg, byte 0 of SNS */ + ch = (uptr->SNS >> 24) & 0xff; /* return the sense data */ + sim_debug(DEBUG_DETAIL, dptr, "disk_srv sense unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* bytes 5-7 - status bytes, bytes 1-3 of SNS */ + ch = (uptr->SNS >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "disk_srv sense unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "disk_srv sense unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "disk_srv sense unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 8-11 - drive mode register entries from assigned disk */ + ch = disk_type[type].type & 0x40; /* zero bits 0, 2-7 in type byte */ + sim_debug(DEBUG_DETAIL, dptr, "disk_srv datr unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = disk_type[type].spt & 0xff; /* get sectors per track */ + sim_debug(DEBUG_DETAIL, dptr, "disk_srv datr unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = disk_type[type].nhds & 0xff; /* get # MHD heads */ + sim_debug(DEBUG_DETAIL, dptr, "disk_srv datr unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = 0; /* no FHD heads */ + sim_debug(DEBUG_DETAIL, dptr, "disk_srv datr unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 12 & 13 are optional, so check if read done */ + /* TODO add drive status bits here */ + if ((test_write_byte_end(chsa)) == 0) { + /* bytes 12 & 13 contain drive related status */ + uptr->SNS2 |= (SNS_SEND|SNS_USEL); /* selected & seek end */ + /* bits 2-7 have sector pulse count */ + ch = ((sec * 2) % SPT(type)) & 0x3f;/* get index cnt */ + uptr->SNS2 = (uptr->SNS2 & 0xc0ff) | ((((uint32)ch) & 0x3f) << 8); + ch = (uptr->SNS2 >> 8) & 0xff; /* seek end and unit selected for now */ + sim_debug(DEBUG_DETAIL, dptr, "disk_srv dsr unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + ch = uptr->SNS2 & 0xff; /* drive on cylinder and ready for now */ + sim_debug(DEBUG_DETAIL, dptr, "disk_srv dsr unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + } + uptr->SNS &= 0xff000000; /* reset status */ + uptr->SNS2 = 0; /* reset status */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_SCK: /* Seek cylinder, track, sector 0x07 */ + /* If we are waiting on seek to finish, check if there yet. */ + if (uptr->CMD & DSK_SEEKING) { + /* see if on cylinder yet */ + if (STAR2CYL(uptr->STAR) == STAR2CYL(uptr->CHS)) { + /* we are on cylinder, seek is done */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv seek on cylinder unit %02x new %04x old %04x\n", + unit, uptr->STAR>>16, uptr->CHS>>16); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS2 |= (SNS_SEND|SNS_ONC); /* On cylinder & seek done */ + /* we have already seeked to the required sector */ + /* we do not need to seek again, so move on */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + break; + } else { + /* we have wasted enough time, we are there */ + /* we are on cylinder, seek is done */ + sim_debug(DEBUG_CMD, dptr, "disk_srv seek over on cylinder unit=%02x %04x %04x\n", + unit, uptr->STAR >> 16, uptr->CHS >> 16); + uptr->CHS = uptr->STAR; /* we are there */ +#ifdef FAST_FOR_UTX + sim_activate(uptr, 15); /* start things off */ +#else + sim_activate(uptr, 150); /* start things off */ +#endif + break; + } + } + + /* not seeking, so start a new seek */ + /* set buf data to current STAR values */ + tcyl = cyl = STAR2CYL(uptr->CHS); /* get current cyl */ + buf[0] = (cyl >> 8) & 0xff; /* split cylinder */ + buf[1] = cyl & 0xff; + buf[2] = (uptr->CHS >> 8) & 0xff; /* get trk/head */ + buf[3] = uptr->CHS & 0xff; /* get sec */ + + sim_debug(DEBUG_CMD, dptr, + "disk_srv current STAR unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + if (len > 4) { + sim_debug(DEBUG_EXP, dptr, + "disk_srv SEEK bad count unit %02x count %04x\n", unit, len); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK|STATUS_LENGTH); + break; + } + + /* Read in 1-4 character seek code */ + for (i = 0; i < 4; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + if (i == 0) { + sim_debug(DEBUG_EXP, dptr, + "disk_srv seek error unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* Disc addressing or seek error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + chp->ccw_count = len; /* restore count, huh? */ + return SCPE_OK; + break; + } + /* done reading, see how many we read */ + if (i == 1) { + /* UTX wants to set seek STAR to zero */ + buf[0] = buf[1] = buf[2] = buf[3] = 0; + break; + } + /* just read the next byte */ + } + } + chp->ccw_count = len; /* restore count for diag, huh? */ + /* else the cyl, trk, and sec are ready to update */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv STAR unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + /* save STAR (target sector) data in STAR */ + uptr->STAR = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); + cyl = STAR2CYL(uptr->STAR); /* get the cylinder */ + trk = buf[2]; /* get the track */ + sec = buf[3]; /* get sec */ + + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv NEW SEEK cyl %04x trk %02x sec %02x unit=%02x\n", + cyl&0xffff, trk, buf[3], unit); + + /* Check if seek valid */ + if (cyl >= disk_type[type].cyl || + trk >= disk_type[type].nhds || + buf[3] >= disk_type[type].spt) { + + sim_debug(DEBUG_EXP, dptr, + "disk_srv seek ERROR cyl %04x trk %02x sec %02x unit=%02x\n", + cyl, trk, buf[3], unit); + + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + + /* set new STAR value, even if invalid */ + uptr->CHS = CHS2STAR(cyl, trk, buf[3]); + + /* we have an error, tell user */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* end command */ + break; + } + + /* set new STAR value using new values */ + tempt = CHS2STAR(cyl, trk, sec); + /* get alternate track if this one is defective */ + tempt = get_dmatrk(uptr, tempt, lbuf); + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(tempt, SPT(type), SPC(type)) * SSB(type); + + if ((tempt == 0) && (uptr->STAR != 0)) { + /* we have error */ + sim_debug(DEBUG_EXP, dptr, + "disk_srv SEEK get_dmatrk return error tempt %06x tstart %06x, STAR %08x\n", + tempt, tstart, uptr->STAR); + } + + /* calc the new sector address of data */ + /* calculate file position in bytes of requested sector */ + /* set new STAR value using new values */ + uptr->STAR = CHS2STAR(cyl, trk, sec); + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(uptr->STAR, SPT(type), SPC(type)) * SSB(type); + + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv seek start %04x cyl %04x trk %02x sec %02x CHS %08x\n", + tstart, cyl, trk, buf[3], uptr->CHS); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "disk_srv Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* Check if already on correct cylinder */ + /* if not, do a delay to slow things down */ + if (STAR2CYL(uptr->STAR) != STAR2CYL(uptr->CHS)) { + int diff = ((int)tcyl - (int)cyl); + if (diff < 0) + diff = -diff; + /* Do a fake seek to kill time */ + uptr->CMD |= DSK_SEEKING; /* show we are seeking */ + sim_debug(DEBUG_EXP, dptr, + "disk_srv seeking unit=%02x to %04x/%02x/%02x from cyl %04x (%04x)\n", + unit, cyl, trk, buf[3], tcyl, diff); +#ifdef FAST_FOR_UTX + sim_activate(uptr, 15); /* start us off */ +#else + sim_activate(uptr, 400+diff); /* start us off */ +#endif + } else { + /* we are on cylinder/track/sector, so go on */ + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv done seeking to %04x cyl %04x trk %02x sec %02x\n", + tstart, cyl, trk, buf[3]); + /* set new STAR value */ + uptr->CHS = CHS2STAR(cyl, trk, buf[3]); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + } + break; + + case DSK_XEZ: /* 0x37 */ /* Rezero & Read IPL record */ + sim_debug(DEBUG_CMD, dptr, "XEZ REZERO IPL unit=%02x seek 0\n", unit); + /* Do a seek to 0 */ + uptr->STAR = 0; /* set STAR to 0, 0, 0 */ + uptr->CHS = 0; /* set current CHS to 0, 0, 0 */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CMD |= DSK_SCK; /* show as seek command */ + tstart = 0; /* byte offset is 0 */ + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "disk_srv Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* we are on cylinder/track/sector zero, so go on */ + sim_debug(DEBUG_DETAIL, dptr, "disk_srv done seek trk 0\n"); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + break; + + case DSK_LMR: /* 0x1F */ + sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x\n", unit); + /* Read in 1 character of mode data */ + if (chan_read_byte(chsa, &buf[0])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x old %x new %x\n", + unit, (uptr->SNS)&0xff, buf[0]); + uptr->CMD &= LMASK; /* remove old cmd */ + uptr->SNS &= MASK24; /* clear old mode data */ + uptr->SNS |= (buf[0] << 24); /* save mode value */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_TESS: /* 0xAB */ /* Test STAR (subchannel target address register) */ + len = chp->ccw_count; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + + /* set position data for current STAR values */ + cyl = STAR2CYL(uptr->CHS); /* get current cyl */ + trk = (uptr->CHS >> 8) & 0xff; /* get trk/head */ + sec = uptr->CHS & 0xff; /* get sec */ + buf[0] = (cyl >> 8) & 0xff; /* split cylinder */ + buf[1] = cyl & 0xff; + buf[2] = trk; /* get trk/head */ + buf[3] = sec; /* get sec */ + + sim_debug(DEBUG_CMD, dptr, + "disk_srv TESS STAR unit=%02x star %04x %02x %02x\n", + unit, cyl, trk, sec); + + /* a count of 0,1 is prog check */ + if (len <= 1) { + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + /* Read in 2-4 character tess code */ + for (i = 0; i < 4; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + if (i <= 1) { + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv TESS error unit=%02x star %04x %02x %02x\n", + unit, cyl, trk, sec); + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + break; + } + /* just read the next byte */ + } + } + tstart = SNS_CHNEND|SNS_DEVEND; /* set default status */ + /* if len = 2, set SNS_SM if tcyl > cyl */ + if (len == 2) { + tcyl = (buf[0] << 8) | buf[1]; /* test cyl */ + if (tcyl > cyl) + tstart |= SNS_SMS; /* set status modifier bit */ + } else + /* if len = 3, set SNS_SM if tcyl > cyl or tcyl == cyl & buf[2] >= trk */ + if (len == 3) { + tcyl = (buf[0] << 8) | buf[1]; /* test cyl */ + if ((tcyl > cyl) || ((tcyl == cyl) && (buf[2] >= trk))) + tstart |= SNS_SMS; /* set status modifier bit */ + } else + /* if len = 4, set SNS_SM if tcyl > cyl or */ + /* if (tcyl == cyl and buf[2] >= trk) */ + /* or if (tcyl == cyl and buf[2] == trk and buf[3] >= sec) */ + if (len >= 4) { + tcyl = (buf[0] << 8) | buf[1]; /* test cyl */ + if ((tcyl > cyl) || ((tcyl == cyl) && (buf[2] >= trk)) || + ((tcyl == cyl) && (buf[2] == trk) && (buf[3] >= sec))) + tstart |= SNS_SMS; /* set status modifier bit */ + } + /* else the cyl, trk, and sect are ready to update */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv tess STAR unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + chan_end(chsa, tstart); + break; + + case DSK_FNSK: /* 0x0B Format for no skip */ + /* buffer must be on halfword boundry if not STATUS_PCHK and SNS_CMDREJ status */ + /* byte count can not exceed 20160 for the track */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "DISK Format starting CMD %08x chsa %04x buffer %06x count %04x\n", + uptr->CMD, chsa, chp->ccw_addr, chp->ccw_count); + sim_debug(DEBUG_DETAIL, dptr, "Format %x label", uptr->CHS); + /* now read sector label data */ + len = chp->ccw_count; + for (i = 0; i < len; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have write error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + if ((i%16) == 0) + sim_debug(DEBUG_DETAIL, dptr, "\nFormat %x label", uptr->CHS); + sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_DETAIL, dptr, "\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_RD: /* Read Data command 0x02 */ + if ((uptr->CMD & DSK_READING) == 0) { /* see if we are reading data */ + uptr->CMD |= DSK_READING; /* read from disk starting */ + sim_debug(DEBUG_CMD, dptr, + "DISK READ starting CMD %08x chsa %04x buffer %06x count %04x\n", + uptr->CMD, chsa, chp->ccw_addr, chp->ccw_count); + } + + if (uptr->CMD & DSK_READING) { /* see if we are reading data */ + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = disksec2star(tstart, type); + + sim_debug(DEBUG_CMD, dptr, + "DISK B4READ reading CMD %08x chsa %04x tstart %04x buffer %06x count %04x\n", + uptr->CMD, chsa, tstart, chp->ccw_addr, chp->ccw_count); + + /* get alternate track if this one is defective */ + tempt = get_dmatrk(uptr, uptr->CHS, lbuf); + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(tempt, SPT(type), SPC(type)) * SSB(type); + + sim_debug(DEBUG_CMD, dptr, + "DISK FTRREAD reading CMD %08x chsa %04x tstart %04x buffer %06x count %04x\n", + uptr->CMD, chsa, tstart, chp->ccw_addr, chp->ccw_count); + + if ((tempt == 0) && (uptr->STAR != 0)) { + /* we have error */ + sim_debug(DEBUG_EXP, dptr, + "disk_srv READ1 get_dmatrk return error tempt %06x tstart %06x\n", tempt, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + sim_debug(DEBUG_EXP, dptr, "disk_srv READ error on seek to %04x\n", tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + uptr->SNS &= ~SNS_DEFTRK; /* remove defective flag */ + /* see if spare track */ + if (lbuf[4] & 0x20) { /* see if spare track */ + uptr->SNS |= SNS_DADE; /* disk addr error */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_EXP, dptr, + "disk_srv READ2 get_dmatrk return spare tempt %06x tstart %06x LASTCNT %04x\n", + tempt, tstart, uptr->LASTCNT); + /* restore original transfer count */ + chp->ccw_count = uptr->LASTCNT; /* restore original transfer count */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + /* see if reserved track */ + if (lbuf[4] & 0x10) { /* see if reserved track */ + uptr->SNS |= SNS_MOCK; /* mode check error */ + uptr->SNS |= SNS_RTAE; /* reserved track access error */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_EXP, dptr, + "disk_srv READ3 get_dmatrk return spare tempt %06x tstart %06x LASTCNT %04x\n", + tempt, tstart, uptr->LASTCNT); + /* restore original transfer count */ + chp->ccw_count = uptr->LASTCNT; /* restore original transfer count */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "disk_srv READ, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "DISK READ reading CMD %08x chsa %04x tstart %04x buffer %06x count %04x\n", + uptr->CMD, chsa, tstart, chp->ccw_addr, chp->ccw_count); + + /* read in a sector of data from disk */ + if ((len=sim_fread(buf, 1, ssize, uptr->fileref)) != ssize) { + sim_debug(DEBUG_EXP, dptr, + "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, ssize, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "disk_srv after READ chsa %04x buffer %06x count %04x\n", + chsa, chp->ccw_addr, chp->ccw_count); + bufp = dump_buf(buf, 0, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 16, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 32, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); +#ifdef EXTRA_WORDS + bufp = dump_buf(buf, 48, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); +if ((chp->ccw_addr == 0x3cde0) && (buf[0] == 0x4a)) { + bufp = dump_buf(buf, 64, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 80, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 96, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 112, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 128, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 144, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 160, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); + bufp = dump_buf(buf, 176, 16); + sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp); +} +#endif + uptr->CHS++; /* next sector number */ + /* process the next sector of data */ + for (i=0; ichan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + sim_debug(DEBUG_EXP, dptr, + "DISK READ4 %04x bytes leaving %04x from diskfile %04x/%02x/%02x\n", + i, chp->ccw_count, ((uptr->CHS)>>16)&0xffff, + ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + } + + /* get current sector offset */ + j = STAR2SEC(tempt, SPT(type), SPC(type)); /* current sector */ + i = ((CYL(type) - 3) * HDS(type)) * SPT(type); /* diag start */ + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv after READ j %04x i %04x j-i %04x CAP %06x DIAG %06x\n", + j, i, j-i, CAP(type), (((CYL(type) - 3) * HDS(type)) * SPT(type))); /* diag start */ + if (j >= i) { /* only do diag sectors */ + cecc = dmle_ecc32(buf, ssize); /* calc ecc for sector */ + sim_debug(DEBUG_DETAIL, dptr, + "ECC j %02x i %02x data calc Old %08x Cur %08x cyl %04x hds %02x sec %02x\n", + j, i, decc[j-i], cecc, STAR2CYL(tempt), ((tempt) >> 8)&0xff, (tempt&0xff)); + if ((decc[j-i] != 0) && (cecc != decc[j-i])) { /* test against old */ + /* checksum error */ + sim_debug(DEBUG_EXP, dptr, + "ECC j %02x i %02x data error Old %08x New %08x cyl %04x hds %02x sec %02x\n", + j, i, decc[j-i], cecc, STAR2CYL(tempt), ((tempt) >> 8)&0xff, (tempt&0xff)); + uptr->SNS |= SNS_ECCD; /* data ECC error */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_CHECK|STATUS_EXPT); + return SCPE_OK; + } + } + + /* see if this is a read ECC from diag */ + /* mode byte will be 0x08 and remaining count will be 4 */ + if ((uptr->SNS & SNS_DIAGMOD) && (chp->ccw_count == 4)) { + for (i=0; iCHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + /* set ECC value here */ + for (i=0; i<4; i++) { + ch = (ecc >> ((3-i)*8)) & 0xff; /* get a char from buffer */ + if (chan_write_byte(chsa, &ch)) { /* put a byte to memory */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + return SCPE_OK; + } + } + sim_debug(DEBUG_CMD, dptr, + "Read ECC %04x for diags 4 bytes to ECC REG cyl %04x hds %02x sec %02x\n", + ecc, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + } + + sim_debug(DEBUG_CMD, dptr, + "DISK READ %04x bytes leaving %4x to be read to %06x from diskfile %04x/%02x/%02x\n", + ssize, chp->ccw_count, chp->ccw_addr, + ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + + /* get sector offset */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + + /* see if over end of disk */ + if (tstart >= (uint32)CAP(type)) { + /* EOM reached, abort */ + sim_debug(DEBUG_EXP, dptr, + "DISK Read reached EOM for read from disk @ /%04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CHS = 0; /* reset cylinder position */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* see if we are done reading data */ + if (test_write_byte_end(chsa)) { + sim_debug(DEBUG_CMD, dptr, + "DISK Read complete for read from diskfile %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "DISK sector read complete, %x bytes to go from diskfile %04x/%02x/%02x\n", + chp->ccw_count, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); +#ifdef FAST_FOR_UTX + sim_activate(uptr, 10); /* wait to read next sector */ +#else + sim_activate(uptr, 300); /* wait to read next sector */ +#endif + break; + } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + break; + + case DSK_WD: /* Write Data command 0x01 */ + if ((uptr->CMD & DSK_WRITING) == 0) { /* see if we are writing data */ + sim_debug(DEBUG_CMD, dptr, + "DISK WRITE starting unit=%02x CMD %08x write %04x from %06x to %03x/%02x/%02x\n", + unit, uptr->CMD, chp->ccw_count, chp->ccw_addr, + ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + + if (uptr->SNS & 0xf0000000) { /* see if any mode bit 0-3 is set */ + sim_debug(DEBUG_CMD, dptr, + "DISK WRITE2 starting CMD %08x chsa %04x buffer %06x count %04x\n", + uptr->CMD, chsa, chp->ccw_addr, chp->ccw_count); + uptr->SNS |= SNS_MOCK; /* mode check error */ + chp->chan_status |= STATUS_PCHK; /* channel prog check */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + uptr->CMD |= DSK_WRITING; /* write to disk starting */ + } + if (uptr->CMD & DSK_WRITING) { /* see if we are writing data */ + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + /* file offset in bytes */ + tstart = tstart * SSB(type); + + /* get alternate track if this one is defective */ + tempt = get_dmatrk(uptr, uptr->CHS, lbuf); + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(tempt, SPT(type), SPC(type)) * SSB(type); + + if ((tempt == 0) && (uptr->STAR != 0)) { + /* we have error */ + sim_debug(DEBUG_EXP, dptr, + "disk_srv WRITE get_dmatrk return error tempt %06x tstart %06x\n", + tempt, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + sim_debug(DEBUG_EXP, dptr, "disk_srv WRITE error on seek to %04x\n", tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + uptr->SNS &= ~SNS_DEFTRK; /* remove defective flag */ + /* see if spare track */ + if (lbuf[4] & 0x20) { /* see if spare track */ + uptr->SNS |= SNS_DADE; /* disk addr error */ + chp->chan_status |= STATUS_PCHK; /* channel prog check */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + /* see if reserved track */ + if (lbuf[4] & 0x10) { /* see if reserved track */ + uptr->SNS |= SNS_MOCK; /* mode check error */ + uptr->SNS |= SNS_RTAE; /* reserved track access error */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "disk_srv WRITE, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* process the next sector of data */ + tcyl = 0; /* used here as a flag for short read */ + for (i=0; ichan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* if error on reading 1st byte, we are done writing */ + if ((i == 0) || (chp->chan_status & STATUS_PCHK)) { + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_EXP, dptr, + "DISK Wrote %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + ch = 0; /* finish out the sector with zero */ + tcyl++; /* show we have no more data to write */ + } + buf2[i] = ch; /* save the char */ + } + + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = disksec2star(tstart, type); + + /* write the sector to disk */ + if ((i=sim_fwrite(buf2, 1, ssize, uptr->fileref)) != ssize) { + sim_debug(DEBUG_EXP, dptr, + "Error %08x on write %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + i, ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "disk_srv after WRITE buffer %06x count %04x\n", + chp->ccw_addr, chp->ccw_count); + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv WRITE data %02x%02x%02x%02x %02x%02x%02x%02x " + "%02x%02x%02x%02x %02x%02x%02x%02x\n", + buf2[0], buf2[1], buf2[2], buf2[3], buf2[4], buf2[5], buf2[6], buf2[7], + buf2[8], buf2[9], buf2[10], buf2[11], buf2[12], buf2[13], buf2[14], buf2[15]); + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv after WRITE CAP %06x DIAG %06x\n", + CAP(type), (((CYL(type) - 3) * HDS(type)) * SPT(type))); /* diag start */ + + /* get current sector offset */ + j = STAR2SEC(tempt, SPT(type), SPC(type)); /* current sector */ + i = ((CYL(type) - 3) * HDS(type)) * SPT(type); /* diag start */ + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv after WRITE j %04x i %04x j-i %04x CAP %06x DIAG %06x\n", + j, i, j-i, CAP(type), (((CYL(type) - 3) * HDS(type)) * SPT(type))); /* diag start */ + if (j >= i) { /* only do diag sectors */ + cecc = dmle_ecc32(buf2, ssize); /* calc ecc for sector */ + sim_debug(DEBUG_DETAIL, dptr, + "ECC j %02x i %02x data write Old %08x Cur %08x cyl %04x hds %02x sec %02x\n", + j, i, decc[j-i], cecc, STAR2CYL(tempt), ((tempt) >> 8)&0xff, (tempt&0xff)); + decc[j-i] = cecc; /* set new ecc */ + } + j = j-i; /* save index */ + + /* see if this is a write ECC from diag */ + /* mode byte will be 0x08 and remaining count will be 4 */ + if ((uptr->SNS & SNS_DIAGMOD) && (chp->ccw_count == 4)) { + for (i=0; iCHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + /* set ECC value here */ + for (i=0; i<4; i++) { + if (chan_read_byte(chsa, &ch)) {/* get a byte from memory */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + return SCPE_OK; + } + /* get an ECC byte */ + buf[i] = ch; /* put a char to buffer */ + ecc |= ((ch & 0xff) << ((3-i)*8)); + } + tcyl++; /* show we have no more data to write */ + sim_debug(DEBUG_DETAIL, dptr, + "Write decc[%04x] ECC=%08x from diags, calc ECC=%08x cyl %04x hds %02x sec %02x\n", + j, ecc, cecc, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + decc[j] = ecc; /* set new ecc from diag */ + } + + sim_debug(DEBUG_CMD, dptr, + "DISK WR to sec end %04x bytes end %04x to diskfile cyl %04x hds %02x sec %02x\n", + len, ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + + uptr->CHS++; /* next sector number */ + if (tcyl != 0) { /* see if done with write command */ + sim_debug(DEBUG_CMD, dptr, + "DISK WroteB %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + } + /* get sector offset */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + + /* see if over end of disk */ + if (tstart >= (uint32)CAP(type)) { + /* EOM reached, abort */ + sim_debug(DEBUG_EXP, dptr, + "DISK Write reached EOM for write to disk @ %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CHS = 0; /* reset cylinder position */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* see if we are done reading data */ + if (test_write_byte_end(chsa)) { + sim_debug(DEBUG_CMD, dptr, + "DISK Write complete for read from diskfile %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + +#ifdef FAST_FOR_UTX + sim_activate(uptr, 15); /* wait to read next sector */ +#else + sim_activate(uptr, 300); /* wait to read next sector */ +#endif + break; + } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + break; + + case DSK_RSL: /* RSL 0x32 */ + /* Read sector label zero to get disk geometry */ + /* write 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + /* zero the Track Label Buffer */ + for (i = 0; i < 30; i++) + buf[i] = 0; + + len = chp->ccw_count; /* get number bytes to read */ + mema = uptr->CHS+(len/30); /* save address */ + + sim_debug(DEBUG_DETAIL, dptr, + "before RSL Sector %x len %x\n", uptr->CHS, len); + + /* read a 30 byte track label for each sector on track */ + /* for 16 sectors per track, that is 480 bytes */ + /* for 20 sectors per track, that is 600 bytes */ + for (j=0; jCHS, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = disksec2star(tstart, type); + + cyl = (uptr->CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (uptr->CHS >> 8) & 0xff; /* get the track */ + sec = uptr->CHS & 0xff; /* get sec */ + seeksec = tstart; /* save sector number */ + + sim_debug(DEBUG_EXP, dptr, + "disk_srv RSL cyl %04x trk %02x sec %02x sector# %06x\n", + cyl, trk, sec, seeksec); + + /* seek sector label area after end of track label area */ + tstart = CAPB(type) + (CYL(type)*HDS(type)*30) + (tstart*30); + + /* file offset in bytes to sector label */ + sim_debug(DEBUG_EXP, dptr, + "disk_srv RSL SEEK on seek to %08x\n", tstart); + + /* seek to the location where we will read sector label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { + sim_debug(DEBUG_EXP, dptr, + "Error seeking sector label area at sect %06x offset %08x\n", + seeksec, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + + /* read in a sector label from disk */ + if (sim_fread(buf, 1, 30, uptr->fileref) != 30) { + sim_debug(DEBUG_EXP, dptr, + "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + + sim_debug(DEBUG_DETAIL, dptr, "Sector %x label", uptr->CHS); + /* now write sector label data */ + for (i = 0; i < 30; i++) { + if (chan_write_byte(chsa, &buf[i])) { + /* we have write error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_DETAIL, dptr, "\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + if (i == 16) + sim_debug(DEBUG_DETAIL, dptr, "\nSector %x label", uptr->CHS); + sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_DETAIL, dptr, "\n"); + + /* leave STAR "unnormalized" for diags */ + uptr->CHS++; /* bump to next sector */ + if ((uptr->CHS & 0xff) == SPC(type)) + break; /* stop at last sector */ + len -= 30; /* count 1 sector label size */ + if (len > 0) + continue; + break; /* done */ + } + + uptr->CHS = mema; /* restore address */ + + sim_debug(DEBUG_DETAIL, dptr, "after RSL Sector %x len %x\n", uptr->CHS, chp->ccw_count); + + /* command done */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "disk_srv cmd RSL done chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_WSL: /* WSL 0x31 write sector labels */ + /* Write sector label to disk */ + /* write 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + len = chp->ccw_count; /* get number bytes to read */ + mema = uptr->CHS; /* save address */ + + sim_debug(DEBUG_DETAIL, dptr, "before WSL Sector %x len %x\n", uptr->CHS, len); + + /* read a 30 byte sector label for each sector on track */ + /* for 16 sectors per track, that is 480 bytes */ + /* for 20 sectors per track, that is 600 bytes */ + for (j=0; jCHS); + /* now read sector label data */ + for (i = 0; i < 30; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have read error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + if ((i%16) == 0) + sim_debug(DEBUG_DETAIL, dptr, "\nSector %x label", uptr->CHS); + sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_DETAIL, dptr, "\n"); + + /* see if user trying to set invalid bit pattern */ + if ((buf[4] & 0x48) == 0x48) { /* see if setting defective alternate trk */ + uptr->SNS |= SNS_DSKFERR; /* disk formating error */ + uptr->CHS = mema; /* restore address */ + chp->ccw_count = len; /* restore number bytes to read */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + return SCPE_OK; + break; + } + + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = disksec2star(tstart, type); + + cyl = (uptr->CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (uptr->CHS >> 8) & 0xff; /* get the track */ + sec = uptr->CHS & 0xff; /* get sec */ + seeksec = tstart; /* save sector number */ + + sim_debug(DEBUG_CMD, dptr, "disk_srv WSL cyl %04x trk %02x sec %02x sector# %06x\n", + cyl, trk, sec, seeksec); + + /* seek sector label area after end of track label area */ + tstart = CAPB(type) + (CYL(type)*HDS(type)*30) + (tstart*30); + + /* file offset in bytes to sector label */ + sim_debug(DEBUG_CMD, dptr, "disk_srv WSL SEEK on seek to %08x\n", tstart); + + /* seek to the location where we will write sector label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { + sim_debug(DEBUG_EXP, dptr, + "Error seeking sector label area at sect %06x offset %08x\n", + seeksec, tstart); + uptr->CHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + + /* write sector label to disk */ + if (sim_fwrite(buf, 1, 30, uptr->fileref) != 30) { + sim_debug(DEBUG_EXP, dptr, + "Error %08x on write %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + + /* leave STAR "unnormalized" for diags */ + uptr->CHS++; /* bump to next sector */ + if ((uptr->CHS & 0xff) == SPC(type)) + break; /* stop at last sector */ + len -= 30; /* count 1 sector label size */ + if (len > 0) + continue; + break; /* done */ + } + + uptr->CHS = mema; /* restore address */ + + sim_debug(DEBUG_DETAIL, dptr, "after WSL Sector %x len %x\n", uptr->CHS, chp->ccw_count); + + /* command done */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "disk_srv cmd WSL done chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_RTL: /* RTL 0x52 */ + /* Read track zero to get disk geometry */ + /* read 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + + /* zero the Track Label Buffer */ + for (i = 0; i < 30; i++) + buf[i] = 0; + uptr->CHS &= 0xffffff00; /* zero sector for trk read */ + mema = uptr->CHS; + + /* get file offset in sectors */ + tstart = STAR2SEC(mema, SPT(type), SPC(type)); + + /* convert sector number back to chs value to sync disk for diags */ + mema = disksec2star(tstart, type); + cyl = (mema >> 16) & 0xffff; /* get the cylinder */ + trk = (mema >> 8) & 0xff; /* get the track */ + + /* get track number */ + tstart = (cyl * HDS(type)) + trk; + sim_debug(DEBUG_CMD, dptr, "disk_srv RTL cyl %4x(%d) trk %x sec# %06x\n", + cyl, cyl, trk, tstart); + + /* calc offset in file to track label */ + tstart = CAPB(type) + (tstart * 30); + + /* file offset in bytes */ + sim_debug(DEBUG_CMD, dptr, "disk_srv RTL SEEK on seek to %06x\n", tstart); + + /* seek to the location where we will r/w track label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "disk_srv RTL, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* read in a track label from disk */ + if ((len=sim_fread(buf, 1, 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_EXP, dptr, + "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + if (buf[4] == 0x08) { /* see if defective track */ + uptr->SNS |= SNS_DEFTRK; /* flag as defective */ + sim_debug(DEBUG_DETAIL, dptr, "Track %08x is defective\n", uptr->CHS); + } + + if (buf[4] == 0x40) { /* see if alternate track */ + uptr->SNS |= SNS_AATT; /* flag as alternate */ + sim_debug(DEBUG_DETAIL, dptr, "Track %08x is alternate\n", uptr->CHS); + } + + /* now write track label data to memory */ + sim_debug(DEBUG_DETAIL, dptr, "Track %08x label", uptr->CHS); + for (i = 0; i < 30; i++) { + if (chan_write_byte(chsa, &buf[i])) { + /* we have write error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (i == 16) + sim_debug(DEBUG_DETAIL, dptr, "\nTrack %08x label", uptr->CHS); + sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_DETAIL, dptr, "\n"); + + /* command done */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "disk_srv cmd RTL done chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_WTL: /* WTL 0x51 */ + /* Write track zero to set disk geometry */ + /* write 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + + sim_debug(DEBUG_DETAIL, dptr, "disk_srv WTL start cnt %04x CHS %08x\n", + chp->ccw_count, uptr->CHS); + + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = disksec2star(tstart, type); + uptr->CHS &= 0xffffff00; /* zero sector for trk read */ + mema = uptr->CHS; + + cyl = (uptr->CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (uptr->CHS >> 8) & 0xff; /* get the track */ + + /* get track number */ + tstart = (cyl * HDS(type)) + trk; + sim_debug(DEBUG_CMD, dptr, "disk_srv WTL cyl %4x trk %x track# %06x CHS %08x\n", + cyl, trk, tstart, uptr->CHS); + + /* calc offset in file to track label */ + tstart = CAPB(type) + (tstart * 30); + + /* file offset in bytes */ + sim_debug(DEBUG_CMD, dptr, "disk_srv WTL SEEK on seek to %06x\n", tstart); + + /* seek to the location where we will write track label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "disk_srv WTL, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + sim_debug(DEBUG_DETAIL, dptr, "Track %08x label", uptr->CHS); + /* now read track label data from memory */ + for (i = 0; i < 30; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have read error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + if (i == 16) + sim_debug(DEBUG_DETAIL, dptr, "\nTrack %08x label", uptr->CHS); + sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_DETAIL, dptr, "\n"); + + /* see if user trying to set invalid bit pattern */ + if ((buf[4] & 0x48) == 0x48) { /* see if setting defective alternate trk */ + uptr->SNS |= SNS_DSKFERR; /* disk formating error */ + uptr->CHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + /* write out a track label to disk */ + if ((len=sim_fwrite(buf, 1, 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_EXP, dptr, + "Error %08x on write %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* clear cache entry for this track */ + /* see if track label is in cache */ + for (i=0; iCHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv cmd WTL chsa %04x count %04x completed CHS %08x\n", + chsa, chp->ccw_count, uptr->CHS); + + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + default: + sim_debug(DEBUG_EXP, dptr, "invalid command %02x unit %02x\n", cmd, unit); + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|STATUS_PCHK); /* return Prog Check */ + break; + } + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv done cmd %02x chsa %04x chs %04x/%02x/%02x\n", + cmd, chsa, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + return SCPE_OK; +} + +/* handle rschnlio cmds for disk */ +t_stat disk_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & DSK_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, + "disk_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + disk_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +/* initialize the disk */ +void disk_ini(UNIT *uptr, t_bool f) +{ + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); /* get the UNIT number */ + int i = GET_TYPE(uptr->flags); + int cn; + + /* start out at sector 0 */ + uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */ + uptr->STAR = 0; /* set STAR to cyl/hd/sec = 0 */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* total sectors on disk */ + uptr->capac = CAP(i); /* size in sectors */ + sim_cancel(uptr); /* stop any timers */ + /* reset track cache */ + for (cn=0; cnname, GET_UADDR(uptr->CMD), uptr->capac, uptr->capac); +} + +t_stat disk_reset(DEVICE *dptr) +{ + int cn, unit; + + for(unit=0; unit < NUM_UNITS_DISK; unit++) { + for (cn=0; cnflags); + DEVICE *dptr = get_dev(uptr); + uint32 trk, cyl, sec; + uint32 ssize = SSB(type); /* disk sector size in bytes */ + uint32 tsize = SPT(type); /* get track size in sectors */ + uint32 tot_tracks = TRK(type); /* total tracks on disk */ + uint32 tot_sectors = CAP(type); /* total number of sectors on disk */ + uint32 cap = CAP(type); /* disk capacity in sectors */ + uint32 CHS; /* cyl, hds, sec format */ + uint8 label[34]; /* track/sector label */ + int32 i, j; + /* get sector address of vendor defect table VDT */ + /* put data = 0xf0000000 0xf4000000 */ + int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type); + /* get sector address of utx diag map (DMAP) track 0 pointer */ + /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ + /* 0x9a000000 + (cyl-1), 0xf4000000 */ + int32 daddr = (CYL(type)-4) * SPC(type) + (HDS(type)-2) * SPT(type); + /* get sector address of utx flaw map sec 1 pointer */ + /* use this address for sec 1 label pointer */ + int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type); + + /* write 30 byte track labels for all tracks on disk */ + /* tot_tracks entries will be created starting at end of disk */ + /* seek first sector after end of disk data */ + if ((sim_fseek(uptr->fileref, CAPB(type), SEEK_SET)) != 0) { + sim_debug(DEBUG_EXP, dptr, + "Error seeking track label area at sect %06x offset %06x\n", + CAP(type), CAPB(type)); + return 1; + } + /* write track labels */ + for (i=0; i<(int)tot_tracks; i++) { + + /* zero the Track Label Buffer */ + for (j = 0; j < 30; j++) + label[j] = 0; + + sec = i * SPT(type); /* get track address in sectors */ + /* convert sector number to CHS value for label */ + CHS = disksec2star(sec, type); /* get current CHS value */ + + /* set buf data to current CHS values */ + if (CHS == 0) { /* write last address on trk 0 */ + cyl = CYL(type)-1; /* lcyl cyl upper 8 bits */ + trk = HDS(type)-1; /* ltkn trk */ + sec = SPT(type)-1; /* lid sector ID */ + } else { + /* write current address on other tracks */ + cyl = (CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (CHS >> 8) & 0xff; /* get the track */ + sec = (CHS) & 0xff; /* get the sector */ + } + + sim_debug(DEBUG_CMD, dptr, "disk_format WTL STAR %08x disk geom %08x\n", + CHS, GEOM(type)); + + /* set buf data to current STAR values */ + label[0] = (cyl >> 8) & 0xff; /* lcyl cyl upper 8 bits */ + label[1] = cyl & 0xff; /* lcyl cyl lower 8 bits */ + label[2] = trk & 0xff; /* ltkn trk */ + label[3] = sec & 0xff; /* lid sector ID */ + label[4] = 0x80; /* show good sector */ + if (i == (tot_tracks-1)) { /* last track? */ + label[3] = 0xff; /* lid show as last track label */ + label[4] |= 0x04; /* set last track flag */ + } + + sim_debug(DEBUG_CMD, dptr, + "disk_format WTL star %02x %02x %02x %02x\n", + label[0], label[1], label[2], label[3]); + + /* daddr has dmap value for track zero label */ + if (CHS == 0) { /* only write dmap address in trk 0 */ + /* output diag defect map address of disk */ + label[12] = (daddr >> 24) & 0xff; /* ldeallp DMAP pointer */ + label[13] = (daddr >> 16) & 0xff; + label[14] = (daddr >> 8) & 0xff; + label[15] = (daddr) & 0xff; + printf("disk_label WTL daddr@daddr %08x -> %08x\r\n", daddr, 0); + sim_debug(DEBUG_CMD, dptr, + "disk_label WTL daddr@daddr %08x -> %08x\n", vaddr, 0); + } + + /* write vaddr to track label for dmap */ + if ((i*SPT(type)) == daddr) { /* get track address in sectors */ + /* output vendor defect map address of disk */ + label[12] = (vaddr >> 24) & 0xff; /* Vaddr pointer */ + label[13] = (vaddr >> 16) & 0xff; + label[14] = (vaddr >> 8) & 0xff; + label[15] = (vaddr) & 0xff; + printf("disk_format WTL vaddr@daddr %08x -> %08x\r\n", vaddr, daddr); + sim_debug(DEBUG_CMD, dptr, + "disk_format WTL vaddr@daddr %08x -> %08x\n", vaddr, daddr); + } + /* if this is removed, utx is unable to create newfs */ + /* get preposterous size 0 error message */ + /* maybe not needed, but left anyway */ + /* uaddr has umap value for track zero label */ + if (CHS == 0) { /* only write dmap address in trk 0 */ + /* output umap address */ + label[16] = (uaddr >> 24) & 0xff; /* lumapp DMAP pointer */ + label[17] = (uaddr >> 16) & 0xff; + label[18] = (uaddr >> 8) & 0xff; + label[19] = (uaddr) & 0xff; + } + + /* the tech doc shows the cyl/trk/sec data is in the first 4 bytes */ + /* of the track label, BUT it is really in the configuration data */ + /* area too. Byte 27 is sectors/track and byte 28 is number of heads. */ + /* Byte 26 is mode. Byte 25 is copy of byte 27. */ + label[25] = SPT(type) & 0xff; + label[26] = disk_type[type].type & 0xfc; /* zero bits 6 & 7 in type byte */ + label[27] = SPT(type) & 0xff; + label[28] = HDS(type) & 0xff; + + if ((sim_fwrite((char *)&label, sizeof(uint8), 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_EXP, dptr, + "Error writing track label to sect %06x offset %06x\n", + cap+(i*tsize), cap*ssize+(i*tsize*ssize)); + return 1; + } + } + + /* write 30 byte sector labels for all sectors on disk */ + /* tot_sector entries will be created starting at end of disk */ + /* plus the track label area size. Seek first sector after end */ + /* of disk track label area */ + if ((sim_fseek(uptr->fileref, CAPB(type)+TRK(type)*30, SEEK_SET)) != 0) { + sim_debug(DEBUG_EXP, dptr, + "Error seeking sector label area at sect %06x offset %06x\n", + CAP(type)+TRK(type), CAPB(type)+TRK(type)*30); + return 1; + } + + /* zero the Sector Label Buffer */ + for (j = 0; j < 30; j++) + label[j] = 0; + + /* convert sector number to CHS value for label */ + /* write sector labels */ + for (i=0; i<(int)tot_sectors; i++) { + + CHS = disksec2star(i, type); /* get current CHS value */ + + /* set buf data to current CHS values */ + /* write current address on other tracks */ + cyl = (CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (CHS >> 8) & 0xff; /* get the track */ + sec = (CHS) & 0xff; /* get the sector */ + + sim_debug(DEBUG_CMD, dptr, "disk_format WSL STAR %08x disk geom %08x\n", + CHS, GEOM(type)); + + /* set buf data to current STAR values */ + label[0] = (cyl >> 8) & 0xff; /* lcyl cyl upper 8 bits */ + label[1] = cyl & 0xff; /* lcyl cyl lower 8 bits */ + label[2] = trk & 0xff; /* ltkn trk */ + label[3] = sec & 0xff; /* lid sector ID */ + label[4] = 0x80; /* show good sector */ + + sim_debug(DEBUG_CMD, dptr, + "disk_format WSL star %02x %02x %02x %02x\n", + label[0], label[1], label[2], label[3]); + + label[12] = 0; + label[13] = 0; + label[14] = 0; + label[15] = 0; + + /* the tech doc shows the cyl/trk/sec data is in the first 4 bytes */ + /* of the track label, BUT it is really in the configuration data */ + /* area too. Byte 27 is sectors/track and byte 28 is number of heads. */ + /* Byte 26 is mode. Byte 25 is copy of byte 27. */ + label[25] = disk_type[type].spt & 0xff; + /* The UDP/DPII controllers do not use these bits, so UTX keys */ + /* on these bits to determine type of controller. Bit 31 is set */ + /* for a HSDP and not set for the UDP/DPII */ + label[26] = disk_type[type].type & 0xfc; /* zero bits 6 & 7 in type byte */ + label[27] = disk_type[type].spt & 0xff; + label[28] = disk_type[type].nhds & 0xff; + + if ((sim_fwrite((char *)&label, sizeof(uint8), 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_CMD, dptr, + "Error writing sector label to sect %06x offset %06x\n", + i, CAPB(type)+TRK(type)*30+i*ssize); + return 1; + } + } + + /* seek home again */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + return SCPE_OK; /* good to go */ +} + +/* create the disk file for the specified device */ +int disk_format(UNIT *uptr) { + int type = GET_TYPE(uptr->flags); + DEVICE *dptr = get_dev(uptr); + uint32 ssize = SSB(type); /* disk sector size in bytes */ + uint32 tsize = SPT(type); /* get track size in sectors */ + uint32 csize = SPC(type); /* get cylinder size in sectors */ + uint32 cyl = CYL(type); /* get # cylinders */ + uint32 cap = CAP(type); /* disk capacity in sectors */ + uint32 cylv = cyl; /* number of cylinders */ + uint8 *buff; + int32 i; + t_stat oldsw = sim_switches; /* save switches */ + + /* last sector address of disk (cyl * hds * spt) - 1 */ + uint32 laddr = CAP(type) - 1; /* last sector of disk */ + + /* last track address of disk (cyl * hds * spt) - spt */ + uint32 ltaddr = CAP(type)-SPT(type); /* last track of disk */ + + /* get sector address of vendor defect table VDT */ + /* put data = 0xf0000000 0xf4000000 */ + int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type); + + /* get sector address of utx diag map (DMAP) track 0 pointer */ + /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ + /* 0x9a000000 + (cyl-1), 0xf4000000 */ + int32 daddr = (CYL(type)-4) * SPC(type) + (HDS(type)-2) * SPT(type); + + /* get sector address of utx flaw data (1 track long) */ + /* set trace data to zero */ + int32 faddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); + + /* get sector address of utx flaw map sec 1 pointer */ + /* use this address for sec 1 label pointer */ + int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type); + + /* vendor flaw map in vaddr */ + uint32 vmap[2] = {0xf0000004, 0xf4000000}; + + /* defect map */ + uint32 dmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr, + 0x9a000000 | (cap-1), 0xf4000000}; + + /* utx flaw map */ + uint32 fmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr, + 0x9a000000 | ltaddr, 0xf4000000}; + + /* see if -i or -n specified on attach command */ + if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) { + sim_switches = 0; /* simh tests 'N' & 'Y' switches */ + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { + sim_switches = oldsw; + return 1; + } + sim_switches = oldsw; /* restore switches */ + } + + /* VDT 249264 (819/18/0) 0x3cdb0 for 9346 - 823/19/16 vaddr */ + /* MDT 249248 (819/17/0) 0x3cda0 for 9346 - 823/19/16 daddr */ + /* UMAP 249216 (819/15/0) 0x3cd80 for 9346 - 823/19/16 uaddr */ + + /* seek to sector 0 */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + + /* get buffer for track data in bytes */ + if ((buff = (uint8 *)calloc(csize*ssize, sizeof(uint8))) == 0) { + detach_unit(uptr); + return SCPE_ARG; + } + sim_debug(DEBUG_CMD, dptr, + "Creating disk file of trk size %04x bytes, capacity %d\n", + tsize*ssize, cap*ssize); + + /* write zeros to each track of the disk */ + for (cyl = 0; cyl < cylv; cyl++) { + if ((sim_fwrite(buff, 1, csize*ssize, uptr->fileref)) != csize*ssize) { + sim_debug(DEBUG_EXP, dptr, + "Error on write to diskfile cyl %04x\n", cyl); + free(buff); /* free cylinder buffer */ + buff = 0; + return 1; + } + if ((cyl % 100) == 0) + fputc('.', stderr); + } + fputc('\r', stderr); + fputc('\n', stderr); + free(buff); /* free cylinder buffer */ + buff = 0; + + /* byte swap the buffers for dmap and umap */ + for (i=0; i<2; i++) { + vmap[i] = (((vmap[i] & 0xff) << 24) | ((vmap[i] & 0xff00) << 8) | + ((vmap[i] & 0xff0000) >> 8) | ((vmap[i] >> 24) & 0xff)); + } + for (i=0; i<4; i++) { + dmap[i] = (((dmap[i] & 0xff) << 24) | ((dmap[i] & 0xff00) << 8) | + ((dmap[i] & 0xff0000) >> 8) | ((dmap[i] >> 24) & 0xff)); + } + + for (i=0; i<4; i++) { + fmap[i] = (((fmap[i] & 0xff) << 24) | ((fmap[i] & 0xff00) << 8) | + ((fmap[i] & 0xff0000) >> 8) | ((fmap[i] >> 24) & 0xff)); + } + + /* now seek to end of disk and write the dmap data */ + /* setup dmap pointed to by track label 0 wd[3] = (cyl-4) * spt + (spt - 1) */ + + /* write dmap data to last sector on disk */ + if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */ + sim_debug(DEBUG_EXP, dptr, + "Error on last sector seek to sect %06x offset %06x\n", + cap-1, (cap-1)*ssize); + return 1; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_EXP, dptr, + "Error writing DMAP to sect %06x offset %06x\n", + cap-1, (cap-1)*ssize); + return 1; + } + + /* seek to vendor label area VMAP */ + if ((sim_fseek(uptr->fileref, vaddr*ssize, SEEK_SET)) != 0) { /* seek VMAP */ + sim_debug(DEBUG_EXP, dptr, + "Error on vendor map seek to sect %06x offset %06x\n", + vaddr, vaddr*ssize); + return 1; + } + if ((sim_fwrite((char *)&vmap, sizeof(uint32), 2, uptr->fileref)) != 2) { + sim_debug(DEBUG_CMD, dptr, + "Error writing VMAP to sect %06x offset %06x\n", + vaddr, vaddr*ssize); + return 1; + } + + /* write DMAP to daddr that is the address in trk 0 label */ + if ((sim_fseek(uptr->fileref, daddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */ + sim_debug(DEBUG_CMD, dptr, + "Error on diag map seek to sect %06x offset %06x\n", + daddr, daddr*ssize); + return 1; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Error writing DMAP to sect %06x offset %06x\n", + daddr, daddr*ssize); + return 1; + } + + /* write dummy UTX DMAP to faddr */ + if ((sim_fseek(uptr->fileref, faddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */ + sim_debug(DEBUG_CMD, dptr, + "Error on media flaw map seek to sect %06x offset %06x\n", + faddr, faddr*ssize); + return 1; + } + if ((sim_fwrite((char *)&fmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Error writing UTX flaw map to sect %06x offset %06x\n", + faddr, faddr*ssize); + return 1; + } + + printf("Disk %s has %x (%d) cyl, %x (%d) hds, %x (%d) sec\r\n", + disk_type[type].name, CYL(type), CYL(type), HDS(type), HDS(type), + SPT(type), SPT(type)); + printf("writing to vmap sec %x (%d) bytes %x (%d)\r\n", + vaddr, vaddr, (vaddr)*ssize, (vaddr)*ssize); + printf("writing to dmap sec %x (%d) %x (%d) dmap to %x (%d) %x (%d)\r\n", + cap-1, cap-1, (cap-1)*ssize, (cap-1)*ssize, + daddr, daddr, daddr*ssize, daddr*ssize); + printf("writing to fmap sec %x (%d) bytes %x (%d)\r\n", + faddr, faddr, (faddr)*ssize, (faddr)*ssize); + printf("writing to umap sec %x (%d) bytes %x (%d)\r\n", + uaddr, uaddr, (uaddr)*ssize, (uaddr)*ssize); + + /* create labels for disk */ + i = disk_label(uptr); /* label disk */ + + /* seek home again */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + return i; /* good or error */ +} + +/* attach the selected file to the disk */ +t_stat disk_attach(UNIT *uptr, CONST char *file) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + int type = GET_TYPE(uptr->flags); + DEVICE *dptr = get_dev(uptr); + DIB *dibp = 0; + t_stat r,s; + uint32 ssize; /* sector size in bytes */ + uint32 info, good; + uint8 buff[1024]; + int i, j; + + /* last sector address of disk (cyl * hds * spt) - 1 */ + uint32 laddr = CAP(type) - 1; /* last sector of disk */ + /* get sector address of utx diag map (DMAP) track 0 pointer */ + /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ + /* 0x9a000000 + (cyl-1), 0xf4000000 */ + int32 daddr = (CYL(type)-4) * SPC(type) + (HDS(type)-2) * SPT(type); + /* defect map */ + uint32 dmap[4] = {0xf0000000 | (CAP(type)-1), 0x8a000000 | daddr, + 0x9a000000 | (CAP(type)-1), 0xf4000000}; + + for (i=0; i<4; i++) { /* byte swap data for last sector */ + dmap[i] = (((dmap[i] & 0xff) << 24) | ((dmap[i] & 0xff00) << 8) | + ((dmap[i] & 0xff0000) >> 8) | ((dmap[i] >> 24) & 0xff)); + } + + /* see if valid disk entry */ + if (disk_type[type].name == 0) { /* does the assigned disk have a name */ + detach_unit(uptr); /* no, reject */ + return SCPE_FMT; /* error */ + } + + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, + "ERROR===ERROR\nDisk device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nDisk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + /* have simulator attach the file to the unit */ + if ((r = attach_unit(uptr, file)) != SCPE_OK) + return r; + + uptr->capac = CAP(type); /* disk capacity in sectors */ + ssize = SSB(type); /* get sector size in bytes */ + for (i=0; i<(int)ssize; i++) + buff[i] = 0; /* zero the buffer */ + + sim_debug(DEBUG_CMD, dptr, + "Disk %s cyl %d hds %d sec %d ssiz %d capacity %d\n", + disk_type[type].name, disk_type[type].cyl, disk_type[type].nhds, + disk_type[type].spt, ssize, uptr->capac); /* disk capacity */ + printf("Disk %s cyl %d hds %d sec %d ssiz %d capacity %d\r\n", + disk_type[type].name, disk_type[type].cyl, disk_type[type].nhds, + disk_type[type].spt, ssize, uptr->capac); /* disk capacity */ + + /* see if -i or -n specified on attach command */ + if ((sim_switches & SWMASK('N')) || (sim_switches & SWMASK('I'))) { + goto fmt; /* user wants new disk */ + } + + /* seek to end of disk */ + if ((sim_fseek(uptr->fileref, 0, SEEK_END)) != 0) { + sim_debug(DEBUG_CMD, dptr, "UDP Disk attach SEEK end failed\n"); + printf("Disk attach SEEK end failed\r\n"); + goto fmt; /* not setup, go format */ + } + + s = ftell(uptr->fileref); /* get current file position */ + if (s == 0) { + sim_debug(DEBUG_CMD, dptr, "UDP Disk attach ftell failed s=%06d\n", s); + printf("Disk attach ftell failed s=%06d\r\n", s); + goto fmt; /* not setup, go format */ + } + sim_debug(DEBUG_CMD, dptr, "UDP Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type)); + printf("Disk attach ftell value s=%06d b=%06d CAP %06d\r\n", s/ssize, s, CAP(type)); + + if (((int)s/(int)ssize) < ((int)CAP(type))) { /* full sized disk? */ + j = (CAP(type) - (s/ssize)); /* get # sectors to write */ + sim_debug(DEBUG_CMD, dptr, + "Disk attach for MPX 1.X needs %04d more sectors added to disk\n", j); + printf("Disk attach for MPX 1.X needs %04d more sectors added to disk\r\n", j); + /* must be MPX 1.X disk, extend to MPX 3.X size */ + /* write sectors of zero to end of disk to fill it out */ + for (i=0; ifileref) != ssize)) { + sim_debug(DEBUG_CMD, dptr, "Disk attach fread ret = %04d\n", r); + printf("Disk attach fread ret = %04d\r\n", r); + goto fmt; /* not setup, go format */ + } + } + s = ftell(uptr->fileref); /* get current file position */ + sim_debug(DEBUG_CMD, dptr, + "Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\n", s/ssize, s); + printf("Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\r\n", s/ssize, s); + } + + /* seek last sector of disk */ + if ((sim_fseek(uptr->fileref, (CAP(type)-1)*ssize, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, "UDP Disk attach SEEK last sector failed\n"); + printf("UDP Disk attach SEEK last sector failed\r\n"); + goto fmt; + } + + /* see if there is disk size-1 in last sector of disk, if not add it */ + if ((r = sim_fread(buff, sizeof(uint8), ssize, uptr->fileref) != ssize)) { + sim_debug(DEBUG_CMD, dptr, "UDP Disk format fread error = %04d\n", r); + printf("UDP Disk format fread error = %04d\r\n", r); +add_size: + /* write dmap data to last sector on disk for mpx 1.x */ + if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */ + sim_debug(DEBUG_CMD, dptr, + "Disk Error on last sector seek to sect %06d offset %06d bytes\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + printf("Disk Error on last sector seek to sect %06d offset %06d bytes\r\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + goto fmt; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Disk Error writing DMAP to sect %06x offset %06d bytes\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + printf("Disk Error writing DMAP to sect %06x offset %06d bytes\r\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + goto fmt; + } + + /* seek last sector of disk */ + if ((sim_fseek(uptr->fileref, (CAP(type))*ssize, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, "Disk attach SEEK last sector failed\n"); + printf("Disk attach SEEK last sector failed\r\n"); + goto fmt; + } + s = ftell(uptr->fileref); /* get current file position */ + sim_debug(DEBUG_CMD, dptr, + "UDP Disk attach MPX file extended & sized secs %06d bytes %06d\n", s/ssize, s); + printf("UDP Disk attach MPX file extended & sized secs %06d bytes %06d\r\n", s/ssize, s); + goto ldone; + } else { + /* if not disk size, go add it in for MPX, error if UTX */ + if ((buff[0] | buff[1] | buff[2] | buff[3]) == 0) { + sim_debug(DEBUG_CMD, dptr, + "UDP Disk format0 buf0 %02x buf1 %02x buf2 %02x buf3 %02x\n", + buff[0], buff[1], buff[2], buff[3]); + goto add_size; + } + } + + info = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3]; + good = 0xf0000000 | (CAP(type)-1); + /* check for 0xf0ssssss where ssssss is disk size-1 in sectors */ + if (info != good) { + sim_debug(DEBUG_EXP, dptr, + "Disk format error buf0 %02x buf1 %02x buf2 %02x buf3 %02x\n", + buff[0], buff[1], buff[2], buff[3]); + printf("Disk format error buf0 %02x buf1 %02x buf2 %02x buf3 %02x\r\n", + buff[0], buff[1], buff[2], buff[3]); +fmt: + /* format the drive */ + if (disk_format(uptr)) { + detach_unit(uptr); /* if no space, error */ + return SCPE_FMT; /* error */ + } + } + +ldone: + /* see if disk has labels already, seek to sector past end of disk */ + if ((sim_fseek(uptr->fileref, CAP(type)*ssize, SEEK_SET)) != 0) { /* seek end */ + sim_debug(DEBUG_CMD, dptr, "UDP Disk attach SEEK last sector @ldone failed\n"); + printf("UDP Disk attach SEEK last sector @ldone failed\r\n"); + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + + i = SCPE_OK; + /* see if disk has labels already, seek to sector past end of disk */ + if ((r = sim_fread(buff, sizeof(uint8), 30, uptr->fileref) != 30)) { + /* the disk does not have labels, add them on */ + /* create labels for disk */ + sim_debug(DEBUG_CMD, dptr, + "File %s attached to %s creating labels\n", + file, disk_type[type].name); + printf("File %s attached to %s creating labels\r\n", + file, disk_type[type].name); + i = disk_label(uptr); /* label disk */ + if (i != 0) { + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + } else { + int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type); + /* uaddr has umap value for track zero label */ + /* output umap address */ + buff[16] = (uaddr >> 24) & 0xff; /* lumapp DMAP pointer */ + buff[17] = (uaddr >> 16) & 0xff; + buff[18] = (uaddr >> 8) & 0xff; + buff[19] = (uaddr) & 0xff; + if ((sim_fseek(uptr->fileref, CAP(type)*ssize, SEEK_SET)) != 0) { /* seek end */ + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + /* output updated umap address to track 0 for UTX21a */ + if ((sim_fwrite(buff, sizeof(uint8), 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_EXP, dptr, + "Error writing back track 0 label to sect %06x offset %06x\n", + CAP(type), CAP(type)*ssize); + return SCPE_FMT; /* error */ + } + } + + /* UTX map (NUMP) does not insert an F4 after the replacement tracks */ + /* so do it after the tracks are defined to stop halt on bootup */ + /* utxmap + 32 + 88 + (3*spare) + 1 */ + /* spare count is at utxmap + 8w (32) */ + + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + + /* start out at sector 0 */ + uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */ + + sim_debug(DEBUG_CMD, dptr, + "UDP %s cyl %d hds %d spt %d spc %d cap sec %d cap bytes %d\n", + disk_type[type].name, CYL(type), HDS(type), SPT(type), SPC(type), + CAP(type), CAPB(type)); + printf("UDP Attach %s cyl %d hds %d spt %d spc %d cap sec %d cap bytes %d\r\n", + disk_type[type].name, CYL(type), HDS(type), SPT(type), SPC(type), + CAP(type), CAPB(type)); + + sim_debug(DEBUG_CMD, dptr, + "UDP File %s attached to %s with labels\n", + file, disk_type[type].name); + printf("UDP File %s attached to %s with labels\r\n", + file, disk_type[type].name); + + /* check for valid configured disk */ + /* must have valid DIB and Channel Program pointer */ + dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */ + if ((dib_unit[chsa] == NULL) || (dibp == NULL) || (chp == NULL)) { + sim_debug(DEBUG_EXP, dptr, + "ERROR===ERROR\nUDP device %s not configured on system, aborting\n", + dptr->name); + printf("ERROR===ERROR\nUDP device %s not configured on system, aborting\r\n", + dptr->name); + detach_unit(uptr); /* detach if error */ + return SCPE_UNATT; /* error */ + } + set_devattn(chsa, SNS_DEVEND); + return SCPE_OK; +} + +/* detach a disk device */ +t_stat disk_detach(UNIT *uptr) { + uptr->SNS = 0; /* clear sense data */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + return detach_unit(uptr); /* tell simh we are done with disk */ +} + +/* boot from the specified disk unit */ +t_stat disk_boot(int32 unit_num, DEVICE *dptr) { + UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */ + + sim_debug(DEBUG_CMD, dptr, + "Disk Boot dev/unit %x\n", GET_UADDR(uptr->CMD)); + + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nDisk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + if ((uptr->flags & UNIT_ATT) == 0) { + sim_debug(DEBUG_EXP, dptr, + "Disk Boot attach error dev/unit %04x\n", + GET_UADDR(uptr->CMD)); + return SCPE_UNATT; /* attached? */ + } + + SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ + SPAD[0xf8] = 0xF000; /* show as F class device */ + + /* now boot the disk */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + return chan_boot(GET_UADDR(uptr->CMD), dptr); /* boot the ch/sa */ +} + +/* Disk option setting commands */ +/* set the disk type attached to unit */ +t_stat disk_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int i; + + if (cptr == NULL) /* any disk name input? */ + return SCPE_ARG; /* arg error */ + if (uptr == NULL) /* valid unit? */ + return SCPE_IERR; /* no, error */ + if (uptr->flags & UNIT_ATT) /* is unit attached? */ + return SCPE_ALATT; /* no, error */ + + /* now loop through the units and find named disk */ + for (i = 0; disk_type[i].name != 0; i++) { + if (strcmp(disk_type[i].name, cptr) == 0) { + uptr->flags &= ~UNIT_TYPE; /* clear the old UNIT type */ + uptr->flags |= SET_TYPE(i); /* set the new type */ + /* set capacity of disk in sectors */ + uptr->capac = CAP(i); + return SCPE_OK; + } + } + return SCPE_ARG; +} + +t_stat disk_get_type(FILE *st, UNIT *uptr, int32 v, CONST void *desc) +{ + if (uptr == NULL) + return SCPE_IERR; + fputs("TYPE=", st); + fputs(disk_type[GET_TYPE(uptr->flags)].name, st); + return SCPE_OK; +} + +/* help information for disk */ +t_stat disk_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + int i; + fprintf (st, "SEL 2314 Disk Processor II\r\n"); + fprintf (st, "Use:\r\n"); + fprintf (st, " sim> SET %sn TYPE=type\r\n", dptr->name); + fprintf (st, "Type can be: "); + for (i = 0; disk_type[i].name != 0; i++) { + fprintf(st, "%s", disk_type[i].name); + if (disk_type[i+1].name != 0) + fprintf(st, ", "); + } + fprintf (st, ".\nEach drive has the following storage capacity:\r\n"); + for (i = 0; disk_type[i].name != 0; i++) { + int32 size = CAPB(i); /* disk capacity in bytes */ + size /= 1024; /* make KB */ + size = (10 * size) / 1024; /* size in MB * 10 */ + fprintf(st, " %-8s %4d.%1d MB cyl %3d hds %3d sec %3d blk %3d\r\n", + disk_type[i].name, size/10, size%10, CYL(i), HDS(i), SPT(i), SSB(i)); + } + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + return SCPE_OK; +} + +const char *disk_description (DEVICE *dptr) +{ + return "SEL 2314 Disk Processor II"; +} + +#endif diff --git a/SEL32/sel32_ec.c b/SEL32/sel32_ec.c new file mode 100644 index 00000000..5c49ba7d --- /dev/null +++ b/SEL32/sel32_ec.c @@ -0,0 +1,1909 @@ +/* sel32_ec.c: SEL-32 8516 Ethernet controller. + + Copyright (c) 2020-2022, Richard Cornwell + Portions provided by James C. Bevier and other SIMH contributers + + 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 "sel32_defs.h" + +#if NUM_DEVS_ETHER > 0 +#include "sim_ether.h" + +/* allow 3 modes */ +#define UNIT_V_MODE (UNIT_V_UF + 1) +#define UNIT_MODE (0x3 << UNIT_V_MODE) +/* get & set disk types */ +#define GET_MODE(x) ((UNIT_MODE & (x)) >> UNIT_V_MODE) +#define SET_MODE(x) (UNIT_MODE & ((x) << UNIT_V_MODE)) + + +#define CMD u3 +/* u3 */ +/* in u3 is device command code and status */ +#define EC_CMDMSK 0x0ff /* Command being run */ +/* commands */ +#define EC_INCH 0x00 /* Initialize channel */ +#define EC_INCH2 0xF0 /* Initialize channel command for processing */ +#define EC_WRITE 0x01 /* Write frame */ +#define EC_READ 0x02 /* Read frame*/ +#define EC_NOP 0x03 /* No operation */ +#define EC_SNS 0x04 /* Sense */ +#define EC_LIA 0x07 /* Load individual address */ +#define EC_TIC 0x08 /* Transfer in channel */ +#define EC_CGA 0x0B /* Disable multicast address */ +#define EC_LGA 0x0F /* Load Multicast address */ +#define EC_LCC 0x10 /* Configure LCC */ +#define EC_STATS 0x14 /* Read Statistics */ +#define EC_CSTATS 0x15 /* Clear software counters */ +#define EC_BUSY 0x100 /* Mark Device as Busy */ + +#define SNS u5 +/* u5 */ +/* Sense byte 0 */ +#define SNS_CMDREJ 0x80000000 /* Command reject */ +#define SNS_SPARE0 0x40000000 /* Spare */ +#define SNS_SPARE1 0x20000000 /* Spare */ +#define SNS_EQUCHK 0x10000000 /* Equipment check */ +#define SNS_SPARE2 0x08000000 /* Spare */ +#define SNS_SPARE3 0x04000000 /* Spare */ +#define SNS_MODE_M 0x03000000 /* Mode Mask */ + +/* Sense byte 1 */ +#define SNS_RCV_RDY 0x00800000 /* Receive unit ready */ +#define SNS_TMT_DEF 0x00400000 /* Transmission deferred */ +#define SNS_COL_RTY 0x00300000 /* Collision retry */ +#define SNS_HRT_TST 0x00080000 /* Heartbeat test failure */ +#define SNS_DMA_UND 0x00040000 /* DMA under run */ +#define SNS_LST_CTS 0x00020000 /* Lost Clear to send */ +#define SNS_NO_CAR 0x00010000 /* No carrier. */ + +/* Sense byte 2 & 3 */ +#define SNS_XFR_MASK 0x0000FFFF /* Previous frame count */ + +typedef uint32 in_addr_T; + +#define ETHTYPE_ARP 0x0806 +#define ETHTYPE_IP 0x0800 + +#define STAT_FR_ALIGN 0 /* Frame alignment errors */ +#define STAT_FR_CRC 1 /* Frame CRC errors */ +#define STAT_LCL_AVAIL 2 /* Local bus available errors */ +#define STAT_LCL_OVER 3 /* Local bus overflow */ +#define STAT_TX_COLL 4 /* Transmission collisions */ +#define STAT_RX_LEN 5 /* Receive length errors */ +#define STAT_TX_SUCC 6 /* Transmitt success after 2-15 collisions */ +#define STAT_TX_DEF 7 /* Transmitt deferred */ +#define STAT_TX_UNSUCC 8 /* Transmitt unsuccessful */ +#define STAT_TX_SUCC1 9 /* Transmitt success after 1 collision */ +#define STAT_LEN 10 /* Number of half word stats */ + +PACKED_BEGIN +struct ec_eth_hdr { + ETH_MAC dest; + ETH_MAC src; + uint16 type; +} PACKED_END; + +/* + * Structure of an internet header, naked of options. + */ +PACKED_BEGIN +struct ip { + uint8 ip_v_hl; /* version,header length */ + uint8 ip_tos; /* type of service */ + uint16 ip_len; /* total length */ + uint16 ip_id; /* identification */ + uint16 ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* don't fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + uint8 ip_ttl; /* time to live */ + uint8 ip_p; /* protocol */ + uint16 ip_sum; /* checksum */ + in_addr_T ip_src; + in_addr_T ip_dst; /* source and dest address */ +} PACKED_END; + +#define TCP_PROTO 6 +PACKED_BEGIN +struct tcp { + uint16 tcp_sport; /* Source port */ + uint16 tcp_dport; /* Destination port */ + uint32 seq; /* Sequence number */ + uint32 ack; /* Ack number */ + uint16 flags; /* Flags */ +#define TCP_FL_FIN 0x01 +#define TCP_FL_SYN 0x02 +#define TCP_FL_RST 0x04 +#define TCP_FL_PSH 0x08 +#define TCP_FL_ACK 0x10 +#define TCP_FL_URG 0x20 + uint16 window; /* Window size */ + uint16 chksum; /* packet checksum */ + uint16 urgent; /* Urgent pointer */ +} PACKED_END; + +#define UDP_PROTO 17 +PACKED_BEGIN +struct udp { + uint16 udp_sport; /* Source port */ + uint16 udp_dport; /* Destination port */ + uint16 len; /* Length */ + uint16 chksum; /* packet checksum */ +} PACKED_END; + +PACKED_BEGIN +struct udp_hdr { + in_addr_T ip_src; + in_addr_T ip_dst; /* source and dest address */ + uint8 zero; + uint8 proto; /* Protocol */ + uint16 hlen; /* Length of header and data */ +} PACKED_END; + +#define ICMP_PROTO 1 +PACKED_BEGIN +struct icmp { + uint8 type; /* Type of packet */ + uint8 code; /* Code */ + uint16 chksum; /* packet checksum */ +} PACKED_END; + +PACKED_BEGIN +struct ip_hdr { + struct ec_eth_hdr ethhdr; + struct ip iphdr; +} PACKED_END; + +#define ARP_REQUEST 1 +#define ARP_REPLY 2 +#define ARP_HWTYPE_ETH 1 + +PACKED_BEGIN +struct arp_hdr { + struct ec_eth_hdr ethhdr; + uint16 hwtype; + int16 protocol; + uint8 hwlen; + uint8 protolen; + uint16 opcode; + ETH_MAC shwaddr; + in_addr_T sipaddr; + ETH_MAC dhwaddr; + in_addr_T dipaddr; + uint8 padding[18]; +} PACKED_END; + +struct ec_device { + ETH_PCALLBACK rcallback; /* read callback routine */ + ETH_PCALLBACK wcallback; /* write callback routine */ + ETH_MAC mac; /* Hardware MAC addresses */ + ETH_DEV etherface; + ETH_QUE ReadQ; + ETH_PACK rec_buff[1024]; /* Buffer for received packet */ + ETH_PACK snd_buff; /* Buffer for sending packet */ + int macs_n; /* Number of multi-cast addresses */ + ETH_MAC macs[67]; /* Watched Multi-cast addresses */ + int amc; /* Recieve all multicast packets */ + uint32 rx_count; /* Packets received */ + uint32 tx_count; /* Packets sent */ + t_stat drop_cnt; /* Packets dropped */ + int r_pkt; /* Packet pending */ + int poll; /* Need to poll receiver */ + int lp_rdy; /* Loop back packet ready */ + int rec_ptr; /* Receive pointer */ + int xtr_ptr; /* Extract pointer */ + uint8 conf[12]; /* user specified configuration */ +} ec_data; + +#define LOOP_MSK 0x3ff + +extern int32 tmxr_poll; +extern uint32 readfull(CHANP *chp, uint32 maddr, uint32 *word); +extern uint32 cont_chan(uint16 chsa); + +static CONST ETH_MAC broadcast_ethaddr = {0xff,0xff,0xff,0xff,0xff,0xff}; + +/* channel program information */ +CHANP ec_chp[NUM_UNITS_ETHER] = {0}; + +/* forward definitions */ +t_stat ec_preio(UNIT *uptr, uint16 chan); +t_stat ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); +t_stat ec_rec_srv(UNIT *uptr); +t_stat ec_srv(UNIT *uptr); +t_stat ec_haltio(UNIT *uptr); +t_stat ec_iocl(CHANP *chp, int32 tic_ok); +void ec_packet_debug(struct ec_device *ec, const char *action, ETH_PACK *packet); +t_stat ec_reset (DEVICE *dptr); +void ec_ini(UNIT *, t_bool); +t_stat ec_rsctrl(UNIT *uptr); +t_stat ec_rschnlio(UNIT *uptr); +t_stat ec_show_mac (FILE* st, UNIT* uptr, int32 val, CONST void* desc); +t_stat ec_set_mac (UNIT* uptr, int32 val, CONST char* cptr, void* desc); +t_stat ec_show_mode (FILE* st, UNIT* uptr, int32 val, CONST void* desc); +t_stat ec_set_mode (UNIT* uptr, int32 val, CONST char* cptr, void* desc); +t_stat ec_attach (UNIT * uptr, CONST char * cptr); +t_stat ec_detach (UNIT * uptr); +t_stat ec_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); +const char *ec_description (DEVICE *dptr); + +#define ec_master_uptr (&ec_unit[0]) /* Unit doing receive digestion */ + +UNIT ec_unit[] = { + {UDATA(ec_rec_srv, UNIT_IDLE|UNIT_ATTABLE, 0), 0, UNIT_ADDR(0xE00)}, /* 0 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE01)}, /* 1 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE02)}, /* 2 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE03)}, /* 3 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE04)}, /* 4 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE05)}, /* 5 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE06)}, /* 6 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE07)}, /* 7 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE08)}, /* 8 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE09)}, /* 9 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0A)}, /* A */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0B)}, /* B */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0C)}, /* C */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0D)}, /* D */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0E)}, /* E */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0F)}, /* F */ +}; + +DIB ec_dib = { + ec_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + ec_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + ec_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + ec_rsctrl, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + ec_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + ec_iocl, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + ec_ini, /* void (*dev_ini)(UNIT *uptr) */ /* init function */ + ec_unit, /* UNIT *units */ /* Pointer to units structure */ + ec_chp, /* CHANP *chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_ETHER, /* number of units defined */ + 0x0F, /* device mask */ + 0x0E00, /* parent channel address */ + 0, /* fifo input index */ + 0, /* fifo output index */ + {0}, /* interrupt status fifo for channel */ +}; + +MTAB ec_mod[] = { + { MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "MODE", "MODE=#", + &ec_set_mode, &ec_show_mode, NULL, "Ethernet mode" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "MAC", "MAC=xx:xx:xx:xx:xx:xx", + &ec_set_mac, &ec_show_mac, NULL, "MAC address" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "ETH", NULL, NULL, + ð_show, NULL, "Display attachedable devices" }, + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", + &set_dev_addr, &show_dev_addr, NULL, "Device channel address"}, + { 0 } + }; + +/* Simulator debug controls */ +DEBTAB ec_debug[] = { + {"CMD", DEBUG_CMD, "Show command execution to devices"}, + {"DATA", DEBUG_DATA, "Show data transfers"}, + {"DETAIL", DEBUG_DETAIL, "Show details about device"}, + {"EXP", DEBUG_EXP, "Show exception information"}, + {"IRQ", DEBUG_IRQ, "Show IRQ requests"}, + {"XIO", DEBUG_XIO, "Show XIO I/O instructions"}, +#define DEBUG_ARP (DEBUG_IRQ<<1) + {"ARP", DEBUG_ARP, "Show ARP activities"}, +#define DEBUG_TCP (DEBUG_ARP<<1) + {"TCP", DEBUG_TCP, "Show TCP packet activities"}, +#define DEBUG_UDP (DEBUG_TCP<<1) + {"UDP", DEBUG_UDP, "Show UDP packet activities"}, +#define DEBUG_ICMP (DEBUG_UDP<<1) + {"ICMP", DEBUG_ICMP, "Show ICMP packet activities"}, +#define DEBUG_ETHER (DEBUG_ICMP<<1) + {"ETHER", DEBUG_ETHER, "Show ETHER activities"}, + {0, 0} +}; + +DEVICE ec_dev = { + "EC", ec_unit, NULL, ec_mod, + NUM_UNITS_ETHER, 16, 24, 4, 16, 32, + NULL, NULL, &ec_reset, NULL, &ec_attach, &ec_detach, + &ec_dib, DEV_DISABLE | DEV_DEBUG | DEV_ETHER, 0, ec_debug, + NULL, NULL, &ec_help, NULL, NULL, &ec_description +}; + +/* load in the IOCD and process the commands */ +/* return = 0 OK */ +/* return = 1 error, chan_status will have reason */ +t_stat ec_iocl(CHANP *chp, int32 tic_ok) +{ + uint32 word1 = 0; + uint32 word2 = 0; + int32 docmd = 0; + UNIT *uptr = chp->unitptr; /* get the unit ptr */ + uint16 chan = get_chan(chp->chan_dev); /* our channel */ + uint16 chsa = chp->chan_dev; + uint16 devstat = 0; + DEVICE *dptr = get_dev(uptr); + + /* check for valid iocd address if 1st iocd */ + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + if (chp->chan_caw & 0x3) { /* must be word bounded */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl iocd bad address chsa %02x caw %06x\n", + chsa, chp->chan_caw); + chp->ccw_addr = chp->chan_caw; /* set the bad iocl address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ + return 1; /* error return */ + } + } +loop: + sim_debug(DEBUG_EXP, dptr, + "ec_iocl @%06x @loop chan_status[%04x] %04x SNS %08x\n", + chp->chan_caw, chan, chp->chan_status, uptr->SNS); + + /* Abort if we have any errors */ + if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl ERROR1 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* return error */ + } + + /* Read in first CCW */ + if (readfull(chp, chp->chan_caw, &word1) != 0) { /* read word1 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl ERROR2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Read in second CCW */ + if (readfull(chp, chp->chan_caw+4, &word2) != 0) { /* read word2 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl ERROR3 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + sim_debug(DEBUG_CMD, dptr, + "ec_iocl @%06x read ccw chsa %04x IOCD wd 1 %08x wd 2 %08x SNS %08x\n", + chp->chan_caw, chp->chan_dev, word1, word2, uptr->SNS); +//#define DYNAMIC_DEBUG +#ifdef DYNAMIC_DEBUG + if ((word1 == 0x0202f000) && (word2 == 0x0000003C) && (uptr->SNS == 0x0080003e)) { + cpu_dev.dctrl |= (DEBUG_INST|DEBUG_XIO); /* start instruction trace */ + } else + if ((word1 == 0x0202f000) && (word2 == 0x00000040) && (uptr->SNS == 0x0080003e)) { + cpu_dev.dctrl &= ~(DEBUG_INST|DEBUG_XIO); /* stop instruction trace */ + } +#endif + + chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */ + + /* Check if we had data chaining in previous iocd */ + /* if we did, use previous cmd value */ + if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + (chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "ec_iocl @%06x DO DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + } else + chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ + + chp->ccw_count = 0; + + if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl mem error PCHK chan_status[%04x] %04x addr %08x\n", + chan, chp->chan_status, word1 & MASK24); + return 1; /* error return */ + } + + /* this switch is here to satisify the SEL diag who wants a program */ + /* check error instead of a unit check error for these cmd values??? */ + /* validate the commands for the ethernet */ + switch (chp->ccw_cmd) { + case 0x18: case 0x20: case 0x28: case 0x30: case 0x38: case 0x40: case 0x48: + case 0x50: case 0x58: case 0x60: case 0x68: case 0x70: case 0x78: case 0x80: + case 0x88: case 0x90: case 0x98: case 0xa0: case 0xa8: case 0xb0: case 0xb8: + case 0xc0: case 0xc8: case 0xd0: case 0xd8: case 0xe0: case 0xe8: case 0xf0: + case 0xf8: + uptr->SNS &= ~SNS_CMDREJ; /* remove CMD reject status */ + sim_debug(DEBUG_CMD, dptr, + "ec_iocl illegal at ec_startcmd %02x SNS %08x\n", + chp->ccw_cmd, uptr->SNS); + chp->ccw_count = 0; /* diags want zero count */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + + case EC_READ: + /* read count must be multiple of 4 */ + if ((word2 & 0xffff) & 3) { + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl READ cnt not multiple of 4 %d\n", word2 & 0xffff); + /* diags wants prog check instead of unit check */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } + /* see if too few bytes */ + if (((chp->chan_info & INFO_SIOCD) == 1) && /* see if 1st IOCD in channel prog */ + ((word2 & 0xffff) < 20) && /* and not at least 20 bytes */ + ((word2 & BIT0) == 0)) { /* and not data chained */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl READ error small packet 0x%04x\n", word2 & 0xffff); + /* diags wants incorrect length instead of program check */ + chp->chan_status |= STATUS_LENGTH; /* incorrect length error */ + return 1; /* error return */ + } + /* see if too many bytes */ + if ((word2 & 0xffff) > (ETH_MAX_PACKET+2)) { + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl READ error large packet 0x%04x\n", word2 & 0xffff); + /* diags wants prog check instead of length check for test 4E */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } + uptr->SNS = 0; + break; + case EC_WRITE: + /* see if too few bytes */ + if (((chp->chan_info & INFO_SIOCD) == 1) && /* see if 1st IOCD in channel prog */ + ((word2 & 0xffff) < 8) && /* and not at least 8 bytes */ + ((word2 & BIT0) == 0)) { /* and not data chained */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl WRITE error small packet 0x%04x\n", word2 & 0xffff); + /* diags wants prog check instead of unit check */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } + /* see if too many bytes */ + if ((word2 & 0xffff) > ETH_MAX_PACKET) { + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl WRITE error large packet 0x%04x\n", word2 & 0xffff); + /* diags wants prog check instead of length check for test 4E */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } + uptr->SNS = 0; + break; + case EC_INCH: case EC_LIA: + case EC_TIC: case EC_CGA: case EC_LGA: case EC_LCC: + uptr->SNS = 0; + break; + case EC_STATS: case EC_CSTATS: + case EC_SNS: + break; + case EC_NOP: + uptr->SNS = 0; + /* nop must have non zero count */ + if ((word2 & 0xffff) == 0) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } + break; + default: + uptr->SNS |= SNS_CMDREJ; + chp->chan_status |= STATUS_CHECK; /* diags want unit check */ + sim_debug(DEBUG_CMD, dptr, + "ec_startcmd illegal2 cmd %02x SNS %08x\n", + chp->ccw_cmd, uptr->SNS); + return 1; /* error return */ + break; + } + + chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2 */ + + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + /* 1st command can not be a TIC */ + if (chp->ccw_cmd == CMD_TIC) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl TIC bad cmd chan_status[%04x] %04x\n", + chan, chp->chan_status); + return 1; /* error return */ + } + } + + /* TIC can't follow TIC or be first in command chain */ + /* diags send bad commands for testing. Use all of op */ + if (chp->ccw_cmd == CMD_TIC) { + if (tic_ok) { + if (((word1 & MASK24) == 0) || (word1 & 0x3)) { + sim_debug(DEBUG_EXP, dptr, + "ec_iocl tic cmd bad address chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + return 1; /* error return */ + } + tic_ok = 0; /* another tic not allowed */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + sim_debug(DEBUG_CMD, dptr, + "ec_iocl tic cmd ccw chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + goto loop; /* restart the IOCD processing */ + } + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl TIC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Check if we had data chaining in previous iocd */ + if ((chp->chan_info & INFO_SIOCD) || /* see if 1st IOCD in channel prog */ + (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + ((chp->ccw_flags & FLAG_DC) == 0))) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "ec_iocl @%06x DO CMD No DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + docmd = 1; /* show we have a command */ + } + + /* Set up for this command */ + chp->ccw_flags = (word2 >> 16) & 0xf800; /* get flags from bits 0-4 of WD 2 of IOCD */ + chp->chan_status = 0; /* clear status for next IOCD */ + /* make a 24 bit address */ + chp->ccw_addr = word1 & MASK24; /* set the data/seek address */ + + /* validate parts of IOCD2 that are reserved */ + if (word2 & 0x07ff0000) { /* bits 5-15 must be zero */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl IOCD2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* DC can only be used with a read/write cmd */ + if (chp->ccw_flags & FLAG_DC) { + if ((chp->ccw_cmd == EC_INCH) || (chp->ccw_cmd == EC_NOP) || + (chp->ccw_cmd == EC_CGA) || (chp->ccw_cmd == EC_CSTATS)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid DC */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl DC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + } + + chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ + + sim_debug(DEBUG_XIO, dptr, + "ec_iocl @%06x read docmd %01x addr %06x count %04x chan %04x ccw_flags %04x\n", + chp->chan_caw, docmd, chp->ccw_addr, chp->ccw_count, chan, chp->ccw_flags); + + if (docmd) { /* see if we need to process a command */ + DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ + + uptr = chp->unitptr; /* get the unit ptr */ + if (dibp == 0 || uptr == 0) { + chp->chan_status |= STATUS_PCHK; /* program check if it is */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl bad dibp or uptr chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* if none, error */ + } + + sim_debug(DEBUG_XIO, dptr, + "ec_iocl @%06x before start_cmd chan %04x status %04x count %04x SNS %08x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, uptr->SNS); + + /* call the device startcmd function to process the current command */ + /* just replace device status bits */ + chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ + devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd); + chp->chan_status = (chp->chan_status & 0xff00) | devstat; + chp->chan_info &= ~INFO_SIOCD; /* show not first IOCD in channel prog */ + + sim_debug(DEBUG_XIO, dptr, + "ec_iocl @%06x after start_cmd chsa %04x status %08x count %04x SNS %08x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count, uptr->SNS); + + /* see if bad status */ + if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) { + chp->chan_status |= STATUS_CEND; /* channel end status */ + chp->ccw_flags = 0; /* no flags */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl bad status chsa %04x status %04x cmd %02x\n", + chsa, chp->chan_status, chp->ccw_cmd); + /* done with command */ + sim_debug(DEBUG_EXP, &cpu_dev, + "ec_iocl ERROR return chsa %04x status %08x\n", + chp->chan_dev, chp->chan_status); + return 1; /* error return */ + } + /* NOTE this code needed for MPX 1.X to run! */ + /* see if command completed */ + /* we have good status */ + if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_XIO, dptr, + "ec_iocl @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n", + chp->chan_caw, FIFO_Num(chsa), chan, chp->chan_status, chp->ccw_count); + } + } + /* the device processor returned OK (0), so wait for I/O to complete */ + /* nothing happening, so return */ + sim_debug(DEBUG_XIO, dptr, + "ec_iocl @%06x return, chsa %04x status %04x count %04x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count); + return 0; /* good return */ +} + +/* start an ethernet operation */ +t_stat ec_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + uint16 chsa = GET_UADDR(uptr->CMD); + + sim_debug(DEBUG_CMD, dptr, "ec_preio CMD %08x unit %02x chsa %04x\n", + uptr->CMD, unit, chsa); + if ((uptr->CMD & EC_CMDMSK) != 0) { /* just return if busy */ + sim_debug(DEBUG_CMD, dptr, + "ec_preio unit %02x chsa %04x BUSY\n", unit, chsa); + return SNS_BSY; + } + + sim_debug(DEBUG_CMD, dptr, "ec_preio CMD %08x unit %02x chsa %04x OK\n", + uptr->CMD, unit, chsa); + return SCPE_OK; /* good to go */ +} + +/* Start ethernet command */ +t_stat ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_CMD, dptr, + "ec_startcmd chsa %04x unit %d cmd %02x CMD %08x\n", + chsa, (int)(uptr - ec_unit), cmd, uptr->CMD); + if ((uptr->CMD & 0xff) != 0) { /* if any status info, we are busy */ + sim_debug(DEBUG_CMD, dptr, "ec_startcmd busy\n"); + return SNS_BSY; + } + + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* Unit is online, so process a command */ + switch (cmd) { + case EC_WRITE: /* Write command 0x01 */ + uptr->CMD |= (cmd|EC_BUSY); /* save cmd */ + // This works most of the time & stops at test 30 with no len errors +//Was sim_activate(uptr, 5000); /* start things off */ + // This works +/*jb*/ sim_activate(uptr, 7500); /* start things off */ + return 0; + case EC_INCH: /* INCH cmd 0x0 */ + cmd = EC_INCH2; /* set dummy INCH cmd 0xf0 */ + case EC_READ: /* Read command 0x02 */ + case EC_TIC: /* Transfer in channel */ + case EC_CGA: /* Disable multicast address */ + case EC_LCC: /* Configure LCC 0x10 */ + case EC_STATS: /* Read Statistics */ + case EC_CSTATS: /* Clear software counters */ + case EC_NOP: /* NOP 0x03 */ + case EC_LIA: /* Load individual address */ + case EC_LGA: /* Load Multicast address */ + /* Fall through */ + case EC_SNS: /* Sense 0x04 */ + uptr->CMD |= cmd|EC_BUSY; /* save cmd */ +//Was M sim_activate(uptr, 100); /* start things off */ + sim_activate(uptr, 150); /* start things off */ + return 0; + } + + uptr->SNS |= SNS_CMDREJ; + sim_debug(DEBUG_CMD, dptr, "ec_startcmd illegal3 cmd %02x SNS %08x\n", + cmd, uptr->SNS); + chp->ccw_count = 0; /* diags want zero count */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* diags want unit check */ +} + +/* Handle processing of ethernet requests. */ +t_stat ec_rec_srv(UNIT *uptr) +{ + DEVICE *dptr = get_dev(uptr); + int cmd = uptr->CMD & EC_CMDMSK; + + /* If not in loopback try and receive a packet */ + if ((ec_data.conf[0] & 0x40) == 0) { + int q = (((ec_data.rec_ptr + 1) & LOOP_MSK) + LOOP_MSK + 1) - ec_data.xtr_ptr; + if (q > LOOP_MSK) + q -= (LOOP_MSK + 1); + if (eth_read(&ec_data.etherface, &ec_data.rec_buff[ec_data.rec_ptr], NULL) > 0) { +//jb if (((ec_data.rec_ptr + 1) & LOOP_MSK) == ec_data.xtr_ptr) { +//jb if (q > 16) { + if (q > 716) { + ec_data.drop_cnt++; + sim_debug(DEBUG_DETAIL, dptr, + "ec_rec_srv received packet %08x dropped %08x\n", + ec_data.rx_count, ec_data.drop_cnt); + } else { + ec_data.rec_ptr = (ec_data.rec_ptr + 1) & LOOP_MSK; + ec_data.rx_count++; + sim_debug(DEBUG_DETAIL, dptr, + "ec_rec_srv received packet %08x\n", ec_data.rx_count); + } + } + } + + /* If there is a command on this subchannel, do it */ + if (cmd != 0) + return ec_srv(uptr); + + return SCPE_OK; +} + +/* Handle processing of ethernet requests. */ +t_stat ec_srv(UNIT *uptr) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + int cmd = uptr->CMD & EC_CMDMSK; + uint32 mema; + int i; + int n, len; + int pirq, cnt, dcnt; + uint8 ch; + uint8 buf[1520]; + uint8 *pck; + struct ec_eth_hdr *hdr; + + sim_debug(DEBUG_CMD, dptr, + "ec_srv chp %p cmd=%02x chsa %04x count %04x SNS %08x\n", + chp, cmd, chsa, chp->ccw_count, uptr->SNS); + + switch (cmd) { +// case EC_INCH: /* 0x00 INCH cmd */ + case EC_INCH2: /* 0xF0 INCH cmd */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "ec_srv starting INCH %06x cmd, chsa %04x addr %06x cnt %04x\n", + chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count); + /* now call set_inch() function to write and test inch buffer addresses */ + /* Ethernet uses 1 dbl wd */ + i = set_inch(uptr, mema, 1); /* new address */ + ec_ini(uptr, 0); + if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + for (i=0; i < len; i++) { + if (chan_read_byte(chsa, &buf[i])) { + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* just dump data */ + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case EC_LIA: /* 0x07 Load individual address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + for(i = 0; i < sizeof (ETH_MAC); i++) { + if (chan_read_byte(chsa, &buf[i])) { + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + + } + } + memcpy(&ec_data.mac, &buf[0], sizeof (ETH_MAC)); + eth_mac_fmt(&ec_data.mac, (char *)&buf[0]); + sim_debug(DEBUG_CMD, dptr, "ec_srv setting mac %s\n", buf); + n = ec_data.macs_n + 2; + memcpy(&ec_data.macs[0], &ec_data.mac, sizeof (ETH_MAC)); + memcpy(&ec_data.macs[1], &broadcast_ethaddr, sizeof (ETH_MAC)); + if (ec_master_uptr->flags & UNIT_ATT) + /* set promiscuous if bit 7 of byte zero of mac address is set */ + eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc, + ec_data.macs[0][0] & 1); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case EC_CGA: /* 0x0B Disable multicast address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + ec_data.macs_n = 0; + ec_data.amc = 0; + if (ec_master_uptr->flags & UNIT_ATT) + eth_filter (&ec_data.etherface, 2, ec_data.macs, ec_data.amc, + ec_data.macs[0][0] & 1); + if (chan_read_byte(chsa, &ch)) + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case EC_LGA: /* 0x0F Load Multicast address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + ec_data.macs_n = 0; + len = 2; + for(n = 2; n < (int)(sizeof(ec_data.macs) / sizeof (ETH_MAC)); n++) { + for(i = 0; i < sizeof (ETH_MAC); i++) { + if (chan_read_byte(chsa, &buf[i])) { + break; + } + } + if (i != sizeof (ETH_MAC)) + break; + memcpy(&ec_data.macs[len++], &buf[0], sizeof (ETH_MAC)); + } + ec_data.macs_n = len - 2; + ec_data.amc = 1; + + for (i = 0; i< len; i++) { + eth_mac_fmt(&ec_data.macs[i], (char *)&buf[0]); + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv load mcast%d: %s\n",i,buf); + } + + if (ec_master_uptr->flags & UNIT_ATT) + /* multicast on means promiscous is too */ + eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc, + ec_data.macs[0][0] & 1); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case EC_WRITE: /* 0x01 Write command */ + /* get queue length */ + n = (((ec_data.rec_ptr) & LOOP_MSK) + LOOP_MSK + 1) - ec_data.xtr_ptr; + if (n >LOOP_MSK) + n -= (LOOP_MSK + 1); + len = sizeof(struct ec_eth_hdr); /* std header size /dest/src/len/ (14) */ + pirq = 0; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + i = GET_MODE(ec_master_uptr->flags); /* get the mode setting */ + sim_debug(DEBUG_DETAIL, dptr, "ec_srv START %04x mode %d write %d %d conf=%d cnt 0x%x q %d\n", + chsa, i, ec_data.xtr_ptr, ec_data.rec_ptr, ec_data.conf[9], chp->ccw_count, n); + hdr = (struct ec_eth_hdr *)(&ec_data.snd_buff.msg[0]); + pck = (uint8 *)(&ec_data.snd_buff.msg[0]); + uptr->SNS &= LMASK; /* remove old count */ + + /* create packet: destination(6)/source(6)/type(2) or len(2)/ data 46-1500 */ + switch (GET_MODE(ec_master_uptr->flags)) { + case 0: + /* user buffer has /dest(6)/src(6)/type(2) or len(2)/ data/ */ + /* create packet: destination(6)/source(6)/type(2) or len(2)/ data 46-1500 */ + + /* copy users header unchanged */ + for(i = 0; i < sizeof(struct ec_eth_hdr); i++) { + if (chan_read_byte(chsa, &pck[i])) { + pirq = 1; + n = i; + sim_debug(DEBUG_DETAIL, dptr, "rw_end case 0 error 0\n"); + goto wr_end; + } + } + /* set transfer count of standard header supplied */ + uptr->SNS |= (sizeof(struct ec_eth_hdr) & 0xffff); /* set transfer count (14) */ + + /* copy in user supplied packet data */ + /* make min cnt 60 and max 1514 */ + i = sizeof(struct ec_eth_hdr); /* dest/src/len 14 bytes */ + while (chan_read_byte(chsa, &ch) == 0) { + if (i < ETH_MAX_PACKET) { + if (i>6 && i<28) + sim_debug(DEBUG_DATA, dptr, "ec_srv data[%3x]: %06x %02x\n", + i, chp->ccw_addr, ch); + pck[i] = ch; + } + i++; + uptr->SNS++; /* set count */ + } + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv case 0 transmit bytes %d (0x%x) SNS %08x\n", + len, len, uptr->SNS); + break; + case 1: + case 2: + /* user buffer has /dest(6)/type(2)/data(46-1500)/ */ + /* create packet: destination(6)/source(6)/type(2) or len(2)/ data 46-1500 */ + /* copy in user dest/type/data */ + + /* get 6 byte destination from user */ + for(i = 0; i < sizeof(ETH_MAC); i++) { + if (chan_read_byte(chsa, &pck[i])) { + pirq = 1; + n = i; + sim_debug(DEBUG_DETAIL, dptr, "rw_end case 1&2 error 0\n"); + goto wr_end; + } + } + /* insert 6 byte source from configuration */ + memcpy(&hdr->src, ec_data.mac, sizeof(ETH_MAC)); + + /* copy two byte type/len from user buffer */ + for(i = sizeof(ETH_MAC) * 2; i < sizeof(struct ec_eth_hdr); i++) { + if (chan_read_byte(chsa, &pck[i])) { + pirq = 1; + n = i; + sim_debug(DEBUG_DETAIL, dptr, "rw_end case 1&2 error 2\n"); + goto wr_end; + } + } + /* set transfer count of user bytes supplied dest(6)/type(2) */ + uptr->SNS |= ((sizeof(struct ec_eth_hdr) - sizeof(ETH_MAC)) & 0xffff); + + /* copy in user supplied packet data */ + /* make min cnt 60 and max 1514 */ + i = sizeof(struct ec_eth_hdr); /* dest/src/len 14 bytes */ + while (chan_read_byte(chsa, &ch) == 0) { + if (i < ETH_MAX_PACKET) { + if (i>6 && i<28) + sim_debug(DEBUG_DATA, dptr, "ec_srv data[%3x]: %06x %02x\n", + i, chp->ccw_addr, ch); + pck[i] = ch; + } + i++; + uptr->SNS++; /* set count */ + } + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv case 1&2 transmit bytes %d (0x%x) SNS %08x i 0x%x\n", + len-6, len-6, uptr->SNS, i); + + /* This code is to simulate word transfers into memory */ + /* from the users buffer. 1-3 extra bytes are placed */ + /* into the buffer. Diags in test 20 checks for this data */ + /* being present. These were set to 0 by the old code */ + /* and diags would complain 11/11/2021 */ + /* save data count */ + dcnt = i - sizeof(struct ec_eth_hdr); /* dest/src/len 14 bytes */ + n = 0; + while (dcnt++ % 4) { + pck[i+n] = RMB(((chp->ccw_addr+n))); + sim_debug(DEBUG_DATA, dptr, "ec_srx i %x data[%3x]: %06x %02x\n", + i, i+n, chp->ccw_addr+n, pck[i+n]); + n++; + } + n = n + i; /* last written char in buffer */ + break; + case 3: + /* user buffer has /dest(6)/data(46-1500)/ */ + /* create packet: destination(6)/source(6)/type(2) or len(2)/ data 46-1500 */ + + /* copy destination(6) from user buffer */ + for(i = 0; i < sizeof(ETH_MAC); i++) { + if (chan_read_byte(chsa, &pck[i])) { + pirq = 1; + n = i; + sim_debug(DEBUG_DETAIL, dptr, "rw_end case 3 error 0\n"); + goto wr_end; + } + } + /* insert source(6) */ + memcpy(&hdr->src, ec_data.mac, sizeof(ETH_MAC)); + +//#define USE_DATA_CNT +#ifdef USE_DATA_CNT + /* insert type(2) */ + hdr->type = htons(ETHTYPE_IP); +#endif + + /* set transfer count of user bytes supplied */ + uptr->SNS |= ((sizeof(struct ec_eth_hdr) - + sizeof(ETH_MAC) - sizeof(int16)) & 0xffff); + + /* copy in user supplied packet data */ + /* make min cnt 60 and max 1514 */ + i = sizeof(struct ec_eth_hdr); /* dest/src/len 14 bytes */ + cnt = 0; + while (chan_read_byte(chsa, &ch) == 0) { + if (i < ETH_MAX_PACKET) { + if (i>6 && i<28) + sim_debug(DEBUG_DATA, dptr, "ec_srv data[%3x]: %06x %02x\n", + i, chp->ccw_addr, ch); + pck[i] = ch; + } + i++; + uptr->SNS++; /* set count */ +#ifndef USE_DATA_CNT + cnt++; /* user data count */ +#endif + } + +#ifndef USE_DATA_CNT + /* insert type(2) */ +// hdr->type = htons(ETHTYPE_IP); + hdr->type = htons(cnt); /* set cnt into type/count field */ +#endif + + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv case 3 transmit bytes %d (0x%x) SNS %08x i 0x%x cnt %x\n", + len-8, len-8, uptr->SNS, i, cnt); + + /* This code is to simulate word transfers into memory */ + /* from the users buffer. 1-3 extra bytes are placed */ + /* into the buffer. Diags in test 20 check for this data */ + /* being present. These were set to 0 by the old code */ + /* and diags would complain 11/11/2021 */ + /* save data count */ + dcnt = i - sizeof(struct ec_eth_hdr); /* dest/src/len 14 bytes */ + n = 0; + while (dcnt++ % 4) { + pck[i+n] = RMB(((chp->ccw_addr+n))); + sim_debug(DEBUG_DATA, dptr, "ec_srx i %x data[%3x]: %06x %02x\n", + i, i+n, chp->ccw_addr+n, pck[i+n]); + n++; + } + n = n + i; /* last written char in buffer */ + break; + } +wr_end: + ec_data.snd_buff.len = i; /* set actual count */ + ec_packet_debug(&ec_data, "send", &ec_data.snd_buff); + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv @wr_end count 0x%x i 0x%04x SNS 0x%04x\n", + chp->ccw_count, i, uptr->SNS); + + /* make sure packet is minimum size for mode 1,2 & 3 */ + /* when handling non-loopback packets */ + if ((ec_data.snd_buff.len < ec_data.conf[9]) && + GET_MODE(ec_master_uptr->flags)) { + /* If not in loopback, pad packet */ + if (((ec_data.conf[0] & 0x40) == 0) || + /* this fixes test 20 for mode 3 */ + (GET_MODE(ec_master_uptr->flags) != 3)) { + /* Pad the packet */ + while(i < ETH_MIN_PACKET) { + ec_data.snd_buff.len++; /* increment actual count */ + pck[n++] = 0; + i++; + } + } + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv @wr_end2 count 0x%x i 0x%04x n 0x%04x SNS 0x%04x\n", + chp->ccw_count, i, n, uptr->SNS); + if (i <= ETH_MIN_PACKET) { + ec_packet_debug(&ec_data, "send", &ec_data.snd_buff); + } + } + /* see if too many bytes, did not get channel end before packet filled */ + if (ec_data.snd_buff.len > ETH_MAX_PACKET) { + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv WRITE error user 2manybytes %0x\n", chp->ccw_count); + /* diags wants prog check instead of length check test 4E */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + ec_data.tx_count++; + if (ec_data.conf[0] & 0x40) { /* see if internal loopback */ + /* yes loopback, buffer the packet */ + int q = (((ec_data.rec_ptr + 1) & LOOP_MSK) + LOOP_MSK + 1) - ec_data.xtr_ptr; + if (q >LOOP_MSK) + q -= (LOOP_MSK + 1); +//jb if (((ec_data.rec_ptr + 1) & LOOP_MSK) == ec_data.xtr_ptr) { +//jb if (q > 16) { + if (q > 716) { + ec_data.drop_cnt++; + sim_debug(DEBUG_DETAIL, dptr, "ec_srv write packet dropped %d q %d\n", + ec_data.drop_cnt, q); + } else { + memcpy(&ec_data.rec_buff[ec_data.rec_ptr], + &ec_data.snd_buff, sizeof(ETH_PACK)); + ec_data.rec_ptr = (ec_data.rec_ptr + 1) & LOOP_MSK; + sim_debug(DEBUG_DETAIL, dptr, "ec_srv WRITE rec queued %d xtr %d queue %04x\n", + ec_data.rec_ptr, ec_data.xtr_ptr, q); + } + } + + /* check for internal loopback */ + if ((ec_data.conf[0] & 0x40) == 0) { +#ifndef NEW_02052021 + /* not internal loopback, user wants to write to network */ + /* check if attached, if not give no carrier and unit exception */ + if ((ec_master_uptr->flags & UNIT_ATT) == 0) { + sim_debug(DEBUG_EXP, dptr, + "EC write device %s not attached on unit EC%04X\n", + dptr->name, GET_UADDR(uptr->CMD)); + uptr->SNS |= SNS_NO_CAR; /* no carrier error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_EXPT); + break; + } +#endif + /* no loopback, write out the packet */ + if (eth_write(&ec_data.etherface, &ec_data.snd_buff, NULL) != SCPE_OK) { + sim_debug(DEBUG_DETAIL, dptr, "ec_srv short packet %d\n", i); + /* diags wants prog check instead of unit check */ + pirq = 1; + } + } + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv sent packet pirq %d 0x%x bytes tx_count=%08x SNS %08x\n", + pirq, ec_data.snd_buff.len, ec_data.tx_count, uptr->SNS); + + if (pirq) + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else { + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + } + break; + + case EC_READ: /* 0x02 Read command */ + /* If no data to receive wait for some more */ + if (ec_data.xtr_ptr == ec_data.rec_ptr) { +// sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv WAIT %04x read %d %d size=%d cnt %d\n", +// chsa, ec_data.xtr_ptr, ec_data.rec_ptr, ec_data.conf[9], chp->ccw_count); +//XX sim_clock_coschedule(uptr, 1500); /* continue poll */ +//HH sim_activate(uptr, 1511); /* continue poll */ + /* this is OK for mode 0, 1, 2, 3 */ +//12dec21 sim_activate(uptr, 2511); /* continue poll */ + /* this is really a 50000 cnt poll by simh */ + sim_clock_coschedule(uptr, 1000); /* continue poll */ + return SCPE_OK; + } + /* get queue length */ + n = (((ec_data.rec_ptr) & LOOP_MSK) + LOOP_MSK + 1) - ec_data.xtr_ptr; + if (n > LOOP_MSK) + n -= (LOOP_MSK + 1); + pirq = 0; + i = GET_MODE(ec_master_uptr->flags); /* get the mode setting */ + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv START %04x mode %d read %d %d conf=%d cnt %d q %d\n", + chsa, i, ec_data.xtr_ptr, ec_data.rec_ptr, ec_data.conf[9], chp->ccw_count, n); + uptr->CMD &= LMASK; /* remove old status bits & cnt */ + + /* Read must be word bounded */ + if (chp->ccw_addr & 0x3) { + sim_debug(DEBUG_EXP, dptr, + "ec_srv iocd bad address caw %06x ccw %06x\n", + chp->chan_caw, chp->ccw_addr); + ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & LOOP_MSK; + chp->ccw_count = 0; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH|STATUS_PCHK); + break; + } + + uptr->SNS &= LMASK; /* remove old count */ + ec_master_uptr->SNS |= SNS_RCV_RDY; + ec_packet_debug(&ec_data, "recv", &ec_data.rec_buff[ec_data.xtr_ptr]); + pck = (uint8 *)(&ec_data.rec_buff[ec_data.xtr_ptr].msg[0]); + len = (int)(ec_data.rec_buff[ec_data.xtr_ptr].len); + n = sizeof(struct ec_eth_hdr); + cnt = len - n; /* number of data bytes */ + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv READ addr %06x pktlen 0x%x rdcnt 0x%x conf 0x%x\n", + chp->ccw_addr, len, chp->ccw_count, ec_data.conf[9]); + + switch (GET_MODE(ec_master_uptr->flags)) { + case 0: + /* create output: destination(6)/source(6)/type(2) or len(2)/ data 46-1500 */ + /* user buffer: destination(6)/source(6)/type(2) or len)2) */ + for(i = 0; i < sizeof(struct ec_eth_hdr); i++) { + if (chan_write_byte(chsa, &pck[i])) { + pirq = 1; + break; + } + } + uptr->SNS |= (len & 0xffff); /* set real transfer count */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 0 received bytes %d (0x%x) SNS %08x i 0x%x cnt 0x%x\n", + len, len, uptr->SNS, i, cnt); + break; + case 1: + case 2: + /* create output: destination(6)/len(2)/source(6)/type(2) or len(2)/ data 46-1500 */ + /* destination / len / source / type or len */ + /* copy 6 byte destination */ + for(i = 0; i < sizeof(ETH_MAC); i++) { + if (chan_write_byte(chsa, &pck[i])) { + pirq = 1; + break; + } + } + /* insert length byte 1 */ + ch = (len >> 8) & 0xff; + if (chan_write_byte(chsa, &ch)) { + pirq = 1; + break; + } + /* insert length byte 2 */ + ch = len & 0xff; + if (chan_write_byte(chsa, &ch)) { + pirq = 1; + break; + } + /* copy in source(6)/type(2) 6 + 2 = 8 = 14 - 6 */ + for(; i < sizeof(struct ec_eth_hdr); i++) { + if (chan_write_byte(chsa, &pck[i])) { + pirq = 1; + break; + } + if (i>5) + sim_debug(DEBUG_DATA, &ec_dev, "ec_srr pck[%3x]: %02x\n", i, pck[i]); + } + uptr->SNS |= ((len+2) & 0xffff); /* set real transfer count */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 1&2 received bytes %d (0x%x) SNS %08x i 0x%x cnt 0x%x\n", + len, len, uptr->SNS, i, cnt); + break; + case 3: + /* create output: destination(6)/len(2)/source(6)/len(2)/ data 46-1500 */ + /* copy 6 byte destination */ + for(i = 0; i < sizeof(ETH_MAC); i++) { + if (chan_write_byte(chsa, &pck[i])) { + pirq = 1; + break; + } + } + /* insert length byte 1 */ + ch = (len >> 8) & 0xff; + if (chan_write_byte(chsa, &ch)) { + pirq = 1; + break; + } + /* insert length byte 2 */ + ch = len & 0xff; + if (chan_write_byte(chsa, &ch)) { + pirq = 1; + break; + } + /* copy in 6 byte source */ + for (; i < sizeof(ETH_MAC) * 2; i++) { + if (chan_write_byte(chsa, &pck[i])) { + pirq = 1; + break; + } + if (i>5) + sim_debug(DEBUG_DATA, &ec_dev, "ec_srr pck[%3x]: %02x\n", i, pck[i]); + } + /* insert length byte 1 */ + ch = (len >> 8) & 0xff; + if (chan_write_byte(chsa, &ch)) { + pirq = 1; + break; + } + /* insert length byte 2 */ + ch = len & 0xff; + if (chan_write_byte(chsa, &ch)) { + pirq = 1; + break; + } + uptr->SNS |= ((len + 2) & 0xffff); /* set real transfer count */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 3 received bytes %d (0x%x) SNS %08x i 0x%x cnt 0x%x\n", + len, len, uptr->SNS, i, cnt); + break; + } + + /* see if user did not request enough data */ + i = sizeof(struct ec_eth_hdr); + if (pirq || (i >= len)) { + ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & LOOP_MSK; + ec_data.rx_count++; + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv0 pirq %d cnt %x received bytes %d of %d rx_count=%08x conf %x\n", + pirq, cnt, i, len, ec_data.rx_count, ec_data.conf[9]); + /* diag wants incorrect length error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH); + break; + } + + /* now copy in the user data */ + for (i = sizeof(struct ec_eth_hdr); i < len; i++) { + if (i > (len - 8)) + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_sww pck[%3x]: %02x %02x\n", i, pck[i], chp->ccw_count); + if (chan_write_byte(chsa, &pck[i])) { + /* we read less than or exact bytes, good to go */ + ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & LOOP_MSK; + ec_data.rx_count++; + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv1 left 0x%x rec'd 0x%x bytes rx_count %08x conf %02x SNS %08x\n", + chp->ccw_count, len, ec_data.rx_count, ec_data.conf[9], uptr->SNS); + /* diag wants incorrect length error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH); + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv done cmd=%02x chsa %04x addr %06x count %04x SNS 0x%08x stat %04x\n", + cmd, chsa, chp->ccw_addr, chp->ccw_count, uptr->SNS, chp->chan_status); + return SCPE_OK; + } + } + /* we have some bytes left, set count mismatch */ + chp->ccw_flags |= FLAG_SLI; + ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & LOOP_MSK; + ec_data.rx_count++; + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv2 left 0x%x rec'd 0x%x bytes rx_count %08x conf %02x SNS %08x\n", + chp->ccw_count, len, ec_data.rx_count, ec_data.conf[9], uptr->SNS); + /* diag does not want incorrect length error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case EC_LCC: /* 0x10 Configure LCC */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* Read up to 12 bytes of configuration data */ + for (i = 0; i < 12; i++) { + if (chan_read_byte(chsa, &ec_data.conf[i])) { + break; + } + } + sim_debug(DEBUG_CMD, &ec_dev, + "ec_srv LCC CONF: %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", + ec_data.conf[0], ec_data.conf[1], ec_data.conf[2], ec_data.conf[3], + ec_data.conf[4], ec_data.conf[5], ec_data.conf[6], ec_data.conf[7], + ec_data.conf[8], ec_data.conf[9], ec_data.conf[10], ec_data.conf[11]); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case EC_STATS: /* 0x14 Read Statistics */ + ch = 0; + /* First 5 words are always zero since these errors are not supported */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_DETAIL, dptr, "ec_srv stats drop_count %08x\n", ec_data.drop_cnt); + for (i = 0; i < STAT_LEN * 2; i++) { + if (i == 6) + ch = (ec_data.drop_cnt >> 8) & 0xff; + if (i == 7) + ch = ec_data.drop_cnt & 0xff; + if (i == 8) + ch = 0; + if (chan_write_byte(chsa, &ch)) { + break; + } + } + sim_debug(DEBUG_DETAIL, dptr, "ec_srv stats rx_count %08x\n", ec_data.rx_count); + ch = (ec_data.rx_count >> 24) & 0xff; + chan_write_byte(chsa, &ch); + ch = (ec_data.rx_count >> 16) & 0xff; + chan_write_byte(chsa, &ch); + ch = (ec_data.rx_count >> 8) & 0xff; + chan_write_byte(chsa, &ch); + ch = ec_data.rx_count & 0xff; + chan_write_byte(chsa, &ch); + sim_debug(DEBUG_DETAIL, dptr, "ec_srv stats tx_count %08x\n", ec_data.tx_count); + ch = (ec_data.tx_count >> 24) & 0xff; + chan_write_byte(chsa, &ch); + ch = (ec_data.tx_count >> 16) & 0xff; + chan_write_byte(chsa, &ch); + ch = (ec_data.tx_count >> 8) & 0xff; + chan_write_byte(chsa, &ch); + ch = ec_data.tx_count & 0xff; + chan_write_byte(chsa, &ch); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case EC_CSTATS: /* 0x15 Clear software counters */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + ec_data.rx_count = ec_data.tx_count = 0; + (void)chan_read_byte(chsa, &ch); + sim_debug(DEBUG_CMD, dptr, + "ec_srv cmd clear counters chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case EC_NOP: /* 0x03 NOP */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "ec_srv cmd NOP chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + /* diags want the count to be returned zero */ + chp->ccw_count = 0; /* NOP command count */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case EC_SNS: /* 0x04 Sense */ + sim_debug(DEBUG_CMD, dptr, + "ec_startcmd CMD sense cnt %02x\n", chp->ccw_count); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + + /* diags want incorrect length or prog check */ + if (chp->ccw_count < 0x04) { + chp->ccw_count = 0; /* zero command count */ + if ((chp->ccw_flags & FLAG_SLI) == 0) { + /* diag wants incorrect length */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH); + break; + } + } + + len = uptr->SNS & 0xffff; + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv SNS len %d xt %d rd %d\n", + len, ec_data.xtr_ptr, ec_data.rec_ptr); + ch = (uptr->SNS >> 24) & 0xfc; + ch |= GET_MODE(ec_master_uptr->flags); + sim_debug(DEBUG_DETAIL, dptr, "ec_srv sense b0 1 %02x\n", ch); + chan_write_byte(chsa, &ch); + ch = (ec_master_uptr->SNS >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "ec_srv sense b1 2 %02x\n", ch); + chan_write_byte(chsa, &ch); + ch = (len >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "ec_srv sense b2 3 %02x\n", ch); + chan_write_byte(chsa, &ch); + ch = len & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "ec_srv sense b3 4 %02x\n", ch); + chan_write_byte(chsa, &ch); + + if (chp->ccw_count > 0) { + if (chp->ccw_flags & FLAG_SLI) + /* diags want prog check */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + /* diag wants incorrect length */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH); + sim_debug(DEBUG_CMD, dptr, + "ec_startcmd CMD sense excess cnt %02x\n", chp->ccw_count); + break; + } +//020522uptr->SNS &= ~(SNS_CMDREJ|SNS_EQUCHK); /* clear old status */ + uptr->SNS = 0; /* clear old status */ + uptr->SNS &= LMASK; /* remove old count */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + break; + + default: + sim_debug(DEBUG_CMD, dptr, "invalid command %02x\n", cmd); + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + } + sim_debug(DEBUG_DETAIL, dptr, + "ec_srv done cmd=%02x chsa %04x count %04x addr %06x flags %04x stat %x SNS 0x%x\n", + cmd, chsa, chp->ccw_count, chp->ccw_addr, chp->ccw_flags, chp->chan_status, uptr->SNS); + return SCPE_OK; +} + +/* Handle haltio transfers for ethernet */ +t_stat ec_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int cmd = uptr->CMD & EC_CMDMSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_EXP, dptr, "ec_haltio enter chsa %04x chp %p cmd %02x\n", chsa, chp, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + if ((uptr->CMD & EC_CMDMSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "ec_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count); + // stop any I/O and post status and return error status */ + if (chsa & 0x0f) /* no cancel for 0 */ + sim_cancel(uptr); /* clear the output timer */ + chp->ccw_count = 0; /* zero the count */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* stop any chaining */ + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS = SNS_RCV_RDY; /* status is online & ready */ + sim_debug(DEBUG_CMD, dptr, + "ec_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); + /* No unit exception status for ethernet */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ + return CC1BIT | SCPE_IOERR; + } + sim_debug(DEBUG_CMD, dptr, + "ec_haltio HIO I/O not busy chsa %04x cmd = %02x\n", chsa, cmd); + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS = SNS_RCV_RDY; /* status is online & ready */ + return CC1BIT | SCPE_OK; /* not busy */ +} + +/* initialize the ethernet */ +void ec_ini(UNIT *uptr, t_bool f) +{ + DEVICE *dptr = get_dev(uptr); + + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS = 0; /* save mode value */ + memset(&ec_data.conf[0], 0, sizeof(ec_data.conf)); + ec_data.macs_n = 0; + ec_data.tx_count = 0; + ec_data.rx_count = 0; + ec_data.rec_ptr = 0; + ec_data.xtr_ptr = 0; + ec_data.drop_cnt = 0; + ec_data.amc = 0; + if (ec_master_uptr->flags & UNIT_ATT) { + /* multicast on means promiscous is too */ + eth_filter (&ec_data.etherface, ec_data.macs_n + 2, ec_data.macs, + ec_data.amc, ec_data.macs[0][0] & 1); + sim_debug(DEBUG_EXP, dptr, + "EC init device %s is attached on unit EC%04X\n", + dptr->name, GET_UADDR(uptr->CMD)); + } else { + sim_debug(DEBUG_EXP, dptr, + "EC init device %s not attached on unit EC%04X\n", + dptr->name, GET_UADDR(uptr->CMD)); +//OLD uptr->SNS |= SNS_NO_CAR; /* no carrier error */ + } +} + +/* handle reset controller cmds for Ethernet */ +t_stat ec_rsctrl(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & EC_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, + "ec_rsctlr chsa %04x cmd = %02x\n", chsa, cmd); +// memset(&ec_data.conf[0], 0, sizeof(ec_data.conf)); + ec_data.tx_count = 0; + ec_data.rx_count = 0; + ec_data.drop_cnt = 0; + ec_data.rec_ptr = 0; /* clear queue */ + ec_data.xtr_ptr = 0; /* clear queue */ + return SCPE_OK; +} + +/* handle reset channel cmds for Ethernet */ +t_stat ec_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & EC_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, + "ec_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + ec_ini(uptr, 0); /* reset the unit */ + /* the interrupt level will be reset in sel32_chan.c code */ + return SCPE_OK; +} + +static char * +ipv4_inet_ntoa(struct in_addr ip) +{ + static char str[20]; + + if (sim_end) + sprintf (str, "%d.%d.%d.%d", ip.s_addr & 0xFF, + (ip.s_addr >> 8) & 0xFF, + (ip.s_addr >> 16) & 0xFF, + (ip.s_addr >> 24) & 0xFF); + else + sprintf (str, "%d.%d.%d.%d", (ip.s_addr >> 24) & 0xFF, + (ip.s_addr >> 16) & 0xFF, + (ip.s_addr >> 8) & 0xFF, + ip.s_addr & 0xFF); + return str; +} + +/* + * Pretty print a packet for debugging. + */ +void ec_packet_debug(struct ec_device *ec, const char *action, + ETH_PACK *packet) { + struct ec_eth_hdr *eth = (struct ec_eth_hdr *)&packet->msg[0]; + struct arp_hdr *arp = (struct arp_hdr *)eth; + struct ip *ip = (struct ip *)&packet->msg[sizeof(struct ec_eth_hdr)]; + struct udp *udp; + struct tcp *tcp; + struct icmp *icmp; + uint8 *payload; + struct in_addr ipaddr; + size_t len; + int flag; + char src_ip[20]; + char dst_ip[20]; + char src_port[8]; + char dst_port[8]; + char flags[64]; + static struct tcp_flag_bits { + const char *name; + uint16 bitmask; + } bits[] = { + {"FIN", TCP_FL_FIN}, + {"SYN", TCP_FL_SYN}, + {"RST", TCP_FL_RST}, + {"PSH", TCP_FL_PSH}, + {"ACK", TCP_FL_ACK}, + {"URG", TCP_FL_URG}, + {NULL, 0} + }; + static const char *icmp_types[] = { + "Echo Reply", // Type 0 + "Type 1 - Unassigned", + "Type 2 - Unassigned", + "Destination Unreachable", // Type 3 + "Source Quench (Deprecated)", // Type 4 + "Redirect", // Type 5 + "Type 6 - Alternate Host Address (Deprecated)", + "Type 7 - Unassigned", + "Echo Request", // Type 8 + "Router Advertisement", // Type 9 + "Router Selection", // Type 10 + "Time Exceeded", // Type 11 + "Type 12 - Parameter Problem", + "Type 13 - Timestamp", + "Type 14 - Timestamp Reply", + "Type 15 - Information Request (Deprecated)", + "Type 16 - Information Reply (Deprecated)", + "Type 17 - Address Mask Request (Deprecated)", + "Type 18 - Address Mask Reply (Deprecated)", + "Type 19 - Reserved (for Security)", + "Type 20 - Reserved (for Robustness Experiment)", + "Type 21 - Reserved (for Robustness Experiment)", + "Type 22 - Reserved (for Robustness Experiment)", + "Type 23 - Reserved (for Robustness Experiment)", + "Type 24 - Reserved (for Robustness Experiment)", + "Type 25 - Reserved (for Robustness Experiment)", + "Type 26 - Reserved (for Robustness Experiment)", + "Type 27 - Reserved (for Robustness Experiment)", + "Type 28 - Reserved (for Robustness Experiment)", + "Type 29 - Reserved (for Robustness Experiment)", + "Type 30 - Traceroute (Deprecated)", + "Type 31 - Datagram Conversion Error (Deprecated)", + "Type 32 - Mobile Host Redirect (Deprecated)", + "Type 33 - IPv6 Where-Are-You (Deprecated)", + "Type 34 - IPv6 I-Am-Here (Deprecated)", + "Type 35 - Mobile Registration Request (Deprecated)", + "Type 36 - Mobile Registration Reply (Deprecated)", + "Type 37 - Domain Name Request (Deprecated)", + "Type 38 - Domain Name Reply (Deprecated)", + "Type 39 - SKIP (Deprecated)", + "Type 40 - Photuris", + "Type 41 - ICMP messages utilized by experimental mobility protocols such as Seamoby", + "Type 42 - Extended Echo Request", + "Type 43 - Extended Echo Reply" + }; + + if (ntohs(eth->type) == ETHTYPE_ARP) { + struct in_addr in_addr; + const char *arp_op = (ARP_REQUEST == ntohs(arp->opcode)) ? "REQUEST" : + ((ARP_REPLY == ntohs(arp->opcode)) ? "REPLY" : "Unknown"); + char eth_src[20], eth_dst[20]; + char arp_shwaddr[20], arp_dhwaddr[20]; + char arp_sipaddr[20], arp_dipaddr[20]; + + if (!(ec_dev.dctrl & DEBUG_ARP)) + return; + eth_mac_fmt(&arp->ethhdr.src, eth_src); + eth_mac_fmt(&arp->ethhdr.dest, eth_dst); + eth_mac_fmt(&arp->shwaddr, arp_shwaddr); + memcpy(&in_addr, &arp->sipaddr, sizeof(in_addr)); + strlcpy(arp_sipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_sipaddr)); + eth_mac_fmt(&arp->dhwaddr, arp_dhwaddr); + memcpy(&in_addr, &arp->dipaddr, sizeof(in_addr)); + strlcpy(arp_dipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_dipaddr)); + sim_debug(DEBUG_ARP, &ec_dev, + "%s %s EthDst=%s EthSrc=%s shwaddr=%s sipaddr=%s dhwaddr=%s dipaddr=%s\n", + action, arp_op, eth_dst, eth_src, arp_shwaddr, arp_sipaddr, arp_dhwaddr, arp_dipaddr); + return; + } +#ifdef OLDWAY + if (ntohs(eth->type) != ETHTYPE_IP) { + payload = (uint8 *)&packet->msg[0]; + len = packet->len; + sim_data_trace(&ec_dev, ec_unit, payload, "", len, "", DEBUG_DATA); + return; + } +#else + /* always dump packet */ + payload = (uint8 *)&packet->msg[0]; + len = packet->len; + sim_data_trace(&ec_dev, ec_unit, payload, "", len, "", DEBUG_DATA); + if (ntohs(eth->type) != ETHTYPE_IP) { + return; + } +#endif + if (!(ec_dev.dctrl & (DEBUG_TCP|DEBUG_UDP|DEBUG_ICMP))) + return; + memcpy(&ipaddr, &ip->ip_src, sizeof(ipaddr)); + strlcpy(src_ip, ipv4_inet_ntoa(ipaddr), sizeof(src_ip)); + memcpy(&ipaddr, &ip->ip_dst, sizeof(ipaddr)); + strlcpy(dst_ip, ipv4_inet_ntoa(ipaddr), sizeof(dst_ip)); + payload = (uint8 *)&packet->msg[sizeof(struct ec_eth_hdr) + (ip->ip_v_hl & 0xf) * 4]; + switch (ip->ip_p) { + case UDP_PROTO: + udp = (struct udp *)payload; + snprintf(src_port, sizeof(src_port), "%d", ntohs(udp->udp_sport)); + snprintf(dst_port, sizeof(dst_port), "%d", ntohs(udp->udp_dport)); + sim_debug(DEBUG_UDP, &ec_dev, "%s %d byte packet from %s:%s to %s:%s\n", action, + ntohs(udp->len), src_ip, src_port, dst_ip, dst_port); + if (udp->len && (ec_dev.dctrl & DEBUG_UDP)) + sim_data_trace(&ec_dev, ec_unit, payload + sizeof(struct udp), "", + ntohs(udp->len), "", DEBUG_DATA); + break; + case TCP_PROTO: + tcp = (struct tcp *)payload; + snprintf(src_port, sizeof(src_port), "%d", ntohs(tcp->tcp_sport)); + snprintf(dst_port, sizeof(dst_port), "%d", ntohs(tcp->tcp_dport)); + strlcpy(flags, "", sizeof(flags)); + for (flag=0; bits[flag].name; flag++) { + if (ntohs(tcp->flags) & bits[flag].bitmask) { + if (*flags) + strlcat(flags, ",", sizeof(flags)); + strlcat(flags, bits[flag].name, sizeof(flags)); + } + + } + len = ntohs(ip->ip_len) - ((ip->ip_v_hl & 0xf) * 4 + (ntohs(tcp->flags) >> 12) * 4); + sim_debug(DEBUG_TCP, &ec_dev, "%s %s%s %d byte packet from %s:%s to %s:%s\n", action, + flags, *flags ? ":" : "", (int)len, src_ip, src_port, dst_ip, dst_port); + if (len && (ec_dev.dctrl & DEBUG_TCP)) + sim_data_trace(&ec_dev, ec_unit, payload + + 4 * (ntohs(tcp->flags) >> 12), "", len, "", DEBUG_DATA); + break; + case ICMP_PROTO: + icmp = (struct icmp *)payload; + len = ntohs(ip->ip_len) - (ip->ip_v_hl & 0xf) * 4; + sim_debug(DEBUG_ICMP, &ec_dev, "%s %s %d byte packet from %s to %s\n", action, + (icmp->type < sizeof(icmp_types)/sizeof(icmp_types[0])) ? + icmp_types[icmp->type] : "", (int)len, src_ip, dst_ip); + if (len && (ec_dev.dctrl & DEBUG_ICMP)) + sim_data_trace(&ec_dev, ec_unit, payload + sizeof(struct icmp), "", len, "", DEBUG_DATA); + break; + } +} + +t_stat ec_show_mode (FILE* st, UNIT* uptr, int32 val, CONST void* desc) +{ + fprintf(st, "MODE=%d", GET_MODE(uptr->flags)); + return SCPE_OK; +} + +t_stat ec_set_mode (UNIT* uptr, int32 val, CONST char* cptr, void* desc) +{ + t_stat r; + int newmode; + + if (!cptr) return SCPE_IERR; + + newmode = get_uint(cptr, 10, 4, &r); + + if (r != SCPE_OK) + return r; + + if (newmode > 3) + return SCPE_ARG; + + uptr->flags &= ~UNIT_MODE; + uptr->flags |= SET_MODE(newmode); + return SCPE_OK; +} + + +t_stat ec_show_mac (FILE* st, UNIT* uptr, int32 val, CONST void* desc) +{ + char buffer[20]; + eth_mac_fmt(&ec_data.mac, buffer); + fprintf(st, "MAC=%s", buffer); + return SCPE_OK; +} + +t_stat ec_set_mac (UNIT* uptr, int32 val, CONST char* cptr, void* desc) +{ + t_stat status; + + if (!cptr) return SCPE_IERR; + if (uptr->flags & UNIT_ATT) return SCPE_ALATT; + + status = eth_mac_scan_ex(&ec_data.mac, cptr, uptr); + if (status != SCPE_OK) + return status; + + return SCPE_OK; +} + +t_stat ec_reset (DEVICE *dptr) +{ + int i; + + for (i = 0; i < sizeof(ETH_MAC); i++) { + if (ec_data.mac[i] != 0) + break; + } + if (i == 6) { /* First call to reset? */ + /* Set a default MAC address in a BBN assigned OID range no longer in use */ + ec_set_mac (dptr->units, 0, "00:00:02:00:00:00/24", NULL); + } + memset(&ec_data.conf[0], 0, sizeof(ec_data.conf)); + ec_data.macs_n = 0; + ec_data.tx_count = 0; + ec_data.rx_count = 0; + ec_data.rec_ptr = 0; + ec_data.xtr_ptr = 0; + ec_data.drop_cnt = 0; + ec_data.amc = 0; + if (ec_master_uptr->flags & UNIT_ATT) + /* multicast on means promiscous is too */ + eth_filter (&ec_data.etherface, ec_data.macs_n + 2, ec_data.macs, + ec_data.amc, ec_data.macs[0][0] & 1); + sim_debug(DEBUG_EXP, dptr, + "EC reset device %s on unit EC%04X\n", dptr->name, + GET_UADDR(dptr->units->CMD)); + return SCPE_OK; +} + +/* attach device: */ +t_stat ec_attach(UNIT* uptr, CONST char* cptr) +{ + t_stat status; + char* tptr; + char buf[32]; + + tptr = (char *) malloc(strlen(cptr) + 1); + if (tptr == NULL) return SCPE_MEM; + strcpy(tptr, cptr); + + memcpy(&ec_data.macs[0], &ec_data.mac, sizeof (ETH_MAC)); + memcpy(&ec_data.macs[1], &broadcast_ethaddr, sizeof (ETH_MAC)); + status = eth_open(&ec_data.etherface, cptr, &ec_dev, DEBUG_ETHER); + if (status != SCPE_OK) { + free(tptr); + return status; + } + eth_mac_fmt(&ec_data.mac, buf); /* format ethernet mac address */ + if (SCPE_OK != eth_check_address_conflict (&ec_data.etherface, + &ec_data.mac)) { + eth_close(&ec_data.etherface); + free(tptr); + return sim_messagef (SCPE_NOATT, + "%s: MAC Address Conflict on LAN for address %s\n", + ec_dev.name, buf); + } + if (SCPE_OK != eth_filter(&ec_data.etherface, 2, ec_data.macs, 0, 0)) { + eth_close(&ec_data.etherface); + free(tptr); + return sim_messagef (SCPE_NOATT, + "%s: Can't set packet filter for MAC Address %s\n", + ec_dev.name, buf); + } + + uptr->filename = tptr; + uptr->flags |= UNIT_ATT; + eth_setcrc(&ec_data.etherface, 0); /* Enable CRC */ + + /* init read queue (first time only) */ + status = ethq_init(&ec_data.ReadQ, 8); /* 8 per device */ + if (status != SCPE_OK) { + eth_close(&ec_data.etherface); + uptr->filename = NULL; + free(tptr); + return sim_messagef (status, "%s: Can't initialize receive queue\n", + ec_dev.name); + } + + eth_set_async (&ec_data.etherface, 0); + return SCPE_OK; +} + +/* detach device: */ +t_stat ec_detach(UNIT* uptr) +{ + if ((uptr->flags & UNIT_ATT) && (uptr->flags & UNIT_DIS) == 0) { + eth_close (&ec_data.etherface); + free(uptr->filename); + uptr->filename = NULL; + uptr->flags &= ~UNIT_ATT; + } + return SCPE_OK; +} + +t_stat ec_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf(st, "Ethernet interface\n\n"); + fprintf(st, "The ethernet interfaces to the network. Setting MAC defines default MAC address\n"); + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + eth_attach_help(st, dptr, uptr, flag, cptr); + return SCPE_OK; +} + +const char *ec_description (DEVICE *dptr) +{ + return "SEL32 8516 Ethernet interface"; +} +#endif diff --git a/SEL32/sel32_fltpt.c b/SEL32/sel32_fltpt.c new file mode 100644 index 00000000..c9f09b9a --- /dev/null +++ b/SEL32/sel32_fltpt.c @@ -0,0 +1,1637 @@ +/* sel32_fltpt.c: SEL 32 floating point instructions processing. + + Copyright (c) 2018-2021, James C. Bevier + Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers + + 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 + JAMES C. BEVIER 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. + + This set of subroutines simulate the excess 64 floating point instructions. + ADFW - add memory float to register + ADFD - add memory double to register pair + SUFW - subtract memory float from register + SUFD - subtract memory double from register pair + MPFW - multiply register by memory float + MPFD - multiply register pair by memory double + DVFW - divide register by memory float + DVFD - divide register pair by memory double + FIXW - convert float to integer (32 bit) + FIXD - convert double to long long (64 bit) + FLTW - convert integer (32 bit) to float + FLTD - convert long long (64 bit) to double + ADRFW - add regist float to register + SURFW - subtract register float from register + DVRFW - divide register float by register float + MPRFW - multiply register float by register float + ADRFD - add register pair double to register pair double + SURFD - subtract register pair double from register pair double + DVRFD - divide register pair double by register pair double + MPRFD - multiply register pair double by register pair double + + Floating Point Formats + float + S - 1 sign bit + X - 7 bit exponent + M - 24 bit mantissa + S XXXXXXX MMMMMMMM MMMMMMMM MMMMMMMM + double + S - 1 sign bit + X - 7 bit exponent + M - 56 bit mantissa + S XXXXXXX MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM + +*/ + +#include "sel32_defs.h" +#include + +uint32 s_fixw(uint32 val, uint32 *cc); +uint32 s_fltw(uint32 val, uint32 *cc); + +t_uint64 s_fixd(t_uint64 val, uint32 *cc); +t_uint64 s_fltd(t_uint64 val, uint32 *cc); + +uint32 s_nor(uint32 reg, uint32 *exp); +t_uint64 s_nord(t_uint64 reg, uint32 *exp); + +uint32 s_mpfw(uint32 reg, uint32 mem, uint32 *cc); +uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc); + +uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc); +uint32 s_sufw(uint32 reg, uint32 mem, uint32 *cc); + +t_uint64 s_adfd(t_uint64 reg, t_uint64 mem, uint32 *cc); +t_uint64 s_sufd(t_uint64 reg, t_uint64 mem, uint32 *cc); + +t_uint64 s_mpfd(t_uint64 reg, t_uint64 mem, uint32 *cc); +t_uint64 s_dvfd(t_uint64 reg, t_uint64 mem, uint32 *cc); + +uint32 s_normfw(uint32 num, uint32 *cc); +t_uint64 s_normfd(t_uint64 num, uint32 *cc); + +#define NORMASK 0xf8000000 /* normalize 5 bit mask */ +#define DNORMASK 0xf800000000000000ll /* double normalize 5 bit mask */ +#define EXMASK 0x7f000000 /* exponent mask */ +#define FRMASK 0x80ffffff /* fraction mask */ +#define DEXMASK 0x7f00000000000000ll /* exponent mask */ +#define DFSVAL 0xff00000000000000ll /* minus full scale value */ +#define DFRMASK 0x80ffffffffffffffll /* fraction mask */ +#define NEGATE32(val) ((~val) + 1) /* negate a value 16/32/64 bits */ + +/************************************************************** +* Common routine for finishing the various F.P. instruction * +* * +* Floating point operations not terminating with an arith- * +* metic exception produce the following condition codes: * +* * +* CC1 CC2 CC3 CC4 Definition * +* ------------------------------------------------------- * +* 0 1 0 0 no exception, fraction positive * +* 0 0 1 0 no exception, fraction negative * +* 0 0 0 1 no exception, fraction = zero * +* * +* * +* an arithmetic exception produces the follwing condition * +* code settings: * +* * +* CC1 CC2 CC3 CC4 Definition * +* -------------------------------------------------------- * +* 1 0 1 0 exp underflow, fraction negative * +* 1 0 1 1 exp overflow, fraction negative * +* 1 1 0 0 exp underflow, fraction positive * +* 1 1 0 1 exp overflow, fraction positive * +* * +**************************************************************/ + +/* normalize floating point fraction */ +uint32 s_nor(uint32 reg, uint32 *exp) { + uint32 texp = 0; /* no exponent yet */ + + if (reg != 0) { /* do nothing if reg is already zero */ + uint32 mv = reg & NORMASK; /* mask off bits 0-4 */ + while ((mv == 0) || (mv == NORMASK)) { + /* not normalized yet, so shift 4 bits left */ + reg <<= 4; /* move over 4 bits */ + texp++; /* bump shift count */ + mv = reg & NORMASK; /* just look at bits 0-4 */ + } + /* bits 0-4 of reg is neither 0 nor all ones */ + /* show that reg is normalized */ + texp = (uint32)(0x40-(int32)texp); /* subtract shift count from 0x40 */ + } + *exp = texp; /* return exponent */ + return (reg); /* return normalized register */ +} + +/* normalize double floating point number */ +t_uint64 s_nord(t_uint64 reg, uint32 *exp) { + uint32 texp = 0; /* no exponent yet */ + + if (reg != 0) { /* do nothing if reg is already zero */ + t_uint64 mv = reg & DNORMASK; /* mask off bits 0-4 */ + while ((mv == 0) || (mv == DNORMASK)) { + /* not normalized yet, so shift 4 bits left */ + reg <<= 4; /* move over 4 bits */ + texp++; /* bump shift count */ + mv = reg & DNORMASK; /* just look at bits 0-4 */ + } + /* bits 0-4 of reg is neither 0 nor all ones */ + /* show that reg is normalized */ + texp = (uint32)(0x40-(int32)texp); /* subtract shift count from 0x40 */ + } + *exp = texp; /* return exponent */ + return (reg); /* return normalized double register */ +} + +/* normalize the memory value when adding number to zero */ +uint32 s_normfw(uint32 num, uint32 *cc) { + uint32 ret; + int32 val; /* temp word */ + int32 exp; /* exponent */ + int32 CCs; /* condition codes */ + uint8 sign; /* original sign */ + + if (num == 0) { /* make sure we have a number */ + *cc = CC4BIT; /* set the cc's */ + return 0; /* return zero */ + } + sign = 0; + + /* special case 0x80000000 (-0) to set CCs to 1011 * value to 0x80000001 */ + if (num == 0x80000000) { + CCs = CC1BIT|CC3BIT|CC4BIT; /* we have AE, exp overflow, neg frac */ + ret = 0x80000001; /* return max neg value */ + + /* return normalized number */ + *cc = CCs; /* set the cc's */ + return ret; /* return result */ + } + + /* special case pos exponent & zero mantissa to be 0 */ + if (((num & 0x80000000) == 0) && ((num & 0xff000000) > 0) && ((num & 0x00ffffff) == 0)) { + ret = 0; /* 0 to any power is still 0 */ + CCs = CC4BIT; /* set zero CC */ + + /* return normalized number */ + *cc = CCs; /* set the cc's */ + return ret; /* return result */ + } + + /* if we have 1xxx xxxx 0000 0000 0000 0000 0000 0000 */ + /* we need to convert to 1yyy yyyy 1111 0000 0000 0000 0000 0000 */ + /* where y = x - 1 */ + if ((num & 0x80ffffff) == 0x80000000) { + int nexp = (0x7f000000 & num) - 0x01000000; + num = 0x80000000 | (nexp & 0x7f000000) | 0x00f00000; + } + + exp = (num & 0x7f000000) >> 24; /* get exponent */ + if (num & 0x80000000) { /* test for neg */ + sign = 1; /* we are neq */ + num = NEGATE32(num); /* two's complement */ + exp ^= 0x7f; /* complement exponent */ + } + val = num & 0x00ffffff; /* get mantissa */ + + /* now make sure number is normalized */ + while ((val != 0) && ((val & 0x00f00000) == 0)) { + val <<= 4; /* move up a nibble */ + exp--; /* and decrease exponent */ + } + + if (exp < 0) { /* check for underflow */ + CCs = CC1BIT; /* we have underflow */ + if (sign & 1) /* we are neq */ + CCs |= CC3BIT; /* set neg CC */ + else + CCs |= CC2BIT; /* set pos CC */ + ret = 0; /* number too small, make 0 */ + exp = 0; /* exponent too */ + + /* return normalized number */ + *cc = CCs; /* set the cc's */ + return ret; /* return result */ + } + + /* rebuild normalized number */ + val = ((val & 0x00ffffff) | ((exp & 0x7f) << 24)); + if (sign & 1) /* we are neq */ + val = NEGATE32(val); /* two's complement */ + if (val == 0) + CCs = CC4BIT; /* show zero */ + else if (val & 0x80000000) /* neqative? */ + CCs = CC3BIT; /* show negative */ + else + CCs = CC2BIT; /* show positive */ + ret = val; /* return normalized number */ + + /* return normalized number */ + *cc = CCs; /* set the cc's */ + return ret; /* return result */ +} + +#ifdef FOR_DEBUG +/* sfpval - determine floating point data value */ +float sfpval(uint32 val) +{ + uint32 wd32; + float num; + int32 exp; + + exp = ((val >> 24) & 0x7f) - 0x40; /* get exponent and remove excess 0x40 */ + wd32 = val & 0x00ffffff; /* get mantissa */ + num = (float)wd32; /* make it a float */ + num *= exp2f((4*exp) - 24); /* raise to power of exponent */ + if (val & 0x80000000) + num *= -1.0; /* if negative, return negative num */ + return num; /* return value */ +} + +/* dfpval - determine double floating point data value */ +double dfpval(t_uint64 wd64) +{ + double dbl; + int32 exp; + t_uint64 sav = wd64; + + if (wd64 & 0x8000000000000000ll) + wd64 = NEGATE32(wd64); + exp = ((wd64 >> 56) & 0x7f) - 0x40; /* get exponent and remove excess 0x40 */ + wd64 &= 0x00ffffffffffffffll; /* get 56 bit mantissa */ + dbl = (double)wd64; /* make it a double float */ + dbl *= exp2((4*exp) - 56); /* raise to power of exponent */ + if (sav & 0x8000000000000000ll) + dbl *= -1.0; /* if negative, return negative num */ + return dbl; /* return value */ +} +#endif /* FOR_DEBUG */ + +/* normalize the memory value when adding number to zero */ +t_uint64 s_normfd(t_uint64 num, uint32 *cc) { + t_uint64 ret; + t_uint64 val; /* temp word */ + int32 exp; /* exponent */ + int32 CCs; /* condition codes */ + uint8 sign; /* original sign */ + + if (num == 0) { /* make sure we have a number */ + *cc = CC4BIT; /* set the cc's */ + return 0; /* return zero */ + } + sign = 0; + + /* special case 0x8000000000000000 (-0) to set CCs to 1011 */ + /* and value to 0x8000000000000001 */ + if (num == 0x8000000000000000LL) { + CCs = CC1BIT|CC3BIT|CC4BIT; /* we have AE, exp overflow, neg frac */ + ret = 0x8000000000000001LL; /* return max neg value */ + /* return normalized number */ + *cc = CCs; /* set the cc's */ + return ret; /* return normalized result */ + } + + /* special case pos exponent & zero mantissa to be 0 */ + if (((num & 0x8000000000000000LL) == 0) && ((num & 0xff00000000000000LL) > 0) && + (num & 0x00ffffffffffffffLL) == 0) { + ret = 0; /* 0 to any power is still 0 */ + CCs = CC4BIT; /* set zero CC */ + /* return normalized number */ + *cc = CCs; /* set the cc's */ + return ret; /* return normalized result */ + } + + /* if we have 1xxx xxxx 0000 0000 0000 0000 0000 0000 */ + /* we need to convert to 1yyy yyyy 1111 0000 0000 0000 0000 0000 */ + /* where y = x - 1 */ + if ((num & 0x80ffffffffffffffLL) == 0x8000000000000000LL) { + t_uint64 nexp = (0x7f00000000000000LL & num) - 0x0100000000000000LL; + num = 0x8000000000000000LL | (nexp & 0x7f00000000000000LL) | 0x00f0000000000000LL; + } + + exp = (num & 0x7f00000000000000LL) >> 56; /* get exponent */ + if (num & 0x8000000000000000LL) { /* test for neg */ + sign = 1; /* we are neq */ + num = NEGATE32(num); /* two's complement */ + exp ^= 0x7f; /* complement exponent */ + } + val = num & 0x00ffffffffffffffLL; /* get mantissa */ + + /* now make sure number is normalized */ + while ((val != 0) && ((val & 0x00f0000000000000LL) == 0)) { + val <<= 4; /* move up a nibble */ + exp--; /* and decrease exponent */ + } + + if (exp < 0) { + CCs = CC1BIT; /* we have underflow */ + if (sign & 1) /* we are neg */ + CCs |= CC3BIT; /* set neg CC */ + else + CCs |= CC2BIT; /* set pos CC */ + ret = 0; /* number too small, make 0 */ + /* return normalized number */ + *cc = CCs; /* set the cc's */ + return ret; /* return normalized result */ + } + + /* rebuild normalized number */ + ret = ((val & 0x00ffffffffffffffll) | (((t_uint64)exp & 0x7f) << 56)); + if (sign & 1) /* we were neg */ + ret = NEGATE32(ret); /* two's complement */ + if (ret == 0) + CCs = CC4BIT; /* show zero */ + else if (ret & 0x8000000000000000LL) /* neqative? */ + CCs = CC3BIT; /* show negative */ + else + CCs = CC2BIT; /* show positive */ + + /* return normalized number */ + *cc = CCs; /* set the cc's */ + return ret; /* return normalized result */ +} + +/* convert from 32 bit float to 32 bit integer */ +/* set CC1 if overflow/underflow exception */ +uint32 s_fixw(uint32 fltv, uint32 *cc) { + uint32 CC = 0, temp, temp2, sc; + uint32 neg = 0; /* clear neg flag */ + + if (fltv & MSIGN) { /* check for negative */ + fltv = NEGATE32(fltv); /* make src positive */ + neg = 1; /* set neg val flag */ + } else { + if (fltv == 0) { /* value zero? */ + temp = 0; /* return zero */ + goto setcc; /* go set CC's */ + } + /* gt 0, fall through */ + } + temp2 = (uint32)(fltv >> 24); /* get exponent */ + fltv <<= 8; /* move src to upper 3 bytes */ + temp2 -= 64; /* take off excess notation */ + temp = temp2; /* save val */ + if ((int32)temp2 == 0) /* exp of zero means zero */ + goto setcc; /* go set CC's */ + if (temp2 & MSIGN) { + /* set CC1 for underflow */ + if (neg) { + temp = 0x7fffffff; /* too big, set to max value */ + goto OVFLO; /* go set CC's */ + } else { + temp = 0; /* assume zero for small values */ + goto UNFLO; /* go set CC's */ + } + } + + temp2 -= 8; /* see if in range */ + temp = fltv; /* save val */ + if ((temp2 == 0) && (fltv == 0x80000000) && (neg == 1)) + goto setcc; /* go set CC's */ + if ((int32)temp2 > 0) { + /* set CC1 for overflow */ + temp = 0; /* assume zero for small values */ + goto OVFLO; /* go set CC's */ + } + sc = (NEGATE32(temp2) * 4); /* pos shift cnt * 4 */ + fltv >>= sc; /* do 4 bit shifts */ + + /* see if overflow to neg */ + /* set CC1 for overflow */ + if (fltv & MSIGN) { + /* set CC1 for overflow */ + temp = 0; /* assume zero for small values */ + goto OVFLO; /* go set CC's */ + } + + /* see if original value was negative */ + if (neg) + fltv = NEGATE32(fltv); /* put back to negative */ + temp = fltv; /* return integer value */ + /* come here to set cc's and return */ + /* temp has return value */ +setcc: + if (temp & MSIGN) + CC |= CC3BIT; /* CC3 for neg */ + else if (temp == 0) + CC |= CC4BIT; /* CC4 for zero */ + else + CC |= CC2BIT; /* CC2 for greater than zero */ + /* return temp for destination reg */ + *cc = CC; /* return CC's */ + return temp; /* return result */ + + /* handle underflow/overflow */ +OVFLO: + CC |= CC4BIT; /* set CC4 for exponent overflow */ +UNFLO: + CC |= CC1BIT; /* set CC1 for arithmetic exception */ + if (neg) /* test for negative */ + CC |= CC3BIT; /* set neg fraction bit CC3 */ + else + CC |= CC2BIT; /* set pos fraction bit CC2 */ + *cc = CC; /* return CC's */ + return temp; /* return result */ +} + +/* convert from 32 bit integer to 32 bit float */ +/* No overflow (CC1) can be generated */ +uint32 s_fltw(uint32 intv, uint32 *cc) { + uint32 CC = 0; + uint32 ret; + uint32 neg = 0; /* zero sign flag */ + uint32 exp = 0; /* exponent */ + uint32 val = (int32)intv; /* integer value */ + + if (intv & 0x80000000) { + val = NEGATE32(intv); + neg = 1; + } + while ((val != 0) && ((val & 0xf0000000) == 0)) { + val <<= 4; /* no round up */ + exp--; + } + if (val != 0) + exp += 0x48; /* set default exponent */ + /* shift value rt 8 bits and round */ + if (val & 0x80) { + if (neg) { + if (val & 0x7f) + val = (val >> 8) + 1; /* round up */ + else + val = (val >> 8); /* no round up */ + } else { + val = (val >> 8) + 1; /* round up */ + } + } else + val = (val >> 8); /* no round up */ + if (val & 0x01000000) { + val = (val >> 4); /* move 1 nibble */ + exp++; + } + ret = (exp << 24) | (val & 0x00ffffff); /* merge value */ + if (neg) + ret = NEGATE32(ret); + if (ret & MSIGN) + CC |= CC3BIT; /* CC3 for neg */ + else if (ret == 0) + CC |= CC4BIT; /* CC4 for zero */ + else + CC |= CC2BIT; /* CC2 for greater than zero */ + /* return temp for destination reg */ + *cc = CC; /* save CC's */ + return ret; /* return results */ +} + +/* convert from 64 bit double to 64 bit integer */ +/* set CC1 if overflow/underflow exception */ +t_uint64 s_fixd(t_uint64 dblv, uint32 *cc) { + uint32 temp2, CC = 0, neg = 0, sc = 0; + t_uint64 dest; + + /* neg and CC flags already set to zero */ + if (dblv & DMSIGN) { + dblv = NEGATE32(dblv); /* make src positive */ + neg = 1; /* set neg val flag */ + } else { + if (dblv == 0) { + dest = 0; /* return zero */ + goto dodblcc; /* go set CC's */ + } + /* gt 0, fall through */ + } + + temp2 = (uint32)(dblv >> 56); /* get exponent */ + dblv <<= 8; /* move fraction to upper 7 bytes */ + temp2 -= 64; /* take off excess notation */ + dest = temp2; /* save val */ + if ((int32)temp2 == 0) /* zero exp means zero */ + goto dodblcc; /* go set CC's */ + if (temp2 & MSIGN) { + /* set CC1 for underflow */ + if (neg) { + dest = 0x7fffffffffffffff; /* too big, set to max value */ + goto DOVFLO; /* go set CC's */ + } else { + dest = 0; /* assume zero for small values */ + goto DUNFLO; /* go set CC's */ + } + } + + temp2 -= 16; /* see if in range */ + dest = dblv; /* save val */ + if ((temp2 == 0) && (dblv == DMSIGN) && (neg == 1)) + goto dodblcc; /* go set CC's */ + if ((int32)temp2 > 0) { + /* set CC1 for overflow */ + dest = 0; /* assume zero for small values */ + goto DOVFLO; /* go set CC's */ + } + sc = (NEGATE32(temp2) * 4); /* pos shift cnt * 4 */ + dblv >>= sc; /* do 4 bit shifts */ + + /* see if overflow to neg */ + if (dblv & DMSIGN) { + /* set CC1 for overflow */ + dest = 0; /* assume zero for small values */ + goto DOVFLO; /* go set CC's */ + } + /* see if original values was negative */ + if (neg) + dblv = NEGATE32(dblv); /* put back to negative */ + dest = dblv; /* return integer value */ + +dodblcc: + /* dest has return value */ + if (dest & DMSIGN) + CC |= CC3BIT; /* CC3 for neg */ + else if (dest == 0) + CC |= CC4BIT; /* CC4 for zero */ + else + CC |= CC2BIT; /* CC2 for greater than zero */ + *cc = CC; /* return CC's */ + return dest; /* return result */ + + /* handle underflow/overflow */ +DOVFLO: + CC |= CC4BIT; /* set CC4 for exponent overflow */ +DUNFLO: + CC |= CC1BIT; /* set CC1 for arithmetic exception */ + if (neg) /* test for negative */ + CC |= CC3BIT; /* set neg fraction bit CC3 */ + else + CC |= CC2BIT; /* set pos fraction bit CC2 */ + *cc = CC; /* return CC's */ + return dest; /* return result */ +} + +/* convert from 64 bit integer to 64 bit double */ +/* No overflow (CC1) can be generated */ +t_uint64 s_fltd(t_uint64 intv, uint32 *cc) { + t_uint64 ret = 0; /* zero return val */ + uint32 neg = 0; /* zero sign flag */ + uint32 CC = 0; /* n0 CC's yet */ + uint32 exp = 0; /* exponent */ + t_uint64 val = intv; /* integer value */ + + if (intv & DMSIGN) { + val = NEGATE32(intv); /* make src positive */ + neg = 1; /* set neg flag */ + } else { + if (intv == 0) { /* see if zero */ + ret = 0; /* return zero */ + CC = CC4BIT; /* CC4 for zero */ + /* return 0 for destination regs */ + *cc = CC; /* return CC's */ + return ret; /* return result */ + } + /* gt 0, fall through */ + } + + /* see if normalized */ + while ((val) && ((val & 0xf000000000000000ll) == 0)) { + val <<= 4; /* zero, shift in next nibble */ + exp--; /* decr exp value */ + } + if (val != 0) + exp += 0x50; /* default exponent */ + + /* shift value rt 8 bits and round */ + if (val & 0x91ll) { + if (neg) { + if (val & 0x7fl) + val = (val >> 8) + 1; /* round up */ + else + val = (val >> 8); /* no round up */ + } else { + if (val & 0x7fl) + val = (val >> 8); /* no round up */ + else + val = (val >> 8) + 1; /* round up */ + } + } else + val = (val >> 8); /* no round up */ + + if (val & 0x0100000000000000ll) { + val = (val >> 4); /* no round up */ + exp++; + } + ret = (((t_uint64)exp) << 56) | (val & 0x00ffffffffffffffll); /* merge value */ + + if (neg) + ret = NEGATE32(ret); + if (ret & DMSIGN) + CC |= CC3BIT; /* CC3 for neg */ + else if (ret == 0) + CC |= CC4BIT; /* CC4 for zero */ + else + CC |= CC2BIT; /* CC2 for greater than zero */ + + /* return temp for destination regs */ + *cc = CC; /* return CC's */ + return ret; /* return result */ +} + +#define CMASK 0x10000000 /* carry mask */ +#define EMASK 0x7f000000 /* single exponent mask */ +#define UMASK 0x0ffffff0 /* single fp mask */ +#define XMASK 0x0fffffff /* single fp mask */ +#define MMASK 0x00ffffff /* single mantissa mask */ +#define NMASK 0x0f000000 /* single nibble mask */ +#define ZMASK 0x00f00000 /* single nibble mask */ + +/* this new version is perfect against the diags, so good */ +/* do new SEL floating add derived from IBM370 code */ +/* Add/Sub single floating point */ +uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc) +{ + uint32 res, ret; + char sign = 0; + int er, em, temp; + uint32 CC; + + /* first we want to make sure the numbers are normalized */ + ret = s_normfw(reg, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + reg = ret; /* use normalized value */ + if (mem == 0) { /* test for add of zero */ + *cc = CC; /* save CC's */ + return ret; /* return normalized results */ + } + + ret = s_normfw(mem, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + mem = ret; /* use normalized value */ + if (reg == 0) { /* test for add to zero */ + *cc = CC; /* save CC's */ + return ret; /* return results results */ + } + + /* extract reg exponent and mantissa */ + if (reg & MSIGN) { /* reg negative */ + sign |= 2; /* set neg flag */ + reg = NEGATE32(reg); /* make negative positive */ + } + er = (reg & EMASK) >> 24; /* extract reg exponent */ + reg &= MMASK; /* extract reg mantissa */ + + /* extract mem exponent and mantissa */ + if (mem & MSIGN) { /* mem negative */ + sign |= 1; /* set neg flag */ + mem = NEGATE32(mem); /* make negative positive */ + } + em = (mem & EMASK) >> 24; /* extract mem exponent */ + mem &= MMASK; /* extract mem mantissa */ + + temp = er - em; /* get signed exp difference */ + mem = mem << 4; /* align mem for guard digit */ + reg = reg << 4; /* align reg for guard digit */ + + if (temp > 0) { /* reg exp > mem exp */ + if (temp > 8) { + mem = 0; /* if too much difference, make zero */ + } else { + /* Shift mem right if reg has larger exponent */ + while (temp-- != 0) { + mem >>= 4; /* adjust for exponent difference */ + em++; /* bump exponent */ + } + } + } else + if (temp < 0) { /* reg < mem exp */ + if (temp < -8) { + reg = 0; /* if too much difference, make zero */ + er = em; /* make exponents the same using mem exp */ + } else { + /* Shift reg right if mem has larger exponent */ + while (temp++ != 0) { + reg >>= 4; /* adjust for exponent difference */ + er++; /* bump exponent */ + } + } + } + + /* exponents should be equal now */ + /* add results */ + if (sign == 2 || sign == 1) { + /* different signs so do subtract */ + mem ^= XMASK; /* complement the value */ + mem++; /* increment the value */ + res = reg + mem; /* add the values */ + if (res & CMASK) { /* see if carry */ + res &= XMASK; /* clear off the carry bit */ + } else { + sign ^= 2; /* flip the sign */ + res ^= XMASK; /* and negate the value by comp */ + res++; /* incr */ + } + } else { + res = reg + mem; /* same sign, just add */ + if (sign == 3) + res += 7; /* round number */ + } + + /* If overflow, shift right 4 bits */ + if (res & CMASK) { /* see if overflow carry */ + res >>= 4; /* move mantissa down 4 bits */ + er++; /* and adjust exponent */ + if (er >= 128) { /* if exponent too large, overflow */ + CC = CC1BIT|CC4BIT; /* set arithmetic overflow */ + /* OVERFLOW */ + /* set CC2 & CC3 on exit */ + CC |= (sign & 2)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + if (CC & CC3BIT) /* NEG overflow? */ + res = 0x80000001; /* yes */ + else + res = 0x7FFFFFFF; /* no, pos */ + /* Store result */ + *cc = CC; /* save CC's */ + return res; + } + } + + CC = 0; /* no CC's yet */ + /* Set condition codes */ + if (res != 0) /* see if non zero */ + CC |= (sign & 2) ? 1 : 2; + else { + er = sign = 0; /* we have zero CC4 */ + } + + /* normalize the fraction */ + if (CC != 0) { /* check for zero value */ + while ((res != 0) && ((res & NMASK) == 0)) { + res <<= 4; /* adjust mantisa by a nibble */ + er--; /* and adjust exponent smaller by 1 */ + } + /* Check if underflow */ + if (er < 0) { + /* UNDERFLOW */ + CC |= CC1BIT; /* set arithmetic exception */ + CC |= (sign & 2)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + res = 0; /* make all zero */ + /* Store result */ + *cc = CC; /* save CC's */ + return res; /* return value */ + } + } else { + /* result is zero */ + sign = er = 0; /* make abs zero */ + } + + res >>= 4; /* remove the guard nibble */ + + /* create result */ + res |= (er << 24) & EXMASK; /* combine exponent & mantissa */ + + /* set the CC's */ + if (CC == 0) { + CC = CC4BIT; /* zero value */ + } else { + if (sign & 2) + res = NEGATE32(res); /* make negative */ + CC = (CC & 3) << 28; /* neg is CC3, pos is CC2 */ + } + + *cc = CC; /* save CC's */ + return res; /* return result */ +} + +/* subtract memory floating point number from register floating point number */ +uint32 s_sufw(uint32 reg, uint32 mem, uint32 *cc) { + return s_adfw(reg, NEGATE32(mem), cc); +} + +/* multiply register floating point number by memory floating point number */ +/* set CC1 if overflow/underflow */ +/* use revised normalization code */ +uint32 s_mpfw(uint32 reg, uint32 mem, uint32 *cc) { + uint32 res, ret; + int sign = 0; + int lsb = 0; + int er, em, temp; + uint32 CC; + + /* first we want to make sure the numbers are normalized */ + ret = s_normfw(reg, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + reg = ret; /* use normalized value */ + + ret = s_normfw(mem, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + mem = ret; /* use normalized value */ + + /* see if multiply by zero */ + if ((reg == 0) || (mem == 0)) { /* test for mult by zero */ + *cc = CC4BIT; /* set CC 4 for 0 */ + return 0; /* return results */ + } + + /* extract reg exponent and mantissa */ + if (reg & MSIGN) { /* reg negative */ + sign ^= 1; /* set neg flag */ + reg = NEGATE32(reg); /* make negative positive */ + } + if (reg & 0x1) /* test lsb */ + lsb = 1; /* reg is odd */ + er = (reg & EXMASK) >> 24; /* extract reg exponent */ + reg &= MMASK; /* extract reg mantissa */ + + /* extract mem exponent and mantissa */ + if (mem & MSIGN) { /* mem negative */ + sign ^= 1; /* set neg flag */ + mem = NEGATE32(mem); /* make negative positive */ + } + if (mem & 0x1) /* test lsb */ + lsb = 1; /* reg is odd */ + em = (mem & EXMASK) >> 24; /* extract mem exponent */ + mem &= MMASK; /* extract mem mantissa */ + + er = er + em - 0x40; /* get the exp value */ + reg = reg << 4; /* create guard digit */ + mem = mem << 4; /* create guard digit */ + + res = 0; /* zero result for multiply */ + /* Do multiply with guard bit */ + for (temp = 0; temp < 28; temp++) { + /* Add if we need too */ + if (reg & 1) + res += mem; + /* Shift right by one */ + reg >>= 1; + res >>= 1; + } + + /* fix up some boundry rounding */ + if ((res >= 0x01000000) && (sign == 0)) { + res += 0x8; + } + if ((res == 0x00FFFFFF) && (sign == 1) && (er != 1)) { + if (lsb == 1) { + if ((er != 0x41) && (er != 0x81)) { + res += 0x1; + } + } + } + + /* If overflow, shift right 4 bits */ + if (res & 0x70000000) { /* see if overflow carry */ + res >>= 4; /* move mantissa down 4 bits */ + er++; /* and adjust exponent */ + if (er >= 128) { /* if exponent is too large, overflow */ + /* OVERFLOW */ + CC = CC1BIT; /* set arithmetic exception */ + CC |= (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + if (CC & CC3BIT) /* NEG overflow? */ + res = 0x80000001; /* double yes */ + else + res = 0x7FFFFFFF; /* no, pos */ + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + } + + /* Align the results & normalize */ + if (res != 0) { + while ((res != 0) && (res & NMASK) == 0) { + res <<= 4; + er--; + } + /* Check if overflow */ + if (er >= 128) { /* if exponent is too large, overflow */ + /* OVERFLOW */ + CC = CC1BIT|CC4BIT; /* set arithmetic exception */ + if (sign & 1) { + CC |= CC3BIT; + res = 0x80000001; /* neg overflow 1011 */ + } else { + CC |= CC2BIT; + res = 0x7FFFFFFF; /* pos overflow 1101 */ + } + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + /* Check if underflow */ + if (er < 0) { + /* UNDERFLOW */ + res = 0; /* make return value zero */ + CC = (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + CC |= CC1BIT; /* set arithmetic exception */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + res >>= 4; /* remove guard nibble */ + } else + er = sign = 0; + + res &= MMASK; /* clear exponent */ + + res |= ((((uint32)er) << 24) & EXMASK); /* merge exp and mantissa */ + + if (sign == 1) /* is result to be negative */ + res = NEGATE32(res); /* make value negative */ + + CC = 0; + if (res != 0) /* see if non zero */ + CC = (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + else + CC = CC4BIT; /* set zero cc */ + + /* return results */ + *cc = CC; /* save CC's */ + return res; /* return results */ +} + +/* divide register float by memory float */ +uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc) { + uint32 CC = 0, temp, temp2, sign; + uint32 expm, expr; + t_uint64 dtemp; + + /* process operator */ + sign = mem & MSIGN; /* save original value for sign */ + if (mem == 0) /* check for divide by zero */ + goto DOVFLO; /* go process divide overflow */ + + if (mem & MSIGN) /* check for negative */ + mem = NEGATE32(mem); /* make mem positive */ + + expm = (mem >> 24); /* get operand exponent */ + mem <<= 8; /* move fraction to upper 3 bytes */ + mem >>= 1; /* adjust fraction for divide */ + + /* process operand */ + if (reg == 0) { + temp = 0; /* return zero */ + goto setcc; /* go set CC's */ + } + if (reg & MSIGN) { /* check for negative */ + reg = NEGATE32(reg); /* make reg positive */ + sign ^= MSIGN; /* complement sign */ + } + expr = (reg >> 24); /* get operator exponent */ + reg <<= 8; /* move fraction to upper 3 bytes */ + reg >>= 6; /* adjust fraction for divide */ + + temp = expr - expm; /* subtract exponents */ + dtemp = ((t_uint64)reg) << 32; /* put reg fraction in upper 32 bits */ + temp2 = (uint32)(dtemp / mem); /* divide reg fraction by mem fraction */ + temp2 >>= 3; /* shift out excess bits */ + temp2 <<= 3; /* replace with zero bits */ + + if (sign & MSIGN) + temp2 = NEGATE32(temp2); /* if negative, negate fraction */ + /* normalize the result in temp and put exponent into expr */ + temp2 = s_nor(temp2, &expr); /* normalize fraction */ + temp += 1; /* adjust exponent */ + +//RROUND: + if (temp2 == MSIGN) { /* check for minus zero */ + temp2 = 0xF8000000; /* yes, fixup value */ + expr++; /* bump exponent */ + } + + if ((int32)temp2 >= 0x7fffffc0) /* check for special rounding */ + goto RRND2; /* no special handling */ + + if (expr != 0x40) { /* result normalized? */ + goto RRND2; /* if not, don't round */ + } + /* result normalized */ + if ((sign & MSIGN) == 0) + goto RRND1; /* if sign set, don't round yet */ + expr += temp; /* add exponent */ + + if (expr & MSIGN) /* test for underflow */ + goto DUNFLO; /* go process underflow */ + + if ((int32)expr > 0x7f) /* test for overflow */ + goto DOVFLO; /* go process overflow */ + + expr ^= FMASK; /* complement exponent */ + temp2 += 0x40; /* round at bit 25 */ + goto RRND3; /* go merge code */ + +RRND1: + temp2 += 0x40; /* round at bit 25 */ +RRND2: + expr += temp; /* add exponent */ + + if (expr & MSIGN) /* test for underflow */ + goto DUNFLO; /* go process underflow */ + + if ((int32)expr > 0x7f) /* test for overflow */ + goto DOVFLO; /* go process overflow */ + + if (sign & MSIGN) /* test for negative */ + expr ^= FMASK; /* yes, complement exponent */ +RRND3: + temp2 <<= 1; /* adjust fraction */ + temp = (expr << 24) | (temp2 >> 8); /* merge exp & fraction */ + goto setcc; /* go set CC's */ + +DOVFLO: + CC |= CC4BIT; /* set CC4 for exponent overflow */ +DUNFLO: + CC |= CC1BIT; /* set CC1 for arithmetic exception */ + if (sign & MSIGN) /* test for negative */ + CC |= CC3BIT; /* set neg fraction bit CC3 */ + else + CC |= CC2BIT; /* set pos fraction bit CC2 */ + *cc = CC; /* return CC's */ + /* return value is not valid, but return fixup value anyway */ + switch ((CC >> 27) & 3) { /* rt justify CC3 & CC4 */ + case 0: + return 0; /* pos underflow */ + break; + case 1: + return 0x7fffffff; /* positive overflow */ + break; + case 2: + return 0; /* neg underflow */ + break; + case 3: + return 0x80000001; /* negative overflow */ + break; + } +setcc: + /* come here to set cc's and return */ + /* temp has return value */ + if (temp & MSIGN) + CC |= CC3BIT; /* CC3 for neg */ + else + if (temp == 0) + CC |= CC4BIT; /* CC4 for zero */ + else + CC |= CC2BIT; /* CC2 for greater than zero */ + /* return temp to destination reg */ + *cc = CC; /* return CC's */ + return temp; /* return result */ +} + +#define DMMASK 0x00ffffffffffffffLL /* double mantissa mask */ +#define DCMASK 0x1000000000000000LL /* double carry mask */ +#define DIBMASK 0x0fffffffffffffffLL /* double fp nibble mask */ +#define DUMASK 0x0ffffffffffffff0LL /* double fp mask */ +#define DNMASK 0x0f00000000000000LL /* double nibble mask */ +#define DZMASK 0x00f0000000000000LL /* shifted nibble mask */ + +/* add memory floating point number to register floating point number */ +/* this code creates an extra guard digit, so it is more accurate than SEL */ +/* The code was modified to have the same results as SEL, so we will use this one */ +/* set CC1 if overflow/underflow */ +t_uint64 s_adfd(t_uint64 reg, t_uint64 mem, uint32 *cc) +{ + t_uint64 res, ret; + uint8 sign = 0; + int er, em, temp; + uint32 CC; + + /* first we want to make sure the numbers are normalized */ + ret = s_normfd(reg, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + reg = ret; /* use normalized value */ + if (mem == 0) { /* test for add of zero */ + *cc = CC; /* save CC's */ + return ret; /* return normalized results */ + } + + ret = s_normfd(mem, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + mem = ret; /* use normalized value */ + if (reg == 0) { /* test for add to zero */ + *cc = CC; /* save CC's */ + return ret; /* return results results */ + } + + /* process the memory operand value */ + /* extract exponent and mantissa */ + if (reg & DMSIGN) { /* reg negative */ + sign |= 2; /* set neg flag */ + reg = NEGATE32(reg); /* make negative positive */ + } + er = (reg & DEXMASK) >> 56; /* extract reg exponent */ + reg &= DMMASK; /* extract reg mantissa */ + + /* extract mem exponent and mantissa */ + if (mem & DMSIGN) { /* mem negative */ + sign |= 1; /* set neg flag */ + mem = NEGATE32(mem); /* make negative positive */ + } + em = (mem & DEXMASK) >> 56; /* extract mem exponent */ + mem &= DMMASK; /* extract mem mantissa */ + + mem = mem << 4; /* align mem for normalization */ + reg = reg << 4; /* align reg for normalization */ + temp = er - em; /* get signed exp difference */ + + if (temp > 0) { /* reg exp > mem exp */ + if (temp > 15) { + mem = 0; /* if too much difference, make zero */ + } else { + /* Shift mem right if reg has larger exponent */ + mem >>= (4 * temp); /* adjust for exponent difference */ + } + } else + if (temp < 0) { /* reg < mem exp */ + if (temp < -15) { + reg = 0; /* if too much difference, make zero */ + } else + /* Shift reg right if mem larger */ + reg >>= (4 * (-temp)); /* adjust for exponent difference */ + er = em; /* make exponents the same */ + } + + /* er now has equal exponent for both values */ + /* add results */ + if (sign == 2 || sign == 1) { + /* different signs so do subtract */ + mem ^= DIBMASK; /* complement the value and inc */ + mem++; /* negate all but upper nibble */ + res = reg + mem; /* add the values */ + if (res & DCMASK) { /* see if carry */ + res &= DIBMASK; /* clear off the carry bit */ + } else { + sign ^= 2; /* flip the sign */ + res ^= DIBMASK; /* and negate the value */ + res++; /* negate all but the upper nibble */ + } + } else { + res = reg + mem; /* same sign, just add */ + if ((res & 0x0fffffffffffff80ll) != 0x0fffffffffffff80ll) { + if (sign == 3) + res += 7; /* round number */ + if ((sign == 3) && (er == 0x7e)) + res |= 0x0f00ll; /* round number more */ + if (sign == 0) + res += 0xf; /* round number */ + } + } + /* following statement effectively removes guard nibble to be like SEL */ + res &= 0xfffffffffffffff0ll; /* remove extra bits */ + + /* If overflow, shift right 4 bits */ + if (res & DCMASK) { /* see if overflow carry */ + res >>= 4; /* move mantissa down 4 bits */ + er++; /* and adjust exponent */ + if (er >= 128) { /* if exponent is too large, overflow */ + /* OVERFLOW */ + CC = CC1BIT|CC4BIT; /* set arithmetic overflow */ + /* set CC2 & CC3 on exit */ + CC |= (sign & 2)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + if (CC & CC3BIT) /* NEG overflow? */ + res = 0x8000000000000001; /* double yes */ + else + res = 0x7FFFFFFFFFFFFFFF; /* no, pos */ + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + } + + CC = 0; + /* Set condition codes */ + if (res != 0) /* see if non zero */ + CC |= (sign & 2) ? 1 : 2; + else { + er = sign = 0; /* we have zero CC4 */ + } + + /* normalize the fraction */ + if (res != 0) { /* see if non zero */ + while ((res != 0) && (res & DNMASK) == 0) { + res <<= 4; /* adjust mantisa by a nibble */ + er--; /* and adjust exponent smaller by 1 */ + } + /* Check if exponent underflow */ + if (er < 0) { + /* UNDERFLOW */ + CC |= CC1BIT; /* set arithmetic exception */ + CC |= (sign & 2)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + res = 0; /* make all zero */ + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + } else { + /* result is zero */ + sign = er = 0; /* make abs zero */ + } + + res >>= 4; /* remove the carryout nibble */ + res &= DMMASK; /* clear exponent */ + + res |= ((((t_uint64)er) << 56) & DEXMASK); /* merge exp and mantissa */ + + /* Set condition codes */ + if (CC == 0) { + CC = CC4BIT; /* set zero cc */ + } else { + if (sign & 2) /* see if negative */ + res = NEGATE32(res); /* make negative */ + CC = (CC & 3) << 28; /* neg is CC3, pos is CC2 */ + } + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ +} + +/* subtract memory floating point number from register floating point number */ +t_uint64 s_sufd(t_uint64 reg, t_uint64 mem, uint32 *cc) { + return s_adfd(reg, NEGATE32(mem), cc); +} + +/* multiply register floating point number by memory floating point number */ +/* set CC1 if overflow/underflow */ +/* use revised normalization code */ +t_uint64 s_mpfd(t_uint64 reg, t_uint64 mem, uint32 *cc) { + t_uint64 res, ret; + int sign = 0; + int lsb = 0; + int er, em, temp; + uint32 CC; + + /* first we want to make sure the numbers are normalized */ + ret = s_normfd(reg, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + reg = ret; /* use normalized value */ + + ret = s_normfd(mem, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + mem = ret; /* use normalized value */ + + /* see if multiply by zero */ + if ((reg == 0ll) || (mem == 0ll)) { /* test for mult by zero */ + *cc = CC4BIT; /* set CC 4 for 0 */ + return 0ll; /* return results results */ + } + + /* extract reg exponent and mantissa */ + if (reg & DMSIGN) { /* reg negative */ + sign ^= 1; /* set neg flag */ + reg = NEGATE32(reg); /* make negative positive */ + } + if (reg & 0x1ll) /* test lsb */ + lsb = 1; /* reg is odd */ + er = (reg & DEXMASK) >> 56; /* extract reg exponent */ + reg &= DMMASK; /* extract reg mantissa */ + + /* extract mem exponent and mantissa */ + if (mem & DMSIGN) { /* mem negative */ + sign ^= 1; /* set neg flag */ + mem = NEGATE32(mem); /* make negative positive */ + } + if (mem & 0x1ll) /* test lsb */ + lsb = 1; /* reg is odd */ + em = (mem & DEXMASK) >> 56; /* extract mem exponent */ + mem &= DMMASK; /* extract mem mantissa */ + + er = er + em - 0x40; /* get the exp value */ + + res = 0; /* zero result for multiply */ + /* multiply by doing shifts and adds */ + for (temp = 0; temp < 56; temp++) { + /* Add if we need too */ + if (reg & 1) + res += mem; + /* Shift right by one */ + reg >>= 1; + res >>= 1; + } + er++; /* adjust exp for extra nible shift */ + + /* fix up some boundry conditions */ + if ((res >= 0x0010000000000000ll) && (sign == 1)) { + res += 0x1; + } + else + if ((res == 0x000FFFFFFFFFFFFFll) && (sign == 1) && (er != 1)) { + if (lsb == 0) { + if ((er == 0x41) || (er == 0x81)) { + er++; + } + } else { + res += 0x1ll; + } + } + + /* If overflow, shift right 4 bits */ + if (res & DEXMASK) { /* see if overflow carry */ + res >>= 4; /* move mantissa down 4 bits */ + er++; /* and adjust exponent */ + if (er >= 0x80) { /* if exponent is too large, overflow */ + /* OVERFLOW */ + CC = CC1BIT; /* set arithmetic exception */ + CC |= (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + if (CC & CC3BIT) /* NEG overflow? */ + res = 0x8000000000000001ll; /* double yes */ + else + res = 0x7FFFFFFFFFFFFFFFll; /* no, pos */ + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + } + + /* Align the results */ + if (res != 0) { + while ((res != 0) && (res & DNMASK) == 0) { + res <<= 4; /* move over mantessa */ + er--; /* reduce exponent cocunt by 1 */ + if ((res == 0x00FFFFFFFFFFFFF0ll) && (sign == 1)) { + if (lsb == 0) { + er--; + } + else { + res += 0x10ll; + } + } + } + /* Check if overflow */ + if (er >= 128) { /* if exponent is too large, overflow */ + /* OVERFLOW */ + CC = CC1BIT|CC4BIT; /* set arithmetic exception */ + if (sign & 1) { + CC |= CC3BIT; /* neg CC */ + res = 0x8000000000000001ll; /* neg overflow 1011 */ + } else { + CC |= CC2BIT; /* pos CC */ + res = 0x7FFFFFFFFFFFFFFFll; /* pos overflow 1101 */ + } + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + /* Check if underflow */ + if (er < 0) { + /* UNDERFLOW */ + res = 0; /* make return value zero */ + CC = (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + CC |= CC1BIT; /* set arithmetic exception */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + res >>= 4; /* remove guard nibble */ + } else { + er = sign = 0; /* have real zero */ + } + + res &= DMMASK; /* clear exponent */ + + res |= ((((t_uint64)er) << 56) & DEXMASK); /* merge exp and mantissa */ + if (sign == 1) /* is result to be negative */ + res = NEGATE32(res); /* make value negative */ + + /* determine CC's for result */ + CC = 0; + if (res != 0) /* see if non zero */ + CC = (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + else + CC = CC4BIT; /* set zero cc */ + + /* return results */ + *cc = CC; /* save CC's */ + return res; /* return results */ +} + +/* divide register floating point number by memory floating point number */ +/* set CC1 if overflow/underflow */ +/* use revised normalization code */ +t_uint64 s_dvfd(t_uint64 reg, t_uint64 mem, uint32 *cc) { + t_uint64 res, ret; + int sign = 0; + int sign2 = 0; + int lsb = 0; + int er, em, temp; + uint32 CC; + + /* first we want to make sure the numbers are normalized */ + ret = s_normfd(reg, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + reg = ret; /* use normalized value */ + + ret = s_normfd(mem, &CC); /* get the reg value */ + if (CC & CC1BIT) { /* see if we have AE */ + *cc = CC; /* save CC's */ + return ret; /* return results */ + } + mem = ret; /* use normalized value */ + + /* see if divide by or into zero */ + if ((reg == 0ll) || (mem == 0ll)) { /* test for divide by zero */ + *cc = CC4BIT; /* set CC 4 for 0 */ + return 0ll; /* return results */ + } + + /* extract reg exponent and mantissa */ + if (reg & DMSIGN) { /* reg negative */ + sign ^= 1; /* set neg flag */ + reg = NEGATE32(reg); /* make negative positive */ + sign2 |= 2; /* set neg flag */ + } + if (reg & 0x1ll) /* test lsb */ + lsb = 1; /* reg is odd */ + er = (reg & DEXMASK) >> 56; /* extract reg exponent */ + reg &= DMMASK; /* extract reg mantissa */ + + /* extract mem exponent and mantissa */ + if (mem & DMSIGN) { /* mem negative */ + sign ^= 1; /* set neg flag */ + mem = NEGATE32(mem); /* make negative positive */ + sign2 |= 1; /* set neg flag */ + } + if (mem & 0x1ll) /* test lsb */ + lsb = 1; /* reg is odd */ + em = (mem & DEXMASK) >> 56; /* extract mem exponent */ + mem &= DMMASK; /* extract mem mantissa */ + + er = er - em + 0x40; /* get the exp value */ + + /* move left 1 nibble for divide */ + /* Shift numbers up 4 bits so as not to lose precision below */ + reg <<= 4; + mem <<= 4; + + /* see if we need to adjust divisor if larger that dividend */ + if (reg > mem) { + reg >>= 4; + er++; + } + + mem ^= DIBMASK; /* change sign of mem val to do add */ + mem++; /* comp & incr */ + + res = 0; /* zero result for multiply */ + /* do divide by using shift & add (subt) */ + for (temp = 56; temp > 0; temp--) { + t_uint64 tmp; + + /* Add if we need too */ + /* Shift left by one */ + reg <<= 1; + /* Subtract remainder to dividend */ + tmp = reg + mem; + + /* Shift quotent left one bit */ + res <<= 1; + + /* If remainder larger then divisor replace */ + if ((tmp & DCMASK) != 0) { + reg = tmp; + res |= 1; + } + } + + /* Compute one final set to see if rounding needed */ + /* Shift left by one */ + reg <<= 1; + /* Subtract remainder to dividend */ + reg += mem; + + /* If .5 off, round, but do not cause carry overflow */ + if (((reg & DMSIGN) != 0) && (res != 0x00FFFFFFFFFFFFFFll)){ + res++; + } + + /* fix up some boundry condtions to make diags happy */ + if (res == 0x00FFFFFFFFFFFFF1ll) { + res += 0x0fll; /* round up by nibble */ + } + else + if (res == 0x00FFFFFFFFFFFFF8ll) { + res &= 0x0FFFFFFFFFFFFFC0ll; /* remove some extra bits */ + } + else + if (res == 0x00FFFFFFFFFFFFFFll) { + if (lsb == 0) { + res += 0x1ll; /* round up by bit to force carry */ + } else { + if (sign) { + if (sign2 == 1) { + res &= 0x00FFFFFFFFFFFFF0ll; /* clear last nibble */ + } else { + res += 0x1ll; /* round up by bit to for carry */ + } + } else { + if (sign2 == 3) { + res += 0x1ll; /* round up by bit to for carry */ + } else { + res &= 0x00FFFFFFFFFFFFF0ll; /* clear last nibble */ + } + } + } + } + /* diags should be happy now */ + + /* If overflow, shift right 4 bits */ + if (res & DEXMASK) { /* see if overflow carry */ + res >>= 4; /* move mantissa down 4 bits */ + er++; /* and adjust exponent */ + if (er >= 128) { /* if exponent is too large, overflow */ + /* OVERFLOW */ + CC = CC1BIT|CC4BIT; /* set arithmetic exception */ + CC |= (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + if (CC & CC3BIT) /* NEG overflow? */ + res = 0x8000000000000001ll; /* double yes */ + else + res = 0x7FFFFFFFFFFFFFFFll; /* no, pos */ + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + } + + /* Align the results */ + if ((res) != 0) { + while ((res != 0) && (res & DZMASK) == 0) { + res <<= 4; + er--; + } + /* Check if overflow */ + if (er >= 128) { /* if exponent is too large, overflow */ + /* OVERFLOW */ + CC = CC1BIT|CC4BIT; /* set arithmetic exception */ + if (sign & 1) { + CC |= CC3BIT; + res = 0x8000000000000001ll; /* neg overflow 1011 */ + } else { + CC |= CC2BIT; + res = 0x7FFFFFFFFFFFFFFFll; /* pos overflow 1101 */ + } + /* store results */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + /* Check if underflow */ + if (er < 0) { + /* UNDERFLOW */ + res = 0; /* make return value zero */ + CC = (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + CC |= CC1BIT; /* set arithmetic exception */ + *cc = CC; /* save CC's */ + return res; /* return results */ + } + } else { + er = sign = 0; + } + + res &= DMMASK; /* clear exponent space */ + + res |= ((((t_uint64)er) << 56) & DEXMASK); /* merge exp and mantissa */ + if (sign & 1) /* is result to be negative */ + res = NEGATE32(res); /* make value negative */ + + /* determine CC's for result */ + CC = 0; + if (res != 0) /* see if non zero */ + CC = (sign & 1)?CC3BIT:CC2BIT; /* neg is CC3, pos is CC2 */ + else + CC = CC4BIT; /* set zero cc */ + + /* return results */ + *cc = CC; /* save CC's */ + return res; /* return results */ +} + diff --git a/SEL32/sel32_hsdp.c b/SEL32/sel32_hsdp.c new file mode 100644 index 00000000..be0f19c7 --- /dev/null +++ b/SEL32/sel32_hsdp.c @@ -0,0 +1,3790 @@ +/* sel32_hsdp.c: SEL-32 8064 High Speed Disk Processor + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell and other SIMH contributers + + 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 + JAMES C. BEVIER 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 "sel32_defs.h" + +/* uncomment to use fast sim_activate times when running UTX */ +/* UTX gets an ioi error for dm0801 if slow times are used */ +/* dm0801 is not even a valid unit number for UDP controller */ +#define FAST_FOR_UTX + +#if NUM_DEVS_HSDP > 0 + +#define UNIT_HSDP UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE + +/* useful conversions */ +/* Fill STAR value from cyl, trk, sec data */ +#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff)) +/* convert STAR value to number of sectors */ +#define STAR2SEC(star,spt,spc) ((star&0xff)+(((star>>8)&0xff)*spt)+(((star>>16)&0xffff)*spc)) +/* convert STAR value to number of heads or tracks */ +#define STAR2TRK(star,tpc) (((star>>16)&0xffff)*tpc+((star>>8)&0x0ff)) +/* convert STAR value to number of cylinders */ +#define STAR2CYL(star) ((star>>16)&RMASK) +/* convert byte value to number of sectors mod sector size */ +#define BYTES2SEC(bytes,ssize) (((bytes) + (ssize-1)) >> 10) +/* get sectors per track for specified type */ +#define SPT(type) (hsdp_type[type].spt) +/* get sectors per cylinder for specified type */ +#define SPC(type) (hsdp_type[type].spt*hsdp_type[type].nhds) +/* get number of tracks for specified type */ +#define TRK(type) (hsdp_type[type].cyl*hsdp_type[type].nhds) +/* get number of cylinders for specified type */ +#define CYL(type) (hsdp_type[type].cyl) +/* get number of heads for specified type */ +#define HDS(type) (hsdp_type[type].nhds) +/* get disk capacity in sectors for specified type */ +#define CAP(type) (CYL(type)*HDS(type)*SPT(type)) +/* get number of bytes per sector for specified type */ +#define SSB(type) (hsdp_type[type].ssiz*4) +/* get disk capacity in bytes for specified type */ +#define CAPB(type) (CAP(type)*SSB(type)) +/* get disk geometry as STAR value for specified type */ +#define GEOM(type) (CHS2STAR(CYL(type),HDS(type),SPT(type))) + +/* INCH command information */ +/* +WD 0 - Data address +WD 1 - Flags - 0 -36 byte count + +Data - 224 word INCH buffer address (SST) +WD 1 Drive 0 Attribute register +WD 2 Drive 1 Attribute register +WD 3 Drive 2 Attribute register +WD 4 Drive 3 Attribute register +WD 5 Drive 4 Attribute register +WD 6 Drive 5 Attribute register +WD 7 Drive 6 Attribute register +WD 8 Drive 7 Attribute register + +Drive attribute register bit assignments (DATR) +Byte 0 bits 0-7 - Flags + Drive type + bits 0&1 - 00=Undefined + - 01=MHD + - 10=Undefined + - 11=Undefined + Optimized seeks + bit 2&3 - 00=Optimize seeks and post IOCL status out of order + - 01=Optimize seeks and post IOCL status in order + - 10=Do not optimize seeks + - 11=Do not optimize seeks + bit 4 - 0=Drive is present + - 1=Drive not present + bit 5 - 0=Not Dual Port + - 1=Dual Port + Sector Size + bit 6&7 - 00=768 bytes + 01=1024 bytes + 10=2048 bytes + 11=Unassigned +Byte 1 bits 8-15 - Sectors per track +Byte 2 bits 16-23 - Number of head +Byte 3 bits 24-31 - Reserved (zero) +*/ + +/* +Drive status bit assignments (DSR) +Byte 0 bits 0-7 + bit 00 - Seek End + 01 - Unit selected + 02 - Sector pulse counter bit 0 + 03 - Sector pulse counter bit 1 + 04 - Sector pulse counter bit 2 + 05 - Sector pulse counter bit 3 + 06 - Sector pulse counter bit 4 + 07 - Sector pulse counter bit 5 +Byte 1 bits 7-15 + bit 08 - Disc drive fault + 09 - Seek error + 10 - On cylinder + 11 - Unit Ready + 12 - Write protected + 13 - Drive busy + 14 - Reserved (zero) + 15 - Reserved (zero) +*/ + +/* Subchannel Target Register (STAR) */ +/* byte 0 - Cylinder MS byte */ +/* byte 1 - Cylinder LS byte */ +/* byte 2 - Track count */ +/* byte 3 - Sector count */ + +/* Mode Register (MODE) */ +/* Bits 0-7 - bit assignments */ + +/* Bits 0-3 are for data recovery operations which can be */ +/* tried by the software */ +/* 0 - Servo offset 0/1=disable/enable */ +/* 1 - Servo offset polarity 0/1=positive/negative */ +/* 2 - Data strobe offset 0/1=disable/enable */ +/* 3 - Data strobe offset polarity 0/1=positive/negative */ +/* Bit 4 enables sector ECC data to be read or written for */ +/* diagnostic commands */ +/* 4 - Read/write ECC data 0/1=disable/enable */ +/* Bit 5 controls the transfer of an ID during express bus */ +/* read commands */ +/* 5 - Express bus ID 0/1=enable/disable */ +/* Bit 6 enables auto-retry in accordance with the firmware */ +/* auto-retry algorithms */ +/* 6 - Auto retry 0/1=enable/disable */ +/* Bit 7 disables the subchannel from interacting with the */ +/* disc drive and is for diagnostic testing only */ +/* 7 - Diagnostic mode 0/1=disable/enable */ + +/* Sense Buffer Register (SBR) */ +/* The SBR contains subchannel error status information */ +/* Byte 0 + * bit 00 Command rejected (CR) + * 01 Intervention requested (IR) + * 02 Unit select error (USEL) + * 03 Equipment check (EQCK) + * 04 Reserved (zero) + * 05 Reserved (zero) + * 06 Disc format error (DFER) + * 07 Defective track encountered (DETR) + * Byte 1 + * bit 08 Reserved (zero) + * 09 At alternate track (AATT) + * 10 Write protect error (WPER) + * 11 Write lock error (WRL) + * 12 Mode check (MOCK) + * 13 Invalid address (INAD) + * 14 Release fault (RELF) + * 15 Chaining error (CHER) + * Byte 2 + * bit 16 Revolution lost (REVL) + * 17 Disc addressing or seek error + * 18 Reserved (zero) + * 19 Reserved (zero) + * 20 ECC error in data (ECCD) + * 21 Reserved (zero) + * 22 Reserved (zero) + * 23 Uncorrectable ECC error (UECC) + * Byte 3 + * Not used + * */ + +/* 224 word Subchannel Storage Buffer (SST) */ +/* 128 words reserved */ +/* 66 words (33 DW) of program status queue (PSQ) */ +/* 8 words of retry counters (1/channel) */ +/* 22 words reserved */ + +/************************************/ +/* track label definations 34 bytes */ + /* for track 0, write max cyl/head/sec values in 0-3 */ + /* otherwise write current values */ +/* +0 short lcyl; cylinder +2 char ltkn; head or track number +3 char lid; track label id (0xff means last track) +4 char lflg1; track status flags + bit 0 good trk + 1 alternate trk + 2 spare trk + 3 reserved trk + 4 defective trk + 5 last track + 6-7 n/u = 0 +5 char lflg2; + bit 0 write lock + 1 write protected + 2-7 n/u = 0 +6 short lspar1; n/u = 0 +8 short lspar2; n/u = 0 +10 short ldef1; defect #1 sec and byte position + * for track 0 write DMAP + * write sector number of cyl-4, hds-2, sec 0 value in 12-15 + * otherwise write current values +12 short ldef2; defect #2 sec and byte position +14 short ldef3; defect #3 sec and byte position + * for track 0 write UMAP which is DMAP - 2 * SPT + * write sector number of cyl-4, hds-4, sec 0 value in 16-19 + * otherwise write current values +16 short ladef1; defect #1 abs position +18 short ladef2; defect #2 abs position +20 short ladef3; defect #3 abs position +22 short laltcyl; alternate cylinder number or return cyl num +24 char lalttk; alrernate track number or return track num +25 char ldscnt; data sector count 16/20 +26 char ldatrflg; device attributes + bit 0 n/u + 1 disk is mhd + 2 n/u + 3 n/u + 4 n/u + 5 dual ported + 6/7 00 768 bytes/blk + 01 1024 bytes/blk + 10 2048 bytes/blk +27 char ldatrscnt; sectors per track (again) +28 char ldatrmhdc; MHD head count +29 char ldatrfhdc; FHD head count +30 uint32 lcrc; Label CRC-32 value + */ + +/*************************************/ +/* sector label definations 34 bytes */ +/* +0 short lcyl; cylinder number +2 char lhd; head number +3 char lsec; sec # 0-15 or 0-19 for 16/20 format +4 char lflg1; track/sector status flags + bit 0 good sec + 1 alternate sec + 2 spare sec + 3 reserved sec + 4 defective sec + 5 last sec + 6-7 n/u = 0 +5 char lflg2; + bit 0 write lock + 1 write protected + 2-7 n/u = 0 +6 short lspar1; n/u = 0 +8 short lspar2; n/u = 0 +10 short ldef1; defect #1 sec and byte position +12 short ldef2; defect #2 sec and byte position +14 short ldef3; defect #3 sec and byte position + * for track 0 write UMAP which is DMAP - 2 * SPT + * write sector number of cyl-4, hds-4, sec 0 value in 16-19 + * otherwise write zeros +16 short lspar3; n/u = 0 +18 short lspar4; n/u = 0 +20 short lspar5; n/u = 0 +22 short laltcyl; alternate cylinder number or return cyl num +24 char lalttk; alrernate track number or return track num +25 char ldscnt; data sector count 16/20 +26 char ldatrflg; device attributes + bit 0 n/u + 1 disk is mhd + 2 n/u + 3 n/u + 4 n/u + 5 dual ported + 6/7 00 768 bytes/blk + 01 1024 bytes/blk + 10 2048 bytes/blk +27 char ldatrscnt; sectors per track (again) +28 char ldatrmhdc; MHD head count +29 char ldatrfhdc; FHD head count +30 uint32 lcrc; Label CRC-32 value + */ + +/* track label / sector label definations */ +/* + 0 short lcyl; cylinder + 2 char ltkn; track + 3 char lid; sector id + 4 char lflg1; track/sector status flags + bit 0 good + 1 alternate + 2 spare + 3 reserved + 4 flaw + 5 last track + 6 start of alternate + 5 char lflg2; + 6 short lspar1; + 8 short lspar2; +10 short ldef1; +12 int ldeallp; DMAP block number trk0 +16 int lumapp; UMAP block number sec1 +20 short ladef3; +22 short laltcyl; +24 char lalttk; sectors per track +25 char ldscnt; number of heads +26 char ldatrflg; device attributes + bit 0 n/u + 1 disk is mhd + 2 n/u + 3 n/u + 4 n/u + 5 dual ported + 6/7 00 768 bytes/blk + 01 1024 bytes/blk + 10 2048 bytes/blk +27 char ldatrscnt; sectors per track (again) +28 char ldatrmhdc; MHD head count +29 char ldatrfhdc; FHD head count + */ + +#define CMD u3 +/* u3 */ +/* in u3 is device command code and status */ +#define DSK_CMDMSK 0x00ff /* Command being run */ +#define DSK_STAR 0x0100 /* STAR value in u4 */ +#define DSK_WAITING 0x0200 /* Doing NOP wait */ +#define DSK_READDONE 0x0400 /* Read finished, end channel */ +#define DSK_ENDDSK 0x0800 /* Sensed end of disk */ +#define DSK_SEEKING 0x1000 /* Disk is currently seeking */ +#define DSK_READING 0x2000 /* Disk is reading data */ +#define DSK_WRITING 0x4000 /* Disk is writing data */ +#define DSK_BUSY 0x8000 /* Disk is busy */ +/* commands */ +#define DSK_INCH 0x00 /* Initialize channel */ +#define DSK_INCH2 0xF0 /* Fake while in srv Initialize channel */ +#define DSK_WD 0x01 /* Write data */ +#define DSK_RD 0x02 /* Read data */ +#define DSK_NOP 0x03 /* No operation */ +#define DSK_SNS 0x04 /* Sense */ +#define DSK_SKC 0x07 /* Seek cylinder, track, sector */ +#define DSK_TIC 0x08 /* Transfer in channel */ +#define DSK_FMT 0x0B /* Format track */ +#define DSK_RE 0x12 /* Read express bus with ECC */ +//#define DSK_LPL 0x13 /* Lock protected label */ +#define DSK_LMR 0x1F /* Load mode register */ +#define DSK_RENO 0x22 /* Read express bus with no ECC */ +#define DSK_RES 0x23 /* Reserve */ +#define DSK_WSL 0x31 /* Write sector label */ +#define DSK_RSL 0x32 /* Read sector label */ +#define DSK_REL 0x33 /* Release */ +#define DSK_XEZ 0x37 /* Rezero */ +#define DSK_WTF 0x41 /* Write track format */ +#define DSK_RVL 0x42 /* Read vendor label */ +#define DSK_POR 0x43 /* Priority Override */ +#define DSK_IHA 0x47 /* Increment head address */ +//#define DSK_SRM 0x4F /* Set reserve track mode */ +#define DSK_WTL 0x51 /* Write track label */ +#define DSK_RTL 0x52 /* Read track label */ +//#define DSK_XRM 0x5F /* Reset reserve track mode */ +#define DSK_RAP 0xA2 /* Read angular position */ +//#define DSK_TESS 0xAB /* Test STAR (subchannel target address register) */ +#define DSK_REC 0xB2 /* Read ECC correction mask */ +#define DSK_INC 0xFF /* Initialize Controller */ + +#define DAI u4 +/* u4 holds the current disk attribute value from the INCH command */ +/* for the current drive. */ +/* Holds the current cylinder, head(track), sector */ + +/* this attribute information is provided by the INCH command */ +/* for each device and is saved. It is reconstructed from */ +/* the hsdp_t structure data for the assigned disk */ +/* +bits 0-7 - Flags + bits 0&1 - 00=Reserved, 01=MHD, 10=FHD, 11=MHD with FHD option + bit 2 - 1=Cartridge module drive + bit 3 - 0=Reserved + bit 4 - 1=Drive not present + bit 5 - 1=Dual Port + bit 6 - 0=Reserved 00 768 byte sec + bit 7 - 0=Reserved 01 1024 byte sec +bits 8-15 - sector count (sectors per track)(F16=16, F20=20) +bits 16-23 - MHD Head count (number of heads on MHD) +bits 24-31 - FHD head count (number of heads on FHD or + number head on FHD option of mini-module) +*/ + +#define SNS u5 +/* u5 */ +/* Sense byte 0 - mode register */ +#define SNS_DROFF 0x80000000 /* Drive Carriage will be offset */ +#define SNS_TRKOFF 0x40000000 /* Track offset: 0=positive, 1=negative */ +#define SNS_RDTMOFF 0x20000000 /* Read timing offset = 1 */ +#define SNS_RDSTRBT 0x10000000 /* Read strobe timing: 1=positive, 0=negative */ +#define SNS_DIAGMOD 0x08000000 /* Diagnostic Mode ECC read/write 0/1=disab;e/enable */ +#define SNS_XPBUS 0x04000000 /* Express Bus ID 0/1=enable/disable */ +#define SNS_AUTORT 0x02000000 /* Auto retry 0/1=disable/enable */ +#define SNS_DIAG 0x01000000 /* Diagnostic mode 0/1=disable/enable */ + +/* Sense byte 1 */ +#define SNS_CMDREJ 0x800000 /* Command reject */ +#define SNS_INTVENT 0x400000 /* Unit intervention required */ +#define SNS_USELE 0x200000 /* Unit Select Error */ +#define SNS_EQUCHK 0x100000 /* Equipment check */ +#define SNS_RES2 0x080000 /* Reserved */ +#define SNS_RES3 0x040000 /* Reserved */ +#define SNS_DSKFERR 0x020000 /* Disk format error */ +#define SNS_DEFTRK 0x010000 /* Defective track encountered */ + +/* Sense byte 2 */ +#define SNS_RES4 0x8000 /* Reserved */ +#define SNS_AATT 0x4000 /* At Alternate track */ +#define SNS_WPER 0x2000 /* Write protection error */ +#define SNS_WRL 0x1000 /* Write lock error */ +#define SNS_MOCK 0x0800 /* Mode check */ +#define SNS_INAD 0x0400 /* Invalid memory address */ +#define SNS_RELF 0x0200 /* Release fault */ +#define SNS_CHER 0x0100 /* Chaining error */ + +/* Sense byte 3 */ +#define SNS_REVL 0x80 /* Revolution lost */ +#define SNS_DADE 0x40 /* Disc addressing or seek error */ +#define SNS_RES5 0x20 /* Reserved */ +#define SNS_RES6 0x10 /* Reserved */ +#define SNS_ECCD 0x08 /* ECC error in data */ +#define SNS_RES7 0x04 /* Reserved */ +#define SNS_RES8 0x02 /* Reserved */ +#define SNS_UESS 0x01 /* Uncorrectable ECC error */ + +#define SNS2 us9 +/* us9 */ +/* us9 holds bytes 4 & 5 of the status for the drive */ + +/* Sense byte 4 */ +#define SNS_SEND 0x8000 /* Seek End */ +#define SNS_USEL 0x4000 /* Unit Selected */ +#define SNS_SPC0 0x2000 /* Sector Pulse Count B0 */ +#define SNS_SPC1 0x1000 /* Sector Pulse Count B1 */ +#define SNS_SPC2 0x0800 /* Sector Pulse Count B2 */ +#define SNS_SPC3 0x0400 /* Sector Pulse Count B3 */ +#define SNS_SPC4 0x0200 /* Sector Pulse Count B4 */ +#define SNS_SPC5 0x0100 /* Sector Pulse Count B5 */ + +/* Sense byte 5 */ +#define SNS_FLT 0x80 /* Disk Drive fault */ +#define SNS_SKER 0x40 /* Seek error */ +#define SNS_ONC 0x20 /* On Cylinder */ +#define SNS_UNR 0x10 /* Unit Ready */ +#define SNS_WRP 0x08 /* Write Protected */ +#define SNS_BUSY 0x04 /* Drive is busy */ +#define SNS_NU1 0x02 /* Spare 1 */ +#define SNS_NU2 0x01 /* Spare 2 */ + +#define CHS u6 +/* u6 - sector target address register (STAR) */ +/* Holds the current cylinder, head(track), sector */ +#define DISK_CYL 0xFFFF0000 /* cylinder mask */ +#define DISK_TRACK 0x0000FF00 /* track mask */ +#define DISK_SECTOR 0x000000FF /* sector mask */ + +/* Not Used up7 */ + +#define LSC us10 +/* us10 */ +/* us10 byte 0 unused */ +/* us10 byte 1 holds logical sector count from track 0 byte 25 */ + +static uint8 obuf[1024], bbuf[1024]; +static uint32 decc[512] = {0}; + +/* disk definition structure */ +struct hsdp_t +{ + const char *name; /* Device ID Name */ + uint16 nhds; /* Number of heads */ + uint16 ssiz; /* sector size in words */ + uint16 spt; /* # sectors per track(head) */ + uint16 ucyl; /* Number of cylinders used */ + uint16 cyl; /* Number of cylinders on disk */ + uint8 type; /* Device type code */ + /* bit 1 mhd */ + /* bits 6/7 = 0 768 byte blk */ /* not used on UDP/DPII */ + /* = 1 1024 byte blk */ /* not used on UDP/DPII */ +} + +hsdp_type[] = +{ + /* Class F Disc Devices */ + /* For MPX */ + {"MH040", 5, 192, 20, 407, 411, 0x40}, /* 0 411 40M XXXX */ + {"MH080", 5, 192, 20, 819, 823, 0x40}, /* 1 823 80M 8138 */ + {"MH160", 10, 192, 20, 819, 823, 0x40}, /* 2 823 160M 8148 */ + {"MH300", 19, 192, 20, 819, 823, 0x40}, /* 3 823 300M 9346 */ + {"MH337", 10, 192, 45, 819, 823, 0x40}, /* 4 823 337M 8887 DP337 */ + {"MH600", 40, 192, 20, 839, 843, 0x40}, /* 5 843 600M 8155 */ + {"MH689", 16, 192, 54, 861, 865, 0x40}, /* 6 823 674M 8888 DP689 */ + /* For UTX */ + {"9342", 5, 256, 16, 819, 823, 0x41}, /* 7 823 80M 9342 MH080 */ + {"8148", 10, 256, 16, 819, 823, 0x41}, /* 8 823 160M 8146 MH160 */ + {"9346", 19, 256, 16, 819, 823, 0x41}, /* 9 823 300M 9344 MH300 */ + {"8858", 24, 256, 16, 707, 711, 0x41}, /* 10 711 340M 8858 DC340 */ + {"8887", 10, 256, 35, 819, 823, 0x41}, /* 11 823 337M 8887 DP337 */ + {"8155", 40, 256, 16, 839, 843, 0x41}, /* 12 843 600M 8155 MH600 */ + {"8888", 16, 256, 43, 861, 865, 0x41}, /* 13 823 674M 8888 DP689 */ + {NULL} +}; + +t_stat hsdp_preio(UNIT *uptr, uint16 chan) ; +t_stat hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ; +t_stat hsdp_haltio(UNIT *uptr); +t_stat hsdp_rsctl(UNIT *uptr); +t_stat hsdp_iocl(CHANP *chp, int32 tic_ok); +t_stat hsdp_srv(UNIT *); +t_stat hsdp_boot(int32 unitnum, DEVICE *); +void hsdp_ini(UNIT *, t_bool); +t_stat hsdp_reset(DEVICE *); +t_stat hsdp_attach(UNIT *, CONST char *); +t_stat hsdp_detach(UNIT *); +t_stat hsdp_set_type(UNIT * uptr, int32 val, CONST char *cptr, void *desc); +t_stat hsdp_get_type(FILE * st, UNIT * uptr, int32 v, CONST void *desc); +t_stat hsdp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *hsdp_description (DEVICE *dptr); +extern uint32 inbusy; +extern uint32 outbusy; +extern uint32 readfull(CHANP *chp, uint32 maddr, uint32 *word); +extern int irq_pend; /* go scan for pending int or I/O */ +extern UNIT itm_unit; +extern uint32 PSD[]; /* PSD */ +extern uint32 cont_chan(uint16 chsa); + +/* channel program information */ +CHANP dpa_chp[NUM_UNITS_HSDP] = {0}; +/* IOCL queue */ +IOCLQ dpa_ioclq[NUM_UNITS_HSDP] = {0}; + +#define TRK_CACHE 10 +/* track label queue */ +struct _trk_data +{ + int32 age; + uint32 track; + uint8 label[30]; +}; + +struct _trk_label +{ + struct _trk_data tkl[TRK_CACHE]; +}; + +static struct _trk_label tkl_label[NUM_UNITS_HSDP] = {0}; + +MTAB hsdp_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "TYPE", "TYPE", + &hsdp_set_type, &hsdp_get_type, NULL, "Type of disk"}, + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, + &show_dev_addr, NULL, "Device channel address"}, + {0}, +}; + +UNIT dpa_unit[] = { +/* SET_TYPE(10) 8887 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x800)}, /* 0 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x802)}, /* 1 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x804)}, /* 2 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x806)}, /* 3 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x808)}, /* 4 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x80A)}, /* 5 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x80C)}, /* 6 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x80E)}, /* 7 */ +}; + +DIB dpa_dib = { + hsdp_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + hsdp_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + hsdp_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + hsdp_haltio, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + hsdp_rsctl, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + NULL, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + hsdp_iocl, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + hsdp_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + dpa_unit, /* UNIT* units */ /* Pointer to units structure */ + dpa_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + dpa_ioclq, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_HSDP, /* uint8 numunits */ /* number of units defined */ + 0x0F, /* uint8 mask */ /* 8 devices - device mask */ + 0x0800, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE dpa_dev = { + "DPA", dpa_unit, NULL, hsdp_mod, + NUM_UNITS_HSDP, 16, 24, 4, 16, 32, + NULL, NULL, &hsdp_reset, &hsdp_boot, &hsdp_attach, &hsdp_detach, + /* ctxt is the DIB pointer */ + &dpa_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &hsdp_help, NULL, NULL, &hsdp_description +}; + +#if NUM_DEVS_HSDP > 1 +/* channel program information */ +CHANP dpb_chp[NUM_UNITS_HSDP] = {0}; +/* IOCL queue */ +IOCPQ dpb_ioclq[NUM_UNITS_HSDP] = {0}; + +UNIT dpb_unit[] = { +/* SET_TYPE(3) DM300 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC00)}, /* 0 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC02)}, /* 1 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC04)}, /* 2 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC06)}, /* 3 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC08)}, /* 4 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0A)}, /* 5 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0C)}, /* 6 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0E)}, /* 7 */ +}; + + +DIB dpb_dib = { + hsdp_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + hsdp_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + hsdp_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + hsdp_haltio, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + hsdp_rsctl, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + NULL, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + hsdp_iocl, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + hsdp_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + dpb_unit, /* UNIT* units */ /* Pointer to units structure */ + dpb_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + dpb_ioclq, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_HSDP, /* uint8 numunits */ /* number of units defined */ + 0x0F, /* uint8 mask */ /* 8 devices - device mask */ + 0x0C00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE dpb_dev = { + "DPB", dpb_unit, NULL, hsdp_mod, + NUM_UNITS_HSDP, 16, 24, 4, 16, 32, + NULL, NULL, &hsdp_reset, &hsdp_boot, &hsdp_attach, &hsdp_detach, + /* ctxt is the DIB pointer */ + &dpb_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &hsdp_help, NULL, NULL, &hsdp_description +}; +#endif + +uint32 dple_ecc32(uint8 *str, int32 len) +{ + int i, j; + uint32 ch, ecc = 0; + uint32 pmask = 0x7e11f439; /* SEL LE poly mask */ + + ecc = (~ecc & MASK32); /* initialize ecc to all bits (~0) */ + for (j=0; j>= 1; /* just shift out the bit */ + ecc ^= pmask; /* eor with poly mask */ + } else + ecc >>= 1; /* just shift out the bit */ + ch >>= 1; /* next bit */ + } + } + return (~ecc & MASK32); /* return ecc value */ +} + +uint32 dpbe_ecc32(uint8 *str, int32 len) +{ + int i, j; + uint32 ch, ecc = 0; + uint32 pmask = 0x9C2F887E; /* SEL BE poly mask */ + + ecc = (~ecc & MASK32); /* initialize ecc to all bits (~0) */ + for (j=0; jflags); + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); /* get the UNIT number */ + int len, i, cn, found = -1; + + /* zero the Track Label Buffer */ + for (i = 0; i < 30; i++) + buf[i] = 0; + + /* get file offset in sectors */ + tstart = STAR2SEC(star, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + nstar = hsdpsec2star(tstart, type); + + cyl = (nstar >> 16) & 0xffff; /* get the cylinder */ + trk = (nstar >> 8) & 0xff; /* get the track */ + sec = nstar & 0xff; /* save sec if any */ + + /* get track number */ + tstart = (cyl * HDS(type)) + trk; + sim_debug(DEBUG_EXP, dptr, "get_dpatrk RTL cyl %4x(%d) trk %x ec# %06x\n", + cyl, cyl, trk, tstart); + + /* calc offset in file to track label */ + offset = CAPB(type) + (tstart * 30); + + /* see if track label is in cache */ + for (cn=0; cnfileref, offset, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "get_dpatrk RTL, Error on seek to %04x\n", offset); + return 0; + } + + /* read in a track label from disk */ + if ((len=sim_fread(buf, 1, 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_CMD, dptr, + "get_dpatrk Error %08x on read %04x of diskfile cyl %04x hds %02x sec 00\n", + len, 30, cyl, trk); + return 0; + } + } + + /* now write track label data to log */ + sim_debug(DEBUG_CMD, dptr, "Dpatrk %08x label", nstar); + for (i = 0; i < 30; i++) { + if (i == 16) + sim_debug(DEBUG_CMD, dptr, "\nDpatrl %08x label", nstar); + sim_debug(DEBUG_CMD, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_CMD, dptr, "\n"); + + if (buf[4] == 0x08) { /* see if defective track */ + uptr->SNS |= SNS_DEFTRK; /* flag as defective */ + tstart = nstar; /* save orginal track */ + /* get the alternate track address */ + cyl = (buf[22] << 8) | buf[23]; /* get the cylinder */ + trk = buf[24]; /* get the track */ + nstar = CHS2STAR(cyl, trk, sec); + sim_debug(DEBUG_CMD, dptr, + "Track %08x is defective, new track %08x\n", tstart, nstar); + } + /* see if we had it in our cache */ + if (found == -1) { + /* not in our cache, save the new track label */ + int32 na = 0; + for (cn=0; cn na) + continue; /* older */ + /* this is less used, so replace it */ + na = cn; + } + /* use na entry */ + for (i=0; i<30; i++) + tkl_label[unit].tkl[na].label[i] = buf[i]; + tkl_label[unit].tkl[na].age = 1; + tkl_label[unit].tkl[cn].track = offset; + } + return nstar; /* return track address */ +} + +/* start a disk operation */ +t_stat hsdp_preio(UNIT *uptr, uint16 chan) +{ + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int unit = (uptr - dptr->units); /* get the UNIT number */ + DIB* dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */ + int32 cnt; + + sim_debug(DEBUG_CMD, dptr, "hsdp_preio CMD %08x unit %02x\n", uptr->CMD, unit); + if ((cnt = IOCLQ_Num(&dibp->ioclq_ptr[unit])) >= (IOCLQ_SIZE)) { + sim_debug(DEBUG_CMD, dptr, "hsdp_preio CMD %08x unit %02x IOCLQ cnt %02x Full\n", + uptr->CMD, unit, cnt); + return SNS_BSY; /* IOCLQ is full, return busy */ + } + if ((uptr->CMD & 0xff) != 0) { /* just return if busy */ + sim_debug(DEBUG_CMD, dptr, "hsdp_preio CMD %08x unit %02x IOCLQ cnt %02x Busy\n", + uptr->CMD, unit, cnt); + return SNS_SMS; /* busy, but IOCLQ is not full */ + } + + sim_debug(DEBUG_CMD, dptr, "hsdp_preio unit %02x chsa %04x OK not busy\n", unit, chsa); + return SCPE_OK; /* not busy and IOCLQ not full */ +} + +/* load in the IOCD and process the commands */ +/* return = 0 OK */ +/* return = 1 error, chan_status will have reason */ +t_stat hsdp_iocl(CHANP *chp, int32 tic_ok) +{ + uint32 word1 = 0; + uint32 word2 = 0; + int32 docmd = 0; + UNIT *uptr = chp->unitptr; /* get the unit ptr */ + uint16 chan = get_chan(chp->chan_dev); /* our channel */ + uint16 chsa = chp->chan_dev; /* our chan/sa */ + uint16 devstat = 0; + DEVICE *dptr = get_dev(uptr); + + /* check for valid iocd address if 1st iocd */ + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + if (chp->chan_caw & 0x3) { /* must be word bounded */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl iocd bad address chsa %02x caw %06x\n", + chsa, chp->chan_caw); + chp->ccw_addr = chp->chan_caw; /* set the bad iocl address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + return 1; /* error return */ + } + } +loop: + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl @%06x entry chan_status[%04x] %04x SNS %08x\n", + chp->chan_caw, chan, chp->chan_status, uptr->SNS); + + /* Abort if we have any errors */ + if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl ERROR1 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* return error */ + } + + /* Read in first CCW */ + if (readfull(chp, chp->chan_caw, &word1) != 0) { /* read word1 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl ERROR2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Read in second CCW */ + if (readfull(chp, chp->chan_caw+4, &word2) != 0) { /* read word2 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl ERROR3 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + sim_debug(DEBUG_CMD, dptr, + "hsdp_iocl @%06x read ccw chan %02x IOCD wd 1 %08x wd 2 %08x SNS %08x\n", + chp->chan_caw, chan, word1, word2, uptr->SNS); + + chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */ + + /* Check if we had data chaining in previous iocd */ + /* if we did, use previous cmd value */ + if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + (chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_iocl @%06x DO DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + } else + chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ + + if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl bad IOCD1 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2 */ + + /* validate the commands for the disk */ + switch (chp->ccw_cmd) { + case DSK_WD: case DSK_RD: case DSK_INCH: case DSK_NOP: case DSK_INC: + case DSK_SKC: case DSK_XEZ: case DSK_LMR: case DSK_WSL: case DSK_RSL: + case DSK_IHA: case DSK_WTL: case DSK_RTL: case DSK_RAP: case DSK_WTF: + case DSK_FMT: case DSK_RE: case DSK_RENO: case DSK_REL: case DSK_RES: + case DSK_RVL: case DSK_POR: case DSK_REC: case DSK_TIC: + case DSK_SNS: + break; + default: + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl bad cmd %02x chan_status[%04x] %04x SNS %08x\n", + chp->ccw_cmd, chan, chp->chan_status, uptr->SNS); + return 1; /* error return */ + } + + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + /* 1st command can not be a TIC */ + if (chp->ccw_cmd == CMD_TIC) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl TIC bad cmd chan_status[%04x] %04x\n", + chan, chp->chan_status); + return 1; /* error return */ + } + } + + /* TIC can't follow TIC or be first in command chain */ + /* diags send bad commands for testing. Use all of op */ + if (chp->ccw_cmd == CMD_TIC) { + if (tic_ok) { + if (((word1 & MASK24) == 0) || (word1 & 0x3)) { + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl tic cmd bad address chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + return 1; /* error return */ + } + tic_ok = 0; /* another tic not allowed */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_iocl tic cmd ccw chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + goto loop; /* restart the IOCD processing */ + } + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + if (((word1 & MASK24) == 0) || (word1 & 0x3)) + uptr->SNS |= SNS_INAD; /* invalid address status */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl TIC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Check if we had data chaining in previous iocd */ + if ((chp->chan_info & INFO_SIOCD) || /* see if 1st IOCD in channel prog */ + (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + ((chp->ccw_flags & FLAG_DC) == 0))) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_iocl @%06x DO CMD No DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + docmd = 1; /* show we have a command */ + } + + /* Set up for this command */ + chp->ccw_flags = (word2 >> 16) & 0xf000; /* get flags from bits 0-3 of WD 2 of IOCD */ + chp->chan_status = 0; /* clear status for next IOCD */ + /* make a 24 bit address */ + chp->ccw_addr = word1 & MASK24; /* set the data/seek address */ + + /* validate parts of IOCD2 that are reserved */ + if (word2 & 0x0fff0000) { /* bits 4-15 must be zero */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl IOCD2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* DC can only be used with a read/write cmd */ + if (chp->ccw_flags & FLAG_DC) { + if ((chp->ccw_cmd != DSK_RD) && (chp->ccw_cmd != DSK_WD)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid DC */ + uptr->SNS |= SNS_CHER; /* chaining error */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl DC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + } + + chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ + + sim_debug(DEBUG_XIO, dptr, + "hsdp_iocl @%06x read docmd %01x addr %06x count %04x chan %04x ccw_flags %04x\n", + chp->chan_caw, docmd, chp->ccw_addr, chp->ccw_count, chan, chp->ccw_flags); + + if (docmd) { /* see if we need to process a command */ + DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ + + uptr = chp->unitptr; /* get the unit ptr */ + if (dibp == 0 || uptr == 0) { + chp->chan_status |= STATUS_PCHK; /* program check if it is */ + return 1; /* if none, error */ + } + + sim_debug(DEBUG_XIO, dptr, + "hsdp_iocl @%06x before start_cmd chan %04x status %04x count %04x SNS %08x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, uptr->u5); + + /* call the device startcmd function to process the current command */ + /* just replace device status bits */ + chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ + devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd); + chp->chan_status = (chp->chan_status & 0xff00) | devstat; + chp->chan_info &= ~INFO_SIOCD; /* show not first IOCD in channel prog */ + + sim_debug(DEBUG_XIO, dptr, + "hsdp_iocl @%06x after start_cmd chan %04x status %08x count %04x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count); + + /* see if bad status */ + if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) { + chp->chan_status |= STATUS_CEND; /* channel end status */ + chp->ccw_flags = 0; /* no flags */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_iocl bad status chsa %04x status %04x cmd %02x\n", + chsa, chp->chan_status, chp->ccw_cmd); + /* done with command */ + sim_debug(DEBUG_EXP, &cpu_dev, + "hsdp_iocl ERROR return chsa %04x status %08x\n", + chp->chan_dev, chp->chan_status); + return 1; /* error return */ + } else + + /* NOTE this code needed for MPX 1.X to run! */ + /* see if command completed */ + /* we have good status */ + if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_XIO, dptr, + "hsdp_iocl @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n", + chp->chan_caw, FIFO_Num(chsa), chan, chp->chan_status, chp->ccw_count); + } + } + /* the device processor returned OK (0), so wait for I/O to complete */ + /* nothing happening, so return */ + sim_debug(DEBUG_XIO, dptr, + "hsdp_iocl @%06x return, chan %04x status %04x count %04x irq_pend %1x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, irq_pend); + return 0; /* good return */ +} + +t_stat hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int32 unit = (uptr - dptr->units); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_CMD, dptr, + "hsdp_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n", + chsa, unit, cmd, uptr->CMD); + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd unit %02x not attached\n", unit); + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + if (cmd != DSK_SNS) /* we are completed with unit check status */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; + } + + if ((uptr->CMD & DSK_CMDMSK) != 0) { + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd unit %02x busy\n", unit); + uptr->CMD |= DSK_BUSY; /* Flag we are busy */ + return SNS_BSY; + } + uptr->SNS2 |= SNS_USEL; /* unit selected */ + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd CMD continue unit=%02x cmd %02x\n", unit, cmd); + + /* Unit is online, so process a command */ + switch (cmd) { + + case DSK_INCH: /* INCH 0x0 */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_startcmd starting INCH %06x cmd, chsa %04x MemBuf %08x cnt %04x\n", + uptr->u4, chsa, chp->ccw_addr, chp->ccw_count); + + uptr->SNS &= ~SNS_CMDREJ; /* not rejected yet */ + uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */ +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 20); /* start things off */ + sim_activate(uptr, 30); /* start things off */ +#else + sim_activate(uptr, 250); /* start things off */ +// sim_activate(uptr, 500); /* start things off */ +#endif + return SCPE_OK; /* good to go */ + break; + + case DSK_INC: /* 0xFF Initialize controller */ + if ((cmd == DSK_INC) && + (chp->ccw_count != 0x20)) /* count must be 32 to be valid */ + break; + case DSK_NOP: /* NOP 0x03 */ + case DSK_SKC: /* Seek command 0x07 */ + case DSK_XEZ: /* Rezero & Read IPL record 0x1f */ + case DSK_WD: /* Write command 0x01 */ + case DSK_RD: /* Read command 0x02 */ + case DSK_LMR: /* read mode register */ + case DSK_WSL: /* WSL 0x31 */ + case DSK_RSL: /* RSL 0x32 */ + case DSK_IHA: /* 0x47 Increment head address */ + case DSK_WTL: /* WTL 0x51 */ + case DSK_RTL: /* RTL 0x52 */ + case DSK_RVL: /* 0x42 Read vendor label */ + case DSK_WTF: /* 0x41 Write track format */ + case DSK_RAP: /* 0xA2 Read angular positions */ + case DSK_FMT: /* 0x0B Format for no skip */ + case DSK_RES: /* 0x23 Reserve */ + case DSK_REL: /* 0x33 Release */ + uptr->SNS &= ~MASK24; /* clear data & leave mode */ + uptr->SNS2 = (SNS_UNR|SNS_ONC|SNS_USEL);/* reset status to on cyl & ready */ + case DSK_SNS: /* Sense 0x04 */ + uptr->CMD |= cmd; /* save cmd */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_startcmd starting disk cmd %02x chsa %04x\n", + cmd, chsa); +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 20); /* start things off */ +// sim_activate(uptr, 30); /* start things off */ + sim_activate(uptr, 25); /* start things off */ +#else + sim_activate(uptr, 250); /* start things off */ +// sim_activate(uptr, 500); /* start things off */ +#endif + return SCPE_OK; /* good to go */ + break; + + } + + sim_debug(DEBUG_CMD, dptr, + "hsdp_startcmd done with hsdp_startcmd %02x chsa %04x SNS %08x\n", + cmd, chsa, uptr->SNS); + /* diags want the chan addr to point at bad command?? */ + chp->chan_caw -= 8; /* backup iocd address for diags */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* return error */ +} + +/* Handle haltio transfers for disk */ +t_stat hsdp_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int cmd = uptr->CMD & DSK_CMDMSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_EXP, dptr, "hsdp_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + /* stop any I/O and post status and return error status */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); + if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count); + sim_cancel(uptr); /* clear the input timer */ + chp->ccw_count = 0; /* zero the count */ + chp->chan_caw = 0; /* zero iocd address for diags */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* stop any chaining */ + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ + return CC2BIT | SCPE_IOERR; /* busy return */ + } else { + sim_debug(DEBUG_CMD, dptr, + "hsdp_haltio HIO I/O not busy chsa %04x cmd = %02x\n", chsa, cmd); + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + return CC1BIT | SCPE_OK; /* not busy */ + } +} + +/* Handle rsctl command for disk */ +t_stat hsdp_rsctl(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & DSK_CMDMSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_rsctl RSCTL chsa %04x cmd %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count); + sim_cancel(uptr); /* clear the input timer */ + chp->ccw_count = 0; /* zero the count */ + chp->chan_caw = 0; /* zero iocd address for diags */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC);/* stop any chaining */ + } + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_rsctl RSCTL I/O not busy chsa %04x cmd %02x\n", chsa, cmd); + return SCPE_OK; /* not busy */ +} + +/* Handle processing of hsdp requests. */ +t_stat hsdp_srv(UNIT *uptr) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + int cmd = uptr->CMD & DSK_CMDMSK; + int type = GET_TYPE(uptr->flags); + uint32 tcyl=0, trk=0, cyl=0, sec=0, tempt=0; + int unit = (uptr - dptr->units); + int len = chp->ccw_count; + int i,j,k; + uint32 mema, ecc, cecc, tstar; /* memory address */ + uint8 ch; + uint16 ssize = hsdp_type[type].ssiz * 4; /* disk sector size in bytes */ + uint32 tstart; + uint8 lbuf[32]; + uint8 buf2[1024]; + uint8 buf[1024]; + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv entry unit %02x CMD %08x chsa %04x count %04x %x/%x/%x \n", + unit, uptr->CMD, chsa, chp->ccw_count, + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + if (cmd != DSK_SNS) { /* we are completed with unit check status */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + } + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv cmd=%02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count); + +#ifdef FOR_TESTING_DIAGS + /* see if mode reg is 1 (diag mode), if so we are done */ + if ((uptr->SNS >> 24) & 1) { /* get mode value */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chp->ccw_count = 0; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } +#endif + + switch (cmd) { + case 0: /* No command, stop disk */ + break; + + case DSK_INC: /* 0xFF Initialize controller */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv cmd CONT INC %06x chsa %04x addr %06x count %04x completed\n", + chp->chan_inch_addr, chsa, mema, chp->ccw_count); + /* to use this inch method, byte count must be 0x20 */ + if (len != 0x20) { + /* we have invalid count, error, bail out */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* read all 32 bytes, stopping every 4 bytes to make words */ + /* the 8 words have drive data for each unit */ + /* WARNING 8 drives must be defined for this controller */ + /* so we will not have a map fault */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv CONT INC data:"); + for (i=0; i < 32; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (i == 16) + sim_debug(DEBUG_CMD, dptr, "\nhsdp_srv CONT INC data:"); + sim_debug(DEBUG_CMD, dptr, " %02x", buf[i]); + if (((i+1)%4) == 0) { /* see if we have a word yet */ +#ifndef FOR_TESTING + int dn = i/4; /* get drive number */ +// UNIT *up = uptr0[dn]; /* get our unit pointer */ + UNIT *uptr0 = dptr->units; /* get unit 0 pointer */ +#endif + /* drive attribute registers */ + /* may want to use this later */ + /* clear warning errors */ + tstart = (buf[i-3]<<24) | (buf[i-2]<<16) + | (buf[i-1]<<8) | (buf[i]); +#ifndef FOR_TESTING + uptr0[dn].DAI = tstart; /* save drive attribute register */ + /* set mode data from last byte */ + uptr0[dn].SNS &= MASK24; /* clear old mode data */ + uptr0[dn].SNS |= (buf[i] << 24); /* save mode value */ +#endif + } + } + sim_debug(DEBUG_CMD, dptr, "\n"); + + uptr->CMD &= LMASK; /* remove old cmd */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv cmd INC chsa %04x chsa %06x count %04x mode %08x completed\n", + chsa, mema, chp->ccw_count, uptr->DAI); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_INCH2: /* use 0xF0 for inch, just need int */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n", + chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count); + + /* mema has IOCD word 1 contents. For the disk processor it contains */ + /* a pointer to the INCH buffer followed by 8 drive attribute words that */ + /* contains the flags, sector count, MHD head count, and FHD count */ + /* len has the byte count from IOCD wd2 and should be 0x24 (36) */ + /* the INCH buffer address must be set for the parent channel as well */ + /* as all other devices on the channel. Call set_inch() to do this for us */ + /* just return OK and channel software will use u4 as status buffer addr */ + + if (len != 36) { + /* we have invalid count, error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* read all 36 bytes, stopping every 4 bytes to make words */ + /* the first word has the inch buffer address */ + /* the next 8 words have drive data for each unit */ + /* WARNING 8 drives must be defined for this controller */ + /* so we will not have a map fault */ + for (i=0; i < 36; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (((i+1)%4) == 0) { /* see if we have a word yet */ + if (i == 3) { + /* inch buffer address */ + mema = (buf[0]<<24) | (buf[1]<<16) | + (buf[2]<<8) | (buf[3]); + sim_debug(DEBUG_CMD, dptr, "Inch buffer %08x", mema); + } else { +#ifndef FOR_TESTING + int dn = (i-4)/4; /* get drive number */ + UNIT *uptr0 = dptr->units; /* get unit 0 pointer */ +#endif + /* drive attribute registers */ + /* may want to use this later */ + /* clear warning errors */ + tstart = (buf[i-3]<<24) | (buf[i-2]<<16) + | (buf[i-1]<<8) | (buf[i]); + if (i == 23) + sim_debug(DEBUG_CMD, dptr, "\nInch buffer %08x", mema); +#ifndef FOR_TESTING + uptr0[dn].DAI = tstart; /* save drive attribute register */ + /* set mode data from last byte */ + uptr0[dn].SNS &= MASK24; /* clear old mode data */ + uptr0[dn].SNS |= (buf[i] << 24); /* save mode value */ +#endif + sim_debug(DEBUG_CMD, dptr, " %08x", tstart); + } + } + } + sim_debug(DEBUG_CMD, dptr, "\n"); + + /* now call set_inch() function to write and test inch buffer addresses */ + /* 1-224 wd buffer is provided, status is 128 words offset from start */ + mema += (128*4); /* offset to inch buffers */ + i = set_inch(uptr, mema, 33); /* new address of 33 entries */ + if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + uptr->CMD &= LMASK; /* remove old cmd */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv cmd INCH %06x chsa %04x addr %06x count %04x mode %08x completed\n", + chp->chan_inch_addr, chsa, mema, chp->ccw_count, tcyl); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_NOP: /* NOP 0x03 */ + if ((uptr->CMD & DSK_WAITING) == 0) { + /* Do a fake wait to kill some time */ + uptr->CMD |= DSK_WAITING; /* show waiting for NOP */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv cmd NOP stalling for 50 cnts\n"); +// sim_activate(uptr, 250); /* start waiting */ +// sim_activate(uptr, 50); /* start waiting */ + sim_activate(uptr, 350); /* start waiting */ + break; + } + /* NOP drop through after wait */ + case DSK_RES: /* 0x23 Reserve */ + case DSK_REL: /* 0x33 Release */ + uptr->CMD &= LMASK; /* remove old cmd */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv cmd NOP chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_RAP: /* 0xA2 Read angular positions */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* get STAR (target sector) data in STAR */ + cyl = STAR2CYL(uptr->CHS); /* get current cyl */ + trk = (uptr->CHS >> 8) & 0xff; /* get trk/head */ + sec = uptr->CHS & 0xff; /* set sec */ + +// ch = ((sec * 2) % SPT(type)) & 0x3f; /* get index cnt */ + ch = ((2*SPT(type))-1) & 0x3f; /* get index cnt */ + uptr->SNS2 = (uptr->SNS2 & 0xc0ff) | ((((uint32)ch) & 0x3f) << 8); + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv RAP %02x cyl %04x trk %02x sec %02x\n", + ch, cyl&0xffff, trk, sec); + + if (chan_write_byte(chsa, &ch)) { /* put a byte to memory */ + sim_debug(DEBUG_CMD, dptr, + "HSDP RAP %02x for addr /%04x/%02x/%02x\n", + ch, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + if (chp->chan_status & STATUS_PCHK) { /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + } else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_IHA: /* 0x47 Increment head address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* get STAR (target sector) data in STAR */ + cyl = STAR2CYL(uptr->CHS); /* get current cyl */ + trk = (uptr->CHS >> 8) & 0xff; /* get trk/head */ + sec = 0; /* set sec to zero for this head */ + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv IHA cyl %04x trk %02x sec %02x unit=%02x\n", + cyl&0xffff, trk, sec, unit); + + /* Check if head increment valid */ + trk += 1; /* increment the head # */ + if (trk >= hsdp_type[type].nhds) { /* see if too big */ + trk = 0; /* back to trk 0 */ + cyl += 1; /* next cylinder */ + if (cyl >= hsdp_type[type].cyl) { /* see if too big */ + /* set new STAR value using new values */ + uptr->CHS = CHS2STAR(cyl, trk, sec); + sim_debug(DEBUG_EXP, dptr, + "hsdp_srv IHA ERROR cyl %04x trk %02x sec %02x unit=%02x\n", + cyl, trk, sec, unit); + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* error */ + break; + } + } + + /* set new STAR value using new values */ + uptr->CHS = CHS2STAR(cyl, trk, sec); + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv IHA unit=%02x STAR %08x %04x/%02x/%02x\n", + unit, uptr->CHS, cyl, trk, sec); + /* get alternate track if this one is defective */ +//sim_debug(DEBUG_CMD, dptr, "Dpatrk1 %08x label\n", uptr->CHS); + tempt = get_dpatrk(uptr, uptr->CHS, lbuf); + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(tempt, SPT(type), SPC(type)) * SSB(type); + + if ((tempt == 0) && (uptr->CHS != 0)) { + /* we have error */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_srv IHA get_dpatrk return error tempt %06x tstart %06x CHS %08x\n", + tempt, tstart, uptr->CHS); + goto iha_error; + } + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ +iha_error: + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + sim_debug(DEBUG_EXP, dptr, "hsdp_srv IHA error on seek to %04x\n", tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_REC: /* 0xB2 */ /* Read ECC correction code */ + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd CMD REC Read ECC\n"); + /* count must be 4, if not prog check */ + if (len != 4) { + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv REC bad count unit=%02x count%04x CHS %08x\n", + unit, len, uptr->CHS); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK|STATUS_LENGTH); + break; + } + /* create offset and mask */ + ecc = dple_ecc32(obuf, ssize); /* calc ecc for original sector */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv DEC old obuf data %02x%02x%02x%02x %02x%02x%02x%02x\n", + obuf[1016], obuf[1017], obuf[1018], obuf[1019], + obuf[1020], obuf[1021], obuf[1022], obuf[1023]); + cecc = dple_ecc32(bbuf, ssize); /* calc ecc for bad sector */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv DEC bad bbuf data %02x%02x%02x%02x %02x%02x%02x%02x\n", + bbuf[1016], bbuf[1017], bbuf[1018], bbuf[1019], + bbuf[1020], bbuf[1021], bbuf[1022], bbuf[1023]); + mema = 0; + for (i=0, j=0; i>= 1; /* move mask right */ + } + tcyl = (k * 8) + sec; /* starting bit# */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv REC sb# %04x byte# %04x mask %06x start %08x\n", + sec, k, mema, tcyl); + /* 16 bit sector offset and 9 of 16 bit mask */ + /* tcyl - fake 14 bit offset */ + /* mema - fake 9 bit mask */ + buf[0] = (tcyl & 0x3f00) >> 8; /* upper 6 bits */ + buf[1] = tcyl & 0xff; /* lower 8 bits */ + buf[2] = (mema & 0x100) >> 8; /* upper 1 bits */ + buf[3] = mema & 0xff; /* lower 8 bits */ + /* write the offset and mask data */ + for (i=0; i<4; i++) { + ch = buf[i]; /* get a char from buffer */ + if (chan_write_byte(chsa, &ch)) { /* put a byte to memory */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv DEC read %04x bytes of %04x\n", + i, chp->ccw_count); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + } + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv wrote DEC offset %04x mask %04x CHS %08x\n", + tcyl & 0x3fff, mema & 0x1ff, uptr->CHS); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_SNS: /* 0x04 */ + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd CMD sense\n"); + + /* count must be 12 or 14, if not prog check */ + if (len != 12 && len != 14) { + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv Sense bad count unit=%02x count%04x\n", unit, len); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK|STATUS_LENGTH); + break; + } + /* bytes 0,1 - Cyl entry from CHS reg */ + ch = (uptr->CHS >> 24) & 0xff; + sim_debug(DEBUG_CMD, dptr, "hsdp_srv sense CHS b0 unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->CHS >> 16) & 0xff; + sim_debug(DEBUG_CMD, dptr, "hsdp_srv sense CHS b1 unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 2 - Track entry from CHS reg */ + ch = (uptr->CHS >> 8) & 0xff; + sim_debug(DEBUG_CMD, dptr, "hsdp_srv sense CHS b2 unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 3 - Sector entry from CHS reg */ + ch = (uptr->CHS) & 0xff; + sec = ch; /* save sec num for later */ +#ifndef FOR_TESTING + /* get STAR (target sector) data in STAR */ + cyl = STAR2CYL(uptr->CHS); /* get current cyl */ + trk = (uptr->CHS >> 8) & 0xff; /* get trk/head */ + if ((trk == (hsdp_type[type].nhds-1)) && /* see if last trk */ + ((cyl == hsdp_type[type].cyl-1)) && /* see if last cyl */ + (sec == 0)) { /* sec is zero */ + ch = 0; /* show last track */ + } +#endif + sim_debug(DEBUG_CMD, dptr, "hsdp_srv sense CHS b3 unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 4 - mode reg, byte 0 of SNS */ + ch = (uptr->SNS >> 24) & 0xff; /* return the sense data */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv sense unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* bytes 5-7 - status bytes, bytes 1-3 of SNS */ + ch = (uptr->SNS >> 16) & 0xff; + sim_debug(DEBUG_CMD, dptr, "hsdp_srv sense unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS >> 8) & 0xff; + sim_debug(DEBUG_CMD, dptr, "hsdp_srv sense unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS) & 0xff; + sim_debug(DEBUG_CMD, dptr, "hsdp_srv sense unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 8-11 - drive mode register entries from assigned hsdp */ + ch = hsdp_type[type].type & 0xff; /* type byte */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv datr unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = hsdp_type[type].spt & 0xff; /* get sectors per track */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv datr unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = hsdp_type[type].nhds & 0xff; /* get # MHD heads */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv datr unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); +#ifdef FOR_TESTING + ch = (uptr->SNS >> 24) & 0xff; /* get mode data */ +#else + ch = 0; /* no FHD heads */ +#endif + sim_debug(DEBUG_CMD, dptr, "hsdp_srv datr unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 12 & 13 are optional, so check if read done */ + /* TODO add drive status bits here */ + if ((test_write_byte_end(chsa)) == 0) { + /* bytes 12 & 13 contain drive related status */ + uptr->SNS2 |= (SNS_SEND|SNS_USEL); /* selected & seek end */ + /* bits 2-7 have sector pulse count */ + ch = ((sec * 2) % SPT(type)) & 0x3f;/* get index cnt */ + uptr->SNS2 = (uptr->SNS2 & 0xc0ff) | ((((uint32)ch) & 0x3f) << 8); + ch = (uptr->SNS2 >> 8) & 0xff; /* seek end and unit selected for now */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv dsr unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + ch = 0x30; /* drive on cylinder and ready for now */ + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + ch = uptr->SNS2 & 0xff; /* drive on cylinder and ready for now */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv dsr unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + } + uptr->SNS &= 0xff000000; /* reset status */ + uptr->SNS2 = 0; /* reset status */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_SKC: /* Seek cylinder, track, sector 0x07 */ + /* If we are waiting on seek to finish, check if there yet. */ + if (uptr->CMD & DSK_SEEKING) { + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)) * SSB(type); + /* we are on cylinder, seek is done */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv seek on cylinder to %04x/%02x/%02x bytes %06x\n", + (uptr->CHS >> 16) & 0xffff, (uptr->CHS >> 8) & 0xff, + uptr->CHS & 0xff, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS2 |= (SNS_SEND|SNS_ONC); /* On cylinder & seek done */ + /* we have already seeked to the required sector */ + /* we do not need to seek again, so move on */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + break; + } + + /* not seeking, so start a new seek */ + /* set buf data to current STAR values */ + tcyl = cyl = STAR2CYL(uptr->CHS); /* get current cyl */ + buf[0] = (cyl >> 8) & 0xff; /* split cylinder */ + buf[1] = cyl & 0xff; + buf[2] = (uptr->CHS >> 8) & 0xff; /* get trk/head */ + buf[3] = uptr->CHS & 0xff; /* get sec */ + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv current STAR unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + if (len > 4) { + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv SEEK bad count unit=%02x count%04x\n", unit, len); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK|STATUS_LENGTH); + break; + } + + /* Read in 1-4 character seek code */ + for (i = 0; i < 4; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + if (i == 0) { + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv seek error unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* Disc addressing or seek error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + chp->ccw_count = len; /* restore count, huh? */ + return SCPE_OK; + break; + } + /* just read the next byte */ + /* done reading, see how many we read */ + if (i == 1) { + /* UTX wants to set seek STAR to zero */ + buf[0] = buf[1] = buf[2] = buf[3] = 0; + break; + } + } + } + /* else the cyl, trk, and sect are ready to update */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv STAR unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + /* save STAR (target sector) data in STAR */ + tstar = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); + cyl = STAR2CYL(tstar); /* get the cylinder */ + trk = buf[2]; /* get the track */ + sec = buf[3]; /* get sec */ + + /* see if we need to incr to next track for alt sec support */ + if (uptr->LSC != SPT(type)) { + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv LSC0 %02x B4 test/incr cyl %04x trk %02x sec %02x\n", + uptr->LSC, (tstar>>16)&0xffff, (tstar>>8)&0xff, tstar&0xff); + if ((int)(tstar&0xff) >= (int)(SPT(type)-1)) { + tstar &= 0xffffff00; /* clear sector number */ + tstar += 0x00000100; /* bump head # */ + if (((tstar>>8)&0xff) >= (HDS(type))) { + tstar &= 0xffff00ff; /* clear head number */ + tstar += 0x00010000; /* bump cyl # */ + } + } + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv LSC0 %02x AF test/incr cyl %04x trk %02x sec %02x\n", + uptr->LSC, (tstar>>16)&0xffff, (tstar>>8)&0xff, tstar&0xff); +//#define DO_DYNAMIC_DEBUG +#ifdef DO_DYNAMIC_DEBUG +// cpu_dev.dctrl |= DEBUG_INST|DEBUG_TRAP|DEBUG_CMD|DEBUG_DETAIL; /* start instruction trace */ +#endif + } + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv NEW SEEK cyl %04x trk %02x sec %02x unit=%02x\n", + cyl&0xffff, trk, buf[3], unit); + + /* Check if seek valid */ + if (cyl >= hsdp_type[type].cyl || + trk >= hsdp_type[type].nhds || + buf[3] >= uptr->LSC) { + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv seek ERROR LSC %02x cyl %04x trk %02x sec %02x unit=%02x\n", + uptr->LSC, cyl, trk, buf[3], unit); + + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + + /* set new STAR value */ + uptr->CHS = CHS2STAR(cyl, trk, buf[3]); + + /* we have an error, tell user */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* end command */ + break; + } + + /* get alternate track if this one is defective */ + tempt = get_dpatrk(uptr, tstar, lbuf); + + if ((tempt == 0) && (tstar != 0)) { + /* we have error */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_srv SEEK get_dpatrk return error tempt %06x STAR %08x\n", + tempt, tstar); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(tempt, SPT(type), SPC(type)) * SSB(type); + /* set new STAR value using new values */ + uptr->CHS = tstar; + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv seek start %04x cyl %04x trk %02x sec %02x CHS %08x\n", + tstart, cyl, trk, buf[3], uptr->CHS); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* seek home */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv Error on seek to %08x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* do a delay to slow things down */ + if (STAR2CYL(uptr->CHS) != tcyl) { + k = ((int)tcyl - (int)cyl); + if (k < 0) + k = -k; + } else { + k = 20; + } + /* Do a fake seek to kill time */ + uptr->CMD |= DSK_SEEKING; /* show we are seeking */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv seeking unit=%02x to %04x/%02x/%02x from cyl %04x (%04x)\n", + unit, cyl, trk, buf[3], tcyl, k); +#ifdef FAST_FOR_UTX + sim_activate(uptr, 15); +// sim_activate(uptr, 20); /* start things off */ +// sim_activate(uptr, 20+k); /* start us off */ +#else +// sim_activate(uptr, 150); /* start things off */ + sim_activate(uptr, 200+k); /* start us off */ +// sim_activate(uptr, 400+k); /* start us off */ +#endif + break; + + case DSK_XEZ: /* 0x37 */ /* Rezero & Read IPL record */ + + sim_debug(DEBUG_CMD, dptr, "RD REZERO IPL unit=%02x seek 0\n", unit); + /* Do a seek to 0 */ + uptr->CHS = 0; /* set current CHS to 0, 0, 0 */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CMD |= DSK_SKC; /* show as seek command */ + tstart = 0; /* byte offset is 0 */ + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* we are on cylinder/track/sector zero, so go on */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv done seek trk 0\n"); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + break; + + case DSK_LMR: /* 0x1F */ + sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x\n", unit); + /* Read in 1 character of mode data */ + if (chan_read_byte(chsa, &buf[0])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x old %02x new %02x\n", + unit, (uptr->SNS>>24)&0xff, buf[0]); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS &= MASK24; /* clear old mode data */ + uptr->SNS |= (buf[0] << 24); /* save mode value */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_FMT: /* 0x0B Format for no skip */ + /* buffer must be on halfword boundry if not STATUS_PCHK and SNS_CMDREJ status */ +// chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ +// uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + /* byte count can not exceed 20160 for the track */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "HSDP Format starting CMD %08x chsa %04x buffer %06x count %04x\n", + uptr->CMD, chsa, chp->ccw_addr, chp->ccw_count); + sim_debug(DEBUG_CMD, dptr, "Format %x label", uptr->CHS); + /* now read sector label data */ + len = chp->ccw_count; + for (i = 0; i < len; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have write error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + if ((i%16) == 0) + sim_debug(DEBUG_CMD, dptr, "\nFormat %x label", uptr->CHS); + sim_debug(DEBUG_CMD, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_CMD, dptr, "\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_RD: /* Read Data */ + if ((uptr->CMD & DSK_READING) == 0) { /* see if we are reading data */ + uptr->CMD |= DSK_READING; /* read from disk starting */ + sim_debug(DEBUG_CMD, dptr, + "HSDP READ starting CMD %08x chsa %04x buffer %06x count %04x\n", + uptr->CMD, chsa, chp->ccw_addr, chp->ccw_count); + } + + if (uptr->CMD & DSK_READING) { /* see if we are reading data */ + /* get sector offset */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = hsdpsec2star(tstart, type); + + /* get alternate track if this one is defective */ + tempt = get_dpatrk(uptr, uptr->CHS, lbuf); + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(tempt, SPT(type), SPC(type)) * SSB(type); + + if ((tempt == 0) && (uptr->CHS != 0)) { + /* we have error */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_srv READ get_dpatrk return error tempt %06x tstart %06x\n", tempt, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + sim_debug(DEBUG_EXP, dptr, "hsdp_srv READ error on seek to %04x\n", tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + uptr->SNS &= ~SNS_DEFTRK; /* remove defective flag */ + /* see if spare track */ + if (lbuf[4] & 0x20) { /* see if spare track */ + uptr->SNS |= SNS_DADE; /* disk addr error */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_srv READ get_dpatrk return spare tempt %06x tstart %06x\n", tempt, tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + /* see if reserved track */ + if (lbuf[4] & 0x10) { /* see if reserved track */ + uptr->SNS |= SNS_MOCK; /* mode check error */ + uptr->SNS |= SNS_RES8; /* reserved track access error */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv READ, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "HSDP READ reading CMD %08x chsa %04x tstart %04x buffer %06x count %04x\n", + uptr->CMD, chsa, tstart, chp->ccw_addr, chp->ccw_count); + + /* read in a sector of data from disk */ + if ((len=sim_fread(buf, 1, ssize, uptr->fileref)) != ssize) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, ssize, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv after READ chsa %04x buffer %06x count %04x\n", + chsa, chp->ccw_addr, chp->ccw_count); + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv READ data %02x%02x%02x%02x %02x%02x%02x%02x " + "%02x%02x%02x%02x %02x%02x%02x%02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], + buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]); + + uptr->CHS++; /* next sector number */ + /* process the next sector of data */ + for (i=0; ichan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + sim_debug(DEBUG_CMD, dptr, + "HSDP Read %04x bytes leaving %04x from diskfile /%04x/%02x/%02x\n", + i, chp->ccw_count, ((uptr->CHS)>>16)&0xffff, + ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + } + + /* get current sector offset */ + j = STAR2SEC(tempt, SPT(type), SPC(type)); /* current sector */ + i = ((CYL(type) - 3) * HDS(type)) * SPT(type); /* diag start */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv after READ j %04x i %04x j-i %04x CAP %06x DIAG %06x\n", + j, i, j-i, CAP(type), (((CYL(type) - 3) * HDS(type)) * SPT(type))); /* diag start */ + if (j >= i) { /* only do diag sectors */ + cecc = dple_ecc32(buf, ssize); /* calc ecc for sector */ + sim_debug(DEBUG_CMD, dptr, + "ECC j %02x i %02x data calc Old %08x Cur %08x cyl %04x hds %02x sec %02x\n", + j, i, decc[j-i], cecc, STAR2CYL(tempt), ((tempt) >> 8)&0xff, (tempt&0xff)); + if ((decc[j-i] != 0) && (cecc != decc[j-i])) { /* test against old */ + /* checksum error */ + sim_debug(DEBUG_CMD, dptr, + "ECC j %02x i %02x data error Old %08x New %08x cyl %04x hds %02x sec %02x\n", + j, i, decc[j-i], cecc, STAR2CYL(tempt), ((tempt) >> 8)&0xff, (tempt&0xff)); + uptr->SNS |= SNS_ECCD; /* data ECC error */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_CHECK|STATUS_EXPT); + return SCPE_OK; + } + } + + /* see if this is a read ECC from diag */ + /* mode byte will be 0x08 and remaining count will be 4 */ + if ((uptr->SNS & SNS_DIAGMOD) && (chp->ccw_count == 4)) { + for (i=0; iCHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + /* set ECC value here */ + for (i=0; i<4; i++) { + ch = (ecc >> ((3-i)*8)) & 0xff; /* get a char from buffer */ + if (chan_write_byte(chsa, &ch)) { /* put a byte to memory */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + return SCPE_OK; + } + } + sim_debug(DEBUG_CMD, dptr, + "Read ECC %04x for diags 4 bytes to ECC REG cyl %04x hds %02x sec %02x\n", + ecc, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + } + + sim_debug(DEBUG_CMD, dptr, + "HSDP READ %04x bytes leaving %4x to be read to %06x from diskfile %04x/%02x/%02x\n", + ssize, chp->ccw_count, chp->ccw_addr, + ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + + /* see if we need to incr to next track for alt sec support */ + if (uptr->LSC != SPT(type)) { + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv LSC %02x B4 test/incr cyl %04x trk %02x sec %02x\n", + uptr->LSC, (uptr->CHS>>16)&0xffff, (uptr->CHS>>8)&0xff, uptr->CHS&0xff); + if ((uptr->CHS&0xff) >= (SPT(type)-1)) { + uptr->CHS &= 0xffffff00; /* clear sector number */ + uptr->CHS += 0x00000100; /* bump head # */ + if (((uptr->CHS>>8)&0xff) >= (HDS(type))) { + uptr->CHS &= 0xffff00ff; /* clear head number */ + uptr->CHS += 0x00010000; /* bump cyl # */ + } + } + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv LSC %02x AF test/incr cyl %04x trk %02x sec %02x\n", + uptr->LSC, (uptr->CHS>>16)&0xffff, (uptr->CHS>>8)&0xff, uptr->CHS&0xff); + } + + /* get sector offset */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + + /* see if over end of disk */ + if (tstart >= (uint32)CAP(type)) { + /* EOM reached, abort */ + sim_debug(DEBUG_CMD, dptr, + "HSDP Read reached EOM for read from disk @ %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CHS = 0; /* reset cylinder position */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* see if we are done reading data */ + if (test_write_byte_end(chsa)) { + /* EOM reached, abort */ + sim_debug(DEBUG_CMD, dptr, + "HSDP Read complete for read from disk @ %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "HSDP sector read complete, %x bytes to go from diskfile /%04x/%02x/%02x\n", + chp->ccw_count, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 10); /* wait to read next sector */ + sim_activate(uptr, 15); /* wait to read next sector */ +// sim_activate(uptr, 20); /* wait to read next sector */ +#else + sim_activate(uptr, 150); /* wait to read next sector */ +// sim_activate(uptr, 300); /* wait to read next sector */ +#endif + break; + } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + break; + + case DSK_WD: /* Write Data */ + if ((uptr->CMD & DSK_WRITING) == 0) { /* see if we are writing data */ + sim_debug(DEBUG_CMD, dptr, + "HSDP WRITE starting unit=%02x CMD %08x write %04x from %06x to %03x/%02x/%02x\n", + unit, uptr->CMD, chp->ccw_count, chp->ccw_addr, + ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + + if (uptr->SNS & 0xf0000000) { /* see if any mode bit 0-3 is set */ + uptr->SNS |= SNS_MOCK; /* mode check error */ + chp->chan_status |= STATUS_PCHK; /* channel prog check */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + uptr->CMD |= DSK_WRITING; /* write to disk starting */ + } + if (uptr->CMD & DSK_WRITING) { /* see if we are writing data */ + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + /* file offset in bytes */ + tstart = tstart * SSB(type); + + /* get alternate track if this one is defective */ + tempt = get_dpatrk(uptr, uptr->CHS, lbuf); + /* file offset in bytes to std or alt track */ + tstart = STAR2SEC(tempt, SPT(type), SPC(type)) * SSB(type); + + if ((tempt == 0) && (uptr->CHS != 0)) { + /* we have error */ + sim_debug(DEBUG_EXP, dptr, + "hsdp_srv WRITE get_dpatrk return error tempt %06x tstart %06x\n", tempt, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + sim_debug(DEBUG_EXP, dptr, "hsdp_srv WRITE error on seek to %04x\n", tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + uptr->SNS &= ~SNS_DEFTRK; /* remove defective flag */ + /* see if spare track */ + if (lbuf[4] & 0x20) { /* see if spare track */ + uptr->SNS |= SNS_DADE; /* disk addr error */ + chp->chan_status |= STATUS_PCHK; /* channel prog check */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + /* see if reserved track */ + if (lbuf[4] & 0x10) { /* see if reserved track */ + uptr->SNS |= SNS_MOCK; /* mode check error */ + uptr->SNS |= SNS_RES8; /* reserved track access error */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv WRITE, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* process the next sector of data */ + tcyl = 0; /* used here as a flag for short read */ + for (i=0; ichan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* if error on reading 1st byte, we are done writing */ + if ((i == 0) || (chp->chan_status & STATUS_PCHK)) { + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "HSDP Wrote %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + ch = 0; /* finish out the sector with zero */ + tcyl++; /* show we have no more data to write */ + } + buf2[i] = ch; /* save the char */ + } + + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = hsdpsec2star(tstart, type); + + /* write the sector to disk */ + if ((i=sim_fwrite(buf2, 1, ssize, uptr->fileref)) != ssize) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on write %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + i, ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv after WRITE buffer %06x count %04x\n", + chp->ccw_addr, chp->ccw_count); + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv WRITE data %02x%02x%02x%02x %02x%02x%02x%02x " + "%02x%02x%02x%02x %02x%02x%02x%02x\n", + buf2[0], buf2[1], buf2[2], buf2[3], buf2[4], buf2[5], buf2[6], buf2[7], + buf2[8], buf2[9], buf2[10], buf2[11], buf2[12], buf2[13], buf2[14], buf2[15]); + sim_debug(DEBUG_DATA, dptr, + "hsdp_srv after WRITE CAP %06x DIAG %06x\n", + CAP(type), (((CYL(type) - 3) * HDS(type)) * SPT(type))); /* diag start */ + + /* get current sector offset */ + j = STAR2SEC(tempt, SPT(type), SPC(type)); /* current sector */ + i = ((CYL(type) - 3) * HDS(type)) * SPT(type); /* diag start */ + sim_debug(DEBUG_DATA, dptr, + "hsdp_srv after WRITE j %04x i %04x j-i %04x CAP %06x DIAG %06x\n", + j, i, j-i, CAP(type), (((CYL(type) - 3) * HDS(type)) * SPT(type))); /* diag start */ + if (j >= i) { /* only do diag sectors */ + cecc = dple_ecc32(buf2, ssize); /* calc ecc for sector */ + sim_debug(DEBUG_DATA, dptr, + "ECC j %02x i %02x data write Old %08x Cur %08x cyl %04x hds %02x sec %02x\n", + j, i, decc[j-i], cecc, STAR2CYL(tempt), ((tempt) >> 8)&0xff, (tempt&0xff)); + decc[j-i] = cecc; /* set new ecc */ + } + j = j-i; /* save index */ + + /* see if this is a write ECC from diag */ + /* mode byte will be 0x08 and remaining count will be 4 */ + if ((uptr->SNS & SNS_DIAGMOD) && (chp->ccw_count == 4)) { + for (i=0; iCHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + /* set ECC value here */ + for (i=0; i<4; i++) { + if (chan_read_byte(chsa, &ch)) {/* get a byte from memory */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + return SCPE_OK; + } + /* get an ECC byte */ + buf[i] = ch; /* put a char to buffer */ + ecc |= ((ch & 0xff) << ((3-i)*8)); + } + tcyl++; /* show we have no more data to write */ + sim_debug(DEBUG_CMD, dptr, + "Write decc[%04x] ECC=%08x from diags, calc ECC=%08x cyl %04x hds %02x sec %02x\n", + j, ecc, cecc, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + decc[j] = ecc; /* set new ecc from diag */ + } + + sim_debug(DEBUG_CMD, dptr, + "DISK WR to sec end %04x bytes end %04x to diskfile cyl %04x hds %02x sec %02x\n", + len, ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + + uptr->CHS++; /* next sector number */ + if (tcyl != 0) { /* see if done with write command */ + sim_debug(DEBUG_CMD, dptr, + "HSDP WroteB %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + } + + /* see if we need to incr to next track for alt sec support */ + if (uptr->LSC != SPT(type)) { + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv LSC2 %02x B4 test/incr cyl %04x trk %02x sec %02x\n", + uptr->LSC, (uptr->CHS>>16)&0xffff, (uptr->CHS>>8)&0xff, uptr->CHS&0xff); + if ((uptr->CHS&0xff) >= (SPT(type)-1)) { + uptr->CHS &= 0xffffff00; /* clear sector number */ + uptr->CHS += 0x00000100; /* bump track # */ + if (((uptr->CHS>>8)&0xff) >= (HDS(type))) { + uptr->CHS &= 0xffff00ff; /* clear head number */ + uptr->CHS += 0x00010000; /* bump cyl # */ + } + } + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv LSC2 %02x AF test/incr cyl %04x trk %02x sec %02x\n", + uptr->LSC, (uptr->CHS>>16)&0xffff, (uptr->CHS>>8)&0xff, uptr->CHS&0xff); + } + + /* get sector offset */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + + /* see if over end of disk */ + if (tstart >= (uint32)CAP(type)) { + /* EOM reached, abort */ + sim_debug(DEBUG_CMD, dptr, + "HSDP Write reached EOM for write to disk @ /%04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CHS = 0; /* reset cylinder position */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* see if we are done reading data */ + if (test_write_byte_end(chsa)) { + sim_debug(DEBUG_CMD, dptr, + "DISK Write complete for read from diskfile %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 10); /* keep writing */ + sim_activate(uptr, 15); /* keep writing */ +#else + sim_activate(uptr, 150); /* wait to read next sector */ +// sim_activate(uptr, 300); /* wait to read next sector */ +#endif + break; + } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + break; + + case DSK_RSL: /* RSL 0x32 */ + /* Read sector label zero to get disk geometry */ + /* write 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + /* zero the Sector Label Buffer */ + for (i = 0; i < 30; i++) + buf[i] = 0; + + len = chp->ccw_count; /* get number of sectors per track */ + mema = uptr->CHS+(len/30); /* save address */ + + sim_debug(DEBUG_CMD, dptr, "before RSL Sector %x len %x\n", uptr->CHS, len); + + /* read a 30 byte sector label for each sector on track */ + /* for 16 sectors per track, that is 480 bytes */ + /* for 20 sectors per track, that is 600 bytes */ + for (j=0; jCHS, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = hsdpsec2star(tstart, type); + + cyl = (uptr->CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (uptr->CHS >> 8) & 0xff; /* get the track */ + sec = uptr->CHS & 0xff; /* get sec */ + seeksec = tstart; /* save sector number */ + + sim_debug(DEBUG_EXP, dptr, "hsdp_srv RSL cyl %04x trk %02x sec %02x sector# %06x\n", + cyl, trk, sec, seeksec); + + /* seek sector label area after end of track label area */ + tstart = CAPB(type) + (CYL(type)*HDS(type)*30) + (tstart*30); + + /* file offset in bytes to sector label */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv RSL SEEK on seek to %08x\n", tstart); + + /* seek to the location where we will read sector label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, + "Error seeking sector label area at sect %06x offset %08x\n", + seeksec, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + + /* read in a sector label from disk */ + if (sim_fread(buf, 1, 30, uptr->fileref) != 30) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + + sim_debug(DEBUG_CMD, dptr, "Sector %x label", uptr->CHS); + /* now write sector label data */ + for (i = 0; i < 30; i++) { + if (chan_write_byte(chsa, &buf[i])) { + /* we have write error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + if (i == 16) + sim_debug(DEBUG_CMD, dptr, "\nSector %x label", uptr->CHS); + sim_debug(DEBUG_CMD, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_CMD, dptr, "\n"); + + /* leave STAR "unnormalized" for diags */ + uptr->CHS++; /* bump to next track */ + if ((uptr->CHS & 0xff) == SPC(type)) + break; /* stop at last sector */ + len -= 30; /* count 1 sector label size */ + if (len > 0) + continue; + break; /* done */ + } + + uptr->CHS = mema; /* restore address */ + + sim_debug(DEBUG_CMD, dptr, "after RSL Sector %x len %x\n", uptr->CHS, chp->ccw_count); + + /* command done */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv cmd RSL done chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_WTF: /* 0x41 Write track format */ + case DSK_WSL: /* WSL 0x31 */ + len = chp->ccw_count; /* get number bytes to read */ + mema = uptr->CHS; /* save address */ + + sim_debug(DEBUG_CMD, dptr, "before WSL/WTF Sector %x len %x\n", uptr->CHS, len); + + /* read a 30 byte sector label for each sector on track */ + /* for 16 sectors per track, that is 480 bytes */ + /* for 20 sectors per track, that is 600 bytes */ + for (j=0; jCHS); + /* now read sector label data */ + for (i = 0; i < 30; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have read error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + if ((i%16) == 0) + sim_debug(DEBUG_CMD, dptr, "\nSector %x label", uptr->CHS); + sim_debug(DEBUG_CMD, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_CMD, dptr, "\n"); + + /* see if user trying to set invalid bit pattern */ + if ((buf[4] & 0x48) == 0x48) { /* see if setting defective alternate trk */ + uptr->SNS |= SNS_DSKFERR; /* disk formating error */ + uptr->CHS = mema; /* restore address */ + chp->ccw_count = len; /* restore number bytes to read */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + return SCPE_OK; + break; + } + + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = hsdpsec2star(tstart, type); + + cyl = (uptr->CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (uptr->CHS >> 8) & 0xff; /* get the track */ + sec = uptr->CHS & 0xff; /* get sec */ + seeksec = tstart; /* save sector number */ + + sim_debug(DEBUG_EXP, dptr, "hsdp_srv WSL/WTF cyl %04x trk %02x sec %02x sector# %06x\n", + cyl, trk, sec, seeksec); + + /* seek sector label area after end of track label area */ + tstart = CAPB(type) + (CYL(type)*HDS(type)*30) + (tstart*30); + + /* file offset in bytes to sector label */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv WSL/WTF SEEK on seek to %08x\n", tstart); + + /* seek to the location where we will write sector label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, + "Error seeking sector label area at sect %06x offset %08x\n", + seeksec, tstart); + uptr->CHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + + /* write sector label to disk */ + if (sim_fwrite(buf, 1, 30, uptr->fileref) != 30) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on write %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + + /* leave STAR "unnormalized" for diags */ + uptr->CHS++; /* bump to next sector */ + if ((uptr->CHS & 0xff) == SPC(type)) + break; /* stop at last sector */ + len -= 30; /* count 1 sector label size */ + if (len > 0) + continue; + break; /* done */ + } + + uptr->CHS = mema; /* restore address */ + + sim_debug(DEBUG_CMD, dptr, "after WSL/WTF Sector %x len %x\n", uptr->CHS, chp->ccw_count); + + /* command done */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv cmd WSL/WTF done chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_RVL: /* 0x42 Read vendor label */ + /* Read track label to get defect information */ + /* write 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + + mema = uptr->CHS & 0xffffff00; /* zero sector for trk read */ + + /* get file offset in sectors */ + tstart = STAR2SEC(mema, SPT(type), SPC(type)); + + /* convert sector number back to chs value to sync disk for diags */ + mema = hsdpsec2star(tstart, type); + cyl = (mema >> 16) & 0xffff; /* get the cylinder */ + trk = (mema >> 8) & 0xff; /* get the track */ + + /* get track number */ + tstart = (cyl * HDS(type)) + trk; + sim_debug(DEBUG_EXP, dptr, "hsdp_srv RVL cyl %4x(%d) trk %x sec# %06x\n", + cyl, cyl, trk, tstart); + + /* calc offset in file to track label */ + tstart = CAPB(type) + (tstart * 30); + + /* file offset in bytes */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv RVL SEEK on seek to %06x\n", tstart); + + /* seek to the location where we will r/w track label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv RVL, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* read in a track label from disk */ + if ((len=sim_fread(buf, 1, 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* clear out area for bad sector errors to show no errors on track */ + /* error info in bytes 10-24 */ + for (i=10; i<25; i++) + buf[i] = 0; + + if (buf[4] == 0x08) { /* see if defective track */ + uptr->SNS |= SNS_DEFTRK; /* flag as defective */ + sim_debug(DEBUG_CMD, dptr, "Track %08x is defective\n", uptr->CHS); + } + + if (buf[4] == 0x40) { /* see if alternate track */ + uptr->SNS |= SNS_AATT; /* flag as alternate */ + sim_debug(DEBUG_CMD, dptr, "Track %08x is alternate\n", uptr->CHS); + } + + /* now write track label data to memory */ + sim_debug(DEBUG_CMD, dptr, "Track %08x label", uptr->CHS); + for (i = 0; i < 30; i++) { + if (chan_write_byte(chsa, &buf[i])) { + /* we have write error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (i == 16) + sim_debug(DEBUG_CMD, dptr, "\nTrack %08x label", uptr->CHS); + sim_debug(DEBUG_CMD, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_CMD, dptr, "\n"); + + /* command done */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv cmd RVL done chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + + case DSK_RTL: /* RTL 0x52 */ + /* Read track zero to get disk geometry */ + /* write 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + + /* zero the Track Label Buffer */ + for (i = 0; i < 30; i++) + buf[i] = 0; + + uptr->CHS &= 0xffffff00; /* zero sector for trk read */ + mema = uptr->CHS; + + /* get file offset in sectors */ + tstart = STAR2SEC(mema, SPT(type), SPC(type)); + + /* convert sector number back to chs value to sync disk for diags */ + mema = hsdpsec2star(tstart, type); + cyl = (mema >> 16) & 0xffff; /* get the cylinder */ + trk = (mema >> 8) & 0xff; /* get the track */ + + /* get track number */ + tstart = (cyl * HDS(type)) + trk; + sim_debug(DEBUG_EXP, dptr, "hsdp_srv RTL cyl %4x(%d) trk %x sec# %06x\n", + cyl, cyl, trk, tstart); + + /* calc offset in file to track label */ + tstart = CAPB(type) + (tstart * 30); + + /* file offset in bytes */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv RTL SEEK on seek to %06x\n", tstart); + + /* seek to the location where we will r/w track label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv RTL, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* read in a track label from disk */ + if ((len=sim_fread(buf, 1, 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + if (buf[4] == 0x08) { /* see if defective track */ + uptr->SNS |= SNS_DEFTRK; /* flag as defective */ + sim_debug(DEBUG_CMD, dptr, "Track %08x is defective\n", uptr->CHS); + } + + if (buf[4] == 0x40) { /* see if alternate track */ + uptr->SNS |= SNS_AATT; /* flag as alternate */ + sim_debug(DEBUG_CMD, dptr, "Track %08x is alternate\n", uptr->CHS); + } + + /* now write track label data to memory */ + sim_debug(DEBUG_CMD, dptr, "Track %08x label", uptr->CHS); + for (i = 0; i < 30; i++) { + if (chan_write_byte(chsa, &buf[i])) { + /* we have write error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (i == 16) + sim_debug(DEBUG_CMD, dptr, "\nTrack %08x label", uptr->CHS); + sim_debug(DEBUG_CMD, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_CMD, dptr, "\n"); + + /* see if we are operating in sector replacement mode */ + /* if specified sector count will be 1 less than physical sector count */ + if (uptr->CHS == 0) /* see if trk 0 label read */ + uptr->LSC = buf[25]; /* save logical sector count from label */ + /* command done */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv cmd RTL done LSC %02x chsa %04x count %04x completed\n", + uptr->LSC, chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_WTL: /* WTL 0x51 */ + /* Write track zero to set disk geometry */ + /* write 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + + sim_debug(DEBUG_EXP, dptr, "hsdp_srv WTL start cnt %04x CHS %08x\n", + chp->ccw_count, uptr->CHS); + + /* get file offset in sectors */ + tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + uptr->CHS = hsdpsec2star(tstart, type); + uptr->CHS &= 0xffffff00; /* zero sector for trk read */ + mema = uptr->CHS; + + cyl = (uptr->CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (uptr->CHS >> 8) & 0xff; /* get the track */ + + /* get track number */ + tstart = (cyl * HDS(type)) + trk; + sim_debug(DEBUG_EXP, dptr, "hsdp_srv WTL cyl %4x trk %x track# %06x CHS %08x\n", + cyl, trk, tstart, uptr->CHS); + + /* calc offset in file to track label */ + tstart = CAPB(type) + (tstart * 30); + + /* file offset in bytes */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv WTL SEEK on seek to %06x\n", tstart); + + /* seek to the location where we will write track label */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "hsdp_srv WTL, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + sim_debug(DEBUG_EXP, dptr, "Track %08x label", uptr->CHS); + /* now read track label data from memory */ + for (i = 0; i < 30; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have read error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + if (i == 16) + sim_debug(DEBUG_EXP, dptr, "\nTrack %08x label", uptr->CHS); + sim_debug(DEBUG_EXP, dptr, " %02x", buf[i]); + } + sim_debug(DEBUG_EXP, dptr, "\n"); + + /* see if user trying to set invalid bit pattern */ + if ((buf[4] & 0x48) == 0x48) { /* see if setting defective alternate trk */ + uptr->SNS |= SNS_DSKFERR; /* disk formating error */ + uptr->CHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + + /* write out a track label to disk */ + if ((len=sim_fwrite(buf, 1, 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on write %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, 30, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* clear cache entry for this track */ + /* see if track label is in cache */ + for (i=0; iCHS = mema; /* restore address */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv cmd WTL chsa %04x count %04x completed CHS %08x\n", + chsa, chp->ccw_count, uptr->CHS); + + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + default: + sim_debug(DEBUG_CMD, dptr, "invalid command %02x unit %02x\n", cmd, unit); + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|STATUS_PCHK); /* return prog check */ + break; + } + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv done cmd %02x chsa %04x chs %04x/%02x/%02x\n", + cmd, chsa, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + return SCPE_OK; +} + +/* initialize the disk */ +void hsdp_ini(UNIT *uptr, t_bool f) +{ + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); /* get the UNIT number */ + int i = GET_TYPE(uptr->flags); + int cn; + + /* start out at sector 0 */ + uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */ + uptr->CMD &= LMASK; /* clear out the flags but leave ch/sa */ + /* total sectors on disk */ + uptr->capac = CAP(i); /* size in sectors */ + sim_cancel(uptr); /* stop any timer */ + /* reset track label cache */ + for (cn=0; cnname, GET_UADDR(uptr->CMD), uptr->capac, uptr->capac); +} + +/* handle rschnlio cmds for hsdp */ +t_stat hsdp_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & DSK_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, "hsdp_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + hsdp_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +t_stat hsdp_reset(DEVICE *dptr) +{ + int cn, unit; + + for(unit=0; unit < NUM_UNITS_HSDP; unit++) { + for (cn=0; cnflags); + DEVICE *dptr = get_dev(uptr); + uint32 trk, cyl, sec; + uint32 ssize = SSB(type); /* disk sector size in bytes */ + uint32 tsize = SPT(type); /* get track size in sectors */ + uint32 tot_tracks = TRK(type); /* total tracks on disk */ + uint32 tot_sectors = CAP(type); /* total number of sectors on disk */ + uint32 cap = CAP(type); /* disk capacity in sectors */ + uint32 CHS; /* cyl, hds, sec format */ + uint8 label[34]; /* track/sector label */ + int32 i, j; + /* get sector address of vendor defect table VDT */ + /* put data = 0xf0000004 0xf4000000 */ + int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type); + /* get sector address of utx diag map (DMAP) track 0 pointer */ + /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ + /* 0x9a000000 + (cyl-1), 0xf4000000 */ + int32 daddr = (CYL(type)-4) * SPC(type) + (HDS(type)-2) * SPT(type); + /* make logical */ + int32 logda = daddr*(SPT(type)-1)/(SPT(type)); + + /* get sector address of utx flaw map sec 1 pointer */ + /* use this address for sec 1 label pointer */ + int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); + /* make logical */ + int32 logua = uaddr*(SPT(type)-1)/(SPT(type)); + + /* write 30 byte track labels for all tracks on disk */ + /* tot_tracks entries will be created starting at end of disk */ + /* seek first sector after end of disk data */ + if ((sim_fseek(uptr->fileref, CAPB(type), SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, + "Error seeking track label area at sect %06x offset %06x\n", + CAP(type), CAPB(type)); + return 1; + } + /* write track labels */ + for (i=0; i<(int)tot_tracks; i++) { + + /* zero the Track Label Buffer */ + for (j = 0; j < 30; j++) + label[j] = 0; + + sec = i * SPT(type); /* get track address in sectors */ + /* convert sector number to CHS value for label */ + CHS = hsdpsec2star(sec, type); /* get current CHS value */ + + /* set buf data to current CHS values */ + if (CHS == 0) { /* write last address on trk 0 */ + cyl = CYL(type)-1; /* lcyl cyl upper 8 bits */ + trk = HDS(type)-1; /* ltkn trk */ + sec = SPT(type)-1; /* lid sector ID */ + } else { + /* write current address on other tracks */ + cyl = (CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (CHS >> 8) & 0xff; /* get the track */ + sec = (CHS) & 0xff; /* get the sector */ + } + + sim_debug(DEBUG_CMD, dptr, "hsdp_label WTL STAR %08x disk geom %08x\n", + CHS, GEOM(type)); + + /* set buf data to current STAR values */ + label[0] = (cyl >> 8) & 0xff; /* lcyl cyl upper 8 bits */ + label[1] = cyl & 0xff; /* lcyl cyl lower 8 bits */ + label[2] = trk & 0xff; /* ltkn trk */ + label[3] = sec & 0xff; /* lid sector ID */ + label[4] = 0x80; /* show good sector */ + if (i == (tot_tracks-1)) { /* last track? */ + label[3] = 0xff; /* lid show as last track label */ + label[4] |= 0x04; /* set last track flag */ + } + + sim_debug(DEBUG_CMD, dptr, + "hsdp_label WTL star %02x %02x %02x %02x\n", + label[0], label[1], label[2], label[3]); + + /* prepare track 0 label on disk */ + if (CHS == 0) { /* only write dmap address in trk 0 */ + /* daddr has dmap value for track zero label */ + /* this logical or physical address must be there, */ + /* otherwise prep crashes with bad diag flaw map pointer */ + if (use_strep) { + /* output logical diag defect map address of disk */ + label[12] = (logda >> 24) & 0xff; /* ldeallp DMAP pointer */ + label[13] = (logda >> 16) & 0xff; + label[14] = (logda >> 8) & 0xff; + label[15] = (logda) & 0xff; + printf("hsdp_label WTL logda@daddr %08x -> %08x\r\n", logda, 0); + sim_debug(DEBUG_CMD, dptr, + "hsdp_label WTL logda@daddr %08x -> %08x\n", logda, 0); + } else { + /* output physical diag defect map address of disk */ + label[12] = (daddr >> 24) & 0xff; /* ldeallp DMAP pointer */ + label[13] = (daddr >> 16) & 0xff; + label[14] = (daddr >> 8) & 0xff; + label[15] = (daddr) & 0xff; + printf("hsdp_label WTL daddr@daddr %08x -> %08x\r\n", daddr, 0); + sim_debug(DEBUG_CMD, dptr, + "hsdp_label WTL daddr@daddr %08x -> %08x\n", vaddr, 0); + } + /* if this is removed, UTX is unable to create newfs */ + /* get preposterous size 0 error message */ + /* address must be logical/physical */ + /* uaddr has umap value for track zero label */ + if (use_strep) { + /* output logical umap address */ + label[16] = (logua >> 24) & 0xff; /* lumapp UMAP lofical pointer */ + label[17] = (logua >> 16) & 0xff; + label[18] = (logua >> 8) & 0xff; + label[19] = (logua) & 0xff; + } else { + /* output physical umap address */ + label[16] = (uaddr >> 24) & 0xff; /* lumapp UMAP physical pointer */ + label[17] = (uaddr >> 16) & 0xff; + label[18] = (uaddr >> 8) & 0xff; + label[19] = (uaddr) & 0xff; + } + } + + /* write vaddr to track label for dmap */ + if ((i*SPT(type)) == daddr) { /* get track address in sectors */ + /* output physical vendor defect map address of disk */ + label[12] = (vaddr >> 24) & 0xff; /* Vaddr pointer vdt */ + label[13] = (vaddr >> 16) & 0xff; + label[14] = (vaddr >> 8) & 0xff; + label[15] = (vaddr) & 0xff; + printf("hsdp_label WTL vaddr@vaddr %08x -> %08x\r\n", vaddr, vaddr); + sim_debug(DEBUG_CMD, dptr, + "hsdp_label WTL vaddr@vaddr %08x -> %08x\n", vaddr, vaddr); + } + + /* the tech doc shows the cyl/trk/sec data is in the first 4 bytes */ + /* of the track label, BUT it is really in the configuration data */ + /* area too. Byte 27 is sectors/track and byte 28 is number of heads. */ + /* Byte 26 is mode. Byte 25 is copy of byte 27. */ + label[25] = SPT(type) & 0xff; /* save sectors per track */ + if ((use_strep) && (i == 0)) { + label[25] = (SPT(type)-1) & 0xff; + } + uptr->LSC = label[25]; /* save logical/physical sector count from label */ + label[26] = hsdp_type[type].type & 0xfd; /* zero bits 6 in type byte */ + label[27] = label[25]; /* same as label[25] */ + label[28] = HDS(type) & 0xff; + + if ((sim_fwrite((char *)&label, sizeof(uint8), 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_CMD, dptr, + "Error writing track label to sect %06x offset %06x\n", + cap+(i*tsize), cap*ssize+(i*tsize*ssize)); + return 1; + } + } + + /* write 30 byte sector labels for all sectors on disk */ + /* tot_sector entries will be created starting at end of disk */ + /* plus the track label area size. seek first sector after end */ + /* of disk track label area */ + if ((sim_fseek(uptr->fileref, CAPB(type)+TRK(type)*30, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, + "Error seeking sector label area at sect %06x offset %06x\n", + CAP(type)+TRK(type), CAPB(type)+TRK(type)*30); + return 1; + } + + /* zero the Sector Label Buffer */ + for (j = 0; j < 30; j++) + label[j] = 0; + + /* convert sector number to CHS value for label */ + /* write sector labels */ + for (i=0; i<(int)tot_sectors; i++) { + + CHS = hsdpsec2star(i, type); /* get current CHS value */ + + /* set buf data to current CHS values */ + /* write current address on other tracks */ + cyl = (CHS >> 16) & 0xffff; /* get the cylinder */ + trk = (CHS >> 8) & 0xff; /* get the track */ + sec = (CHS) & 0xff; /* get the sector */ + + sim_debug(DEBUG_CMD, dptr, "hsdp_label WSL STAR %08x disk geom %08x\n", + CHS, GEOM(type)); + + /* set buf data to current STAR values */ + label[0] = (cyl >> 8) & 0xff; /* lcyl cyl upper 8 bits */ + label[1] = cyl & 0xff; /* lcyl cyl lower 8 bits */ + label[2] = trk & 0xff; /* ltkn trk */ + label[3] = sec & 0xff; /* lid sector ID */ + label[4] = 0x80; /* show good sector */ + + sim_debug(DEBUG_CMD, dptr, + "hsdp_label WSL star %02x %02x %02x %02x\n", + label[0], label[1], label[2], label[3]); + + label[12] = 0; + label[13] = 0; + label[14] = 0; + label[15] = 0; + label[16] = 0; + label[17] = 0; + label[18] = 0; + label[19] = 0; + + /* if this is written, UTX will not be able to do a newfs */ + /* gets preposterous size 0 error */ + /* the tech doc shows the cyl/trk/sec data is in the first 4 bytes */ + /* of the track label, BUT it is really in the configuration data */ + /* area too. Byte 27 is sectors/track and byte 28 is number of heads. */ + /* Byte 26 is mode. Byte 25 is copy of byte 27. */ + label[25] = hsdp_type[type].spt & 0xff; + /* The UDP/DPII controllers do not use these bits, so UTX keys */ + /* on these bits to determine type of controller. Bit 31 is set */ + /* for a HSDP and not set for the UDP/DPII */ + label[26] = hsdp_type[type].type & 0xfd; /* zero bits 6 & leave 7 in type byte */ + label[27] = hsdp_type[type].spt & 0xff; + label[28] = hsdp_type[type].nhds & 0xff; + + if ((sim_fwrite((char *)&label, sizeof(uint8), 30, uptr->fileref)) != 30) { + sim_debug(DEBUG_CMD, dptr, + "Error writing sector label to sect %06x offset %06x\n", + i, CAPB(type)+TRK(type)*30+i*ssize); + return 1; + } + } + + /* seek home again */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + return SCPE_OK; /* good to go */ +} + +/* create the disk file for the specified device */ +int hsdp_format(UNIT *uptr) { + int type = GET_TYPE(uptr->flags); + DEVICE *dptr = get_dev(uptr); + uint32 ssize = SSB(type); /* disk sector size in bytes */ + uint32 tsize = SPT(type); /* get track size in sectors */ + uint32 csize = SPC(type); /* get cylinder size in sectors */ + uint32 cyl = CYL(type); /* get # cylinders */ + uint32 cap = CAP(type); /* disk capacity in sectors */ + uint32 cylv = cyl; /* number of cylinders */ + uint8 *buff; + int i; + int use_st_format = 1; /* assume we use s/t replacement */ + t_stat oldsw = sim_switches; /* save switches */ + + /* last sector address of disk (cyl * hds * spt) - 1 */ + uint32 laddr = CAP(type) - 1; /* last sector of disk */ + + /* get sector address of vendor defect table VDT */ + /* put data = 0xf0000004 0xf4000000 */ + int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type); + /* get sector address of utx diag map (DMAP) track 0 pointer */ + /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ + /* 0x9a000000 + (cyl-1), 0xf4000000 */ + int32 daddr = (CYL(type)-4) * SPC(type) + (HDS(type)-2) * SPT(type); + /* make logical */ + int32 logda = daddr*(SPT(type)-1)/(SPT(type)); + + int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); + + /* NULL vendor flaw map */ + uint32 vmap[2] = {0xf0000004, 0xf4000000}; + + /* NULL diag flaw map */ + uint32 pdmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr, + 0x9a000000 | (cap-1), 0xf4000000}; + + uint32 dmap[4] = {0xf0000000 | (((cap-1)*(SPT(type)-1))/(SPT(type))), + 0x8a000000 | logda, + 0x9a000000 | (((cap-1)*(SPT(type)-1))/(SPT(type))), 0xf4000000}; + + /* see if -i or -n specified on attach command */ + if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) { + sim_switches = 0; /* simh tests 'N' & 'Y' switches */ + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { + sim_switches = oldsw; + return 1; + } + } + if (!get_yn("Use Sector/Track replacement format? [N] ", FALSE)) { + use_st_format = 0; /* do not use s/t replacement */ + } + sim_switches = oldsw; /* restore switches */ + + /* get physical sector address of media defect table */ + /* VDT 286965 (819/9/0) 0x460f5 for 8887 - 823/10/35 */ + /* MDT 286930 (819/8/0) 0x460d2 for 8887 - 823/10/35 Trk 0 ptr */ + /* FMAP 286895 (819/7/0) 0x460af for 8887 - 823/10/35 */ + /* UMAP 286860 (819/6/0) 0x4608c for 8887 - 823/10/35 */ + + /* get logical sector address of media defect table */ + /* VDT 278766 (819/9/0) 0x440ee for 8887 - 823/10/34 */ + /* MDT 278732 (819/8/0) 0x440cc for 8887 - 823/10/34 */ + /* FMAP 278698 (819/7/0) 0x440aa for 8887 - 823/10/34 Sec 0 ptr */ + /* UMAP 278664 (819/6/0) 0x44088 for 8887 - 823/10/34 Sec 0 ptr */ + + /* seek to sector 0 */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + + /* get buffer for track data in bytes */ + if ((buff = (uint8 *)calloc(csize*ssize, sizeof(uint8))) == 0) { + detach_unit(uptr); + return SCPE_ARG; + } + sim_debug(DEBUG_CMD, dptr, + "Creating disk file of trk size %04x bytes, capacity %d\n", + tsize*ssize, cap*ssize); + + /* write zeros to each track of the disk */ + for (cyl = 0; cyl < cylv; cyl++) { + if ((sim_fwrite(buff, 1, csize*ssize, uptr->fileref)) != csize*ssize) { + sim_debug(DEBUG_CMD, dptr, + "Error on write to diskfile cyl %04x\n", cyl); + free(buff); /* free cylinder buffer */ + buff = NULL; + return 1; + } + if ((cyl % 100) == 0) + fputc('.', stderr); + } + fputc('\r', stderr); + fputc('\n', stderr); + free(buff); /* free cylinder buffer */ + buff = NULL; + + /* byte swap the buffers for dmap and umap */ + for (i=0; i<2; i++) { + vmap[i] = (((vmap[i] & 0xff) << 24) | ((vmap[i] & 0xff00) << 8) | + ((vmap[i] & 0xff0000) >> 8) | ((vmap[i] >> 24) & 0xff)); + } + for (i=0; i<4; i++) { + dmap[i] = (((dmap[i] & 0xff) << 24) | ((dmap[i] & 0xff00) << 8) | + ((dmap[i] & 0xff0000) >> 8) | ((dmap[i] >> 24) & 0xff)); + } + for (i=0; i<4; i++) { + pdmap[i] = (((pdmap[i] & 0xff) << 24) | ((pdmap[i] & 0xff00) << 8) | + ((pdmap[i] & 0xff0000) >> 8) | ((pdmap[i] >> 24) & 0xff)); + } + + /* now seek to end of disk and write the dmap data */ + /* setup dmap pointed to by track label 0 wd[3] = (cyl-4) * spt + (spt - 1) */ + + /* write dmap data to last sector on disk */ + if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */ + sim_debug(DEBUG_CMD, dptr, + "Error on last sector seek to sect %06x offset %06x\n", + cap-1, (cap-1)*ssize); + return 1; + } + if ((sim_fwrite((char *)&pdmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Error writing DMAP to sect %06x offset %06x\n", + cap-1, (cap-1)*ssize); + return 1; + } + + /* seek to vendor label area VMAP */ + if ((sim_fseek(uptr->fileref, vaddr*ssize, SEEK_SET)) != 0) { /* seek VMAP */ + sim_debug(DEBUG_CMD, dptr, + "Error on vendor map seek to sect %06x offset %06x\n", + vaddr, vaddr*ssize); + return 1; + } + if ((sim_fwrite((char *)&vmap, sizeof(uint32), 2, uptr->fileref)) != 2) { + sim_debug(DEBUG_CMD, dptr, + "Error writing VMAP to sect %06x offset %06x\n", + vaddr, vaddr*ssize); + return 1; + } + + /* write DMAP to daddr that is the address in trk 0 label */ + if ((sim_fseek(uptr->fileref, daddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */ + sim_debug(DEBUG_CMD, dptr, + "Error on diag map seek to sect %06x offset %06x\n", + daddr, daddr*ssize); + return 1; + } + if (use_st_format) { + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Error writing LDMAP to sect %06x offset %06x\n", + daddr, daddr*ssize); + return 1; + } + } else + { + if ((sim_fwrite((char *)&pdmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Error writing DMAP to sect %06x offset %06x\n", + daddr, daddr*ssize); + return 1; + } + } + printf("Disk %s has %x (%d) cyl, %x (%d) hds, %x (%d) sec\r\n", + hsdp_type[type].name, CYL(type), CYL(type), HDS(type), HDS(type), + SPT(type), SPT(type)); + printf("writing to vmap sec %x (%d) bytes %x (%d)\r\n", + vaddr, vaddr, (vaddr)*ssize, (vaddr)*ssize); + printf("writing to dmap %x (%d) %x (%d) dmap to %x (%d) %x (%d)\r\n", + cap-1, cap-1, (cap-1)*ssize, (cap-1)*ssize, + daddr, daddr, daddr*ssize, daddr*ssize); + printf("writing to umap sec %x (%d) bytes %x (%d)\r\n", + uaddr, uaddr, (uaddr)*ssize, (uaddr)*ssize); + + /* create labels for disk */ + i = hsdp_label(uptr, use_st_format); /* label disk */ + + /* seek home again */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + return SCPE_OK; +} + +/* attach the selected file to the disk */ +t_stat hsdp_attach(UNIT *uptr, CONST char *file) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + int type = GET_TYPE(uptr->flags); + DEVICE *dptr = get_dev(uptr); + DIB *dibp = 0; + t_stat r, s; + uint32 ssize; /* sector size in bytes */ + uint32 info, good; + uint8 buff[1024]; + int i, j; + int use_st_format = 0; + + /* last sector address of disk (cyl * hds * spt) - 1 */ + int32 laddr = CAP(type) - 1; /* last sector of disk */ + /* get sector address of utx diag map (DMAP) track 0 pointer */ + /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ + /* 0x9a000000 + (cyl-1), 0xf4000000 */ + int32 daddr = (CYL(type)-4) * SPC(type) + (HDS(type)-2) * SPT(type); + int32 umapaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); + /* defect map */ + uint32 dmap[4] = {0xf0000000 | (CAP(type)-1), 0x8a000000 | daddr, + 0x9a000000 | (CAP(type)-1), 0xf4000000}; + + for (i=0; i<4; i++) { /* byte swap data for last sector */ + dmap[i] = (((dmap[i] & 0xff) << 24) | ((dmap[i] & 0xff00) << 8) | + ((dmap[i] & 0xff0000) >> 8) | ((dmap[i] >> 24) & 0xff)); + } + + /* see if valid disk entry */ + if (hsdp_type[type].name == 0) { /* does the assigned disk have a name */ + detach_unit(uptr); /* no, reject */ + return SCPE_FMT; /* error */ + } + + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, + "ERROR===ERROR\nHSDP device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nHSDP device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + /* have simulator attach the file to the unit */ + if ((r = attach_unit(uptr, file)) != SCPE_OK) + return r; + + uptr->capac = CAP(type); /* size in sectors */ + ssize = SSB(type); /* disk sector size in bytes */ + for (i=0; i<(int)ssize; i++) + buff[i] = 0; /* zero the buffer */ + + sim_debug(DEBUG_CMD, dptr, + "Disk %s cyl %d hds %d sec %d ssiz %d capacity %d\n", + hsdp_type[type].name, hsdp_type[type].cyl, hsdp_type[type].nhds, + hsdp_type[type].spt, ssize, uptr->capac); /* hsdp capacity */ + + printf("Disk %s cyl %d hds %d sec %d ssiz %d capacity %d\r\n", + hsdp_type[type].name, hsdp_type[type].cyl, hsdp_type[type].nhds, + hsdp_type[type].spt, ssize, uptr->capac); /* hsdp capacity */ + + /* see if -i or -n specified on attach command */ + if ((sim_switches & SWMASK('N')) || (sim_switches & SWMASK('I'))) { + goto fmt; /* user wants new disk */ + } + + /* seek to end of disk */ + if ((sim_fseek(uptr->fileref, 0, SEEK_END)) != 0) { + sim_debug(DEBUG_CMD, dptr, "HSDP Disk attach SEEK end failed\n"); + printf("Disk attach SEEK end failed\r\n"); + goto fmt; /* not setup, go format */ + } + + s = ftell(uptr->fileref); /* get current file position */ + if (s == 0) { + sim_debug(DEBUG_CMD, dptr, "HSDP Disk attach ftell failed s=%06d\n", s); + printf("HSDP Disk attach ftell failed s=%06d\r\n", s); + goto fmt; /* not setup, go format */ + } + + if (((int)s/(int)ssize) < ((int)CAP(type))) { /* full sized disk? */ + j = (CAP(type) - (s/ssize)); /* get # sectors to write */ + sim_debug(DEBUG_CMD, dptr, + "Disk attach for MPX 1.X needs %04d more sectors added to disk\n", j); + printf("Disk attach for MPX 1.X needs %04d more sectors added to disk\r\n", j); + /* must be MPX 1.X disk, extend to MPX 3.X size */ + /* write sectors of zero to end of disk to fill it out */ + for (i=0; ifileref) != ssize)) { + sim_debug(DEBUG_CMD, dptr, "Disk attach fread ret = %04d\n", r); + printf("Disk attach fread ret = %04d\r\n", r); + goto fmt; /* not setup, go format */ + } + } + s = ftell(uptr->fileref); /* get current file position */ + sim_debug(DEBUG_CMD, dptr, + "Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\n", s/ssize, s); + printf("Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\r\n", s/ssize, s); + } + + /* seek last sector of disk */ + if ((sim_fseek(uptr->fileref, (CAP(type)-1)*ssize, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, "HSDP Disk attach SEEK last sector failed\n"); + printf("HSDP Disk attach SEEK last sector failed\r\n"); + goto fmt; + } + + /* see if there is disk size-1 in last sector of disk, if not add it */ + if ((r = sim_fread(buff, sizeof(uint8), ssize, uptr->fileref) != ssize)) { + sim_debug(DEBUG_CMD, dptr, "HSDP Disk format fread error = %04d\n", r); + printf("HSDP Disk format fread error = %04d\r\n", r); +add_size: + /* write dmap data to last sector on disk for mpx 1.x */ + if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */ + sim_debug(DEBUG_CMD, dptr, + "Disk Error on last sector seek to sect %06d offset %06d bytes\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + printf("Disk Error on last sector seek to sect %06d offset %06d bytes\r\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + goto fmt; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Disk Error writing DMAP to sect %06x offset %06d bytes\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + printf("Disk Error writing DMAP to sect %06x offset %06d bytes\r\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + goto fmt; + } + + /* seek last sector of disk */ + if ((sim_fseek(uptr->fileref, (CAP(type))*ssize, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, "Disk attach SEEK last sector failed\n"); + printf( "Disk attach SEEK last sector failed\r\n"); + goto fmt; + } + s = ftell(uptr->fileref); /* get current file position */ + sim_debug(DEBUG_CMD, dptr, + "HSDP Disk attach MPX file extended & sized secs %06d bytes %06d\n", s/ssize, s); + printf("HSDP Disk attach MPX file extended & sized secs %06d bytes %06d\r\n", s/ssize, s); + goto ldone; + } else { + /* if not disk size, go add it in for MPX, error if UTX */ + if ((buff[0] | buff[1] | buff[2] | buff[3]) == 0) { + sim_debug(DEBUG_CMD, dptr, + "HSDP Disk format0 buf0 %02x buf1 %02x buf2 %02x buf3 %02x\n", + buff[0], buff[1], buff[2], buff[3]); + goto add_size; + } + } + + info = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3]; + good = 0xf0000000 | (CAP(type)-1); + /* check for 0xf0ssssss where ssssss is disk size-1 in sectors */ + if (info != good) { + sim_debug(DEBUG_CMD, dptr, + "Disk format error buf0 %02x buf1 %02x buf2 %02x buf3 %02x\n", + buff[0], buff[1], buff[2], buff[3]); + printf("Disk format error buf0 %02x buf1 %02x buf2 %02x buf3 %02x\r\n", + buff[0], buff[1], buff[2], buff[3]); +fmt: + /* format the drive */ + if (hsdp_format(uptr)) { + detach_unit(uptr); /* if no space, error */ + return SCPE_FMT; /* error */ + } + } + +ldone: + /* see if disk has labels already, seek to sector past end of disk */ + if ((sim_fseek(uptr->fileref, CAP(type)*ssize, SEEK_SET)) != 0) { /* seek end */ + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + i = SCPE_OK; + /* see if disk has labels already, seek to sector past end of disk */ + if ((r = sim_fread(buff, sizeof(uint8), 30, uptr->fileref) != 30)) { + use_st_format = 1; + /* the disk does not have labels, add them on */ + /* create labels for disk */ + sim_debug(DEBUG_CMD, dptr, + "File %s attached to %s creating labels\n", + file, hsdp_type[type].name); + printf("File %s attached to %s creating labels\r\n", + file, hsdp_type[type].name); + if (!get_yn("Use Sector/Track replacement format for labels? [Y] ", TRUE)) { + use_st_format = 0; + } + /* create labels for disk */ + i = hsdp_label(uptr, use_st_format); /* label disk */ + if (i != 0) { + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + } + + /* see if disk has labels already, seek to sector past end of disk */ + if ((sim_fseek(uptr->fileref, CAP(type)*ssize, SEEK_SET)) != 0) { /* seek end */ + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + /* see if disk has labels already, read label for track 0 */ + if ((r = sim_fread(buff, sizeof(uint8), 30, uptr->fileref) != 30)) { + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + uptr->LSC = buff[25]; /* save logical sector count from label */ + + /* UTX map (NUMP) does not insert an F4 after the replacement tracks */ + /* so do it after the tracks are defined to stop halt on bootup */ + /* utxmap + 32 + 88 + (3*spare) + 1 */ + /* spare count is at utxmap + 8w (32) */ + /* get umap sector address from umapaddr */ + info = (buff[16]<<24) | (buff[17]<<16) | (buff[18]<<8) | buff[19]; + daddr = umapaddr * ssize; /* byte offset in file */ + if ((sim_fseek(uptr->fileref, umapaddr*ssize, SEEK_SET)) != 0) { /* seek umap */ + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + /* read umap into buff */ + if ((r = sim_fread(buff, sizeof(uint8), ssize, uptr->fileref) != ssize)) { + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + info = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3]; + good = 0x4e554d50; /* NUMP */ + if (info == good) { + /* we have a UTX umap, so fixup the data */ + if (buff[35] <= SPT(type)) + i = (127) + (buff[35]*12); /* byte offset to where to put 0xf4 */ + else + i = 127; /* only 1 track of replacement */ + buff[i] = 0xf4; /* set stop for UTX search */ + if ((sim_fseek(uptr->fileref, umapaddr*ssize, SEEK_SET)) != 0) { /* seek umap */ + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + if ((r = sim_fwrite(buff, sizeof(uint8), ssize, uptr->fileref) != ssize)) { + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + } + + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + + /* start out at sector 0 */ + uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */ + + if (uptr->LSC == SPT(type)) { + /* physical sectoring */ + sim_debug(DEBUG_CMD, dptr, + "HSDP PHY %02x Attach %s cyl %d hds %d pspt %d pspc %d cap sec %d cap bytes %d\n", + uptr->LSC, hsdp_type[type].name, CYL(type), HDS(type), SPT(type), SPC(type), + CAP(type), CAPB(type)); + printf("HSDP PHY %02x Attach %s cyl %d hds %d pspt %d pspc %d cap sec %d cap bytes %d\r\n", + uptr->LSC, hsdp_type[type].name, CYL(type), HDS(type), SPT(type), SPC(type), + CAP(type), CAPB(type)); + } else { + /* logical sectoring */ + sim_debug(DEBUG_CMD, dptr, + "HSDP LSF %02x Attach %s cyl %d hds %d lspt %d lspc %d cap sec %d cap bytes %d\n", + uptr->LSC, hsdp_type[type].name, CYL(type), HDS(type), SPT(type)-1, (SPT(type)-1)*HDS(type), + (CYL(type)*HDS(type)*(SPT(type)-1)), (CYL(type)*HDS(type)*(SPT(type)-1))*ssize); + printf("HSDP LSF %02x Attach %s cyl %d hds %d lspt %d lspc %d cap sec %d cap bytes %d\r\n", + uptr->LSC, hsdp_type[type].name, CYL(type), HDS(type), SPT(type)-1, (SPT(type)-1)*HDS(type), + (CYL(type)*HDS(type)*(SPT(type)-1)), (CYL(type)*HDS(type)*(SPT(type)-1))*ssize); + } + + sim_debug(DEBUG_CMD, dptr, + "HSDP File %s attached to %s\n", + file, hsdp_type[type].name); + printf("HSDP File %s attached to %s\r\n", + file, hsdp_type[type].name); + + /* check for valid configured disk */ + /* must have valid DIB and Channel Program pointer */ + dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */ + if ((dib_unit[chsa] == NULL) || (dibp == NULL) || (chp == NULL)) { + sim_debug(DEBUG_CMD, dptr, + "ERROR===ERROR\nHSDP device %s not configured on system, aborting\n", + dptr->name); + printf("ERROR===ERROR\nHSDP device %s not configured on system, aborting\r\n", + dptr->name); + detach_unit(uptr); /* detach if error */ + return SCPE_UNATT; /* error */ + } + set_devattn(chsa, SNS_DEVEND); + return SCPE_OK; +} + +/* detach a disk device */ +t_stat hsdp_detach(UNIT *uptr) { + uptr->SNS = 0; /* clear sense data */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + return detach_unit(uptr); /* tell simh we are done with disk */ +} + +/* boot from the specified disk unit */ +t_stat hsdp_boot(int32 unit_num, DEVICE * dptr) { + UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */ + + sim_debug(DEBUG_CMD, dptr, "HSDP Boot dev/unit %x\n", GET_UADDR(uptr->CMD)); + + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nHSDP device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + if ((uptr->flags & UNIT_ATT) == 0) { + sim_debug(DEBUG_EXP, dptr, "HSDP Boot attach error dev/unit %04x\n", + GET_UADDR(uptr->CMD)); + printf("HSDP Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + return SCPE_UNATT; /* attached? */ + } + SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ + SPAD[0xf8] = 0xF000; /* show as F class device */ + + /* now boot the disk */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + return chan_boot(GET_UADDR(uptr->CMD), dptr); /* boot the ch/sa */ +} + +/* Disk option setting commands */ +/* set the disk type attached to unit */ +t_stat hsdp_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int i; + + if (cptr == NULL) /* any disk name input? */ + return SCPE_ARG; /* arg error */ + if (uptr == NULL) /* valid unit? */ + return SCPE_IERR; /* no, error */ + if (uptr->flags & UNIT_ATT) /* is unit attached? */ + return SCPE_ALATT; /* no, error */ + + /* now loop through the units and find named disk */ + for (i = 0; hsdp_type[i].name != 0; i++) { + if (strcmp(hsdp_type[i].name, cptr) == 0) { + uptr->flags &= ~UNIT_TYPE; /* clear old type */ + uptr->flags |= SET_TYPE(i); /* set new type */ + /* set capacity of disk in sectors */ + uptr->capac = CAP(i); + return SCPE_OK; + } + } + return SCPE_ARG; +} + +t_stat hsdp_get_type(FILE *st, UNIT * uptr, int32 v, CONST void *desc) +{ + if (uptr == NULL) + return SCPE_IERR; + fputs("TYPE=", st); + fputs(hsdp_type[GET_TYPE(uptr->flags)].name, st); + return SCPE_OK; +} + +/* help information for disk */ +t_stat hsdp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + int i; + fprintf (st, "SEL 8064 High Speed Disk Processor\r\n"); + fprintf (st, "Use:\r\n"); + fprintf (st, " sim> SET %sn TYPE=type\r\n", dptr->name); + fprintf (st, "Type can be: "); + for (i = 0; hsdp_type[i].name != 0; i++) { + fprintf(st, "%s", hsdp_type[i].name); + if (hsdp_type[i+1].name != 0) + fprintf(st, ", "); + } + fprintf (st, ".\nEach drive has the following storage capacity:\r\n"); + for (i = 0; hsdp_type[i].name != 0; i++) { + int32 size = CAPB(i); /* disk capacity in bytes */ + size /= 1024; /* make KB */ + size = (10 * size) / 1024; /* size in MB * 10 */ + fprintf(st, " %-8s %4d.%1d MB cyl %3d hds %3d sec %3d blk %3d\r\n", + hsdp_type[i].name, size/10, size%10, CYL(i), HDS(i), SPT(i), SSB(i)); + } + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + return SCPE_OK; +} + +const char *hsdp_description (DEVICE *dptr) +{ + return "SEL 8064 High Speed Disk Processor"; +} + +#endif diff --git a/SEL32/sel32_iop.c b/SEL32/sel32_iop.c new file mode 100644 index 00000000..707de588 --- /dev/null +++ b/SEL32/sel32_iop.c @@ -0,0 +1,301 @@ +/* sel32_iop.c: SEL-32 Model 8000/8001/8002 IOP processor controller + + Copyright (c) 2018-2022, James C. Bevier + + 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 + JAMES C. BEVIER 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. + + This channel is the interrupt fielder for all of the IOP sub channels. It's + channel address is 7E00. This code handles the INCH command for the IOP + devices and controls the status FIFO for the iop devices on interrupts and + TIO instructions.. + + Possible devices: + The f8iop communication controller (TY7EA0), (TY7EB0), (TY7EC0) + The ctiop console communications controller (CT7EFC & CT7EFD) + The lpiop line printer controller (LP7EF8), (LP7EF9) + +*/ + +#include "sel32_defs.h" + +#if NUM_DEVS_IOP > 0 + +#define UNIT_IOP UNIT_IDLE | UNIT_DISABLE + +/* forward definitions */ +t_stat iop_preio(UNIT *uptr, uint16 chan); +t_stat iop_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); +void iop_ini(UNIT *uptr, t_bool f); +t_stat iop_rschnlio(UNIT *uptr); +t_stat iop_srv(UNIT *uptr); +t_stat iop_reset(DEVICE *dptr); +t_stat iop_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *iop_desc(DEVICE *dptr); + +/* Held in u3 is the device command and status */ +#define IOP_INCH 0x00 /* Initialize channel command */ +#define IOP_INCH2 0xf0 /* Initialize channel command after start */ +#define IOP_NOP 0x03 /* NOP command */ +#define IOP_MSK 0xff /* Command mask */ + +/* Status held in u3 */ +/* controller/unit address in upper 16 bits */ +#define CON_INPUT 0x100 /* Input ready for unit */ +#define CON_CR 0x200 /* Output at beginning of line */ +#define CON_REQ 0x400 /* Request key pressed */ +#define CON_EKO 0x800 /* Echo input character */ +#define CON_OUTPUT 0x1000 /* Output ready for unit */ +#define CON_READ 0x2000 /* Read mode selected */ + +/* not used u4 */ + +/* in u5 packs sense byte 0,1 and 3 */ +/* Sense byte 0 */ +#define SNS_CMDREJ 0x80000000 /* Command reject */ +#define SNS_INTVENT 0x40000000 /* Unit intervention required */ +/* sense byte 3 */ +#define SNS_RDY 0x80 /* device ready */ +#define SNS_ONLN 0x40 /* device online */ + +/* std devices. data structures + iop_dev Console device descriptor + iop_unit Console unit descriptor + iop_reg Console register list + iop_mod Console modifiers list +*/ + +struct _iop_data +{ + uint8 ibuff[145]; /* Input line buffer */ + uint8 incnt; /* char count */ +} +iop_data[NUM_UNITS_IOP]; + +/* channel program information */ +CHANP iop_chp[NUM_UNITS_IOP] = {0}; + +MTAB iop_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", + &set_dev_addr, &show_dev_addr, NULL, "Controller Channel address"}, + {0} +}; + +UNIT iop_unit[] = { + {UDATA(&iop_srv, UNIT_IOP, 0), 0, UNIT_ADDR(0x7E00)}, /* Channel controller */ +}; + +DIB iop_dib = { + iop_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + iop_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command SIO */ + NULL, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O HIO */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O HIO */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O TIO */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + iop_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + iop_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + iop_unit, /* UNIT* units */ /* Pointer to units structure */ + iop_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_IOP, /* uint8 numunits */ /* number of units defined */ + 0xff, /* uint8 mask */ /* 16 devices - device mask */ + 0x7e00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE iop_dev = { + "IOP", iop_unit, NULL, iop_mod, + NUM_UNITS_IOP, 8, 15, 1, 8, 8, + NULL, NULL, &iop_reset, /* examine, deposit, reset */ + NULL, NULL, NULL, /* boot, attach, detach */ + /* dib ptr, dev flags, debug flags, debug */ + &iop_dib, DEV_CHAN|DEV_DIS|DEV_DISABLE|DEV_DEBUG, 0, dev_debug, +}; + +/* IOP controller routines */ +/* initialize the console chan/unit */ +void iop_ini(UNIT *uptr, t_bool f) +{ + int unit = (uptr - iop_unit); /* unit 0 */ + DEVICE *dptr = &iop_dev; /* one and only dummy device */ + + iop_data[unit].incnt = 0; /* no input data */ + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + sim_cancel(uptr); /* stop any timers */ + sim_debug(DEBUG_CMD, &iop_dev, + "IOP init device %s controller/device %04x\n", + dptr->name, GET_UADDR(uptr->u3)); +} + +/* handle rschnlio cmds for iop */ +t_stat iop_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->u3); + int cmd = uptr->u3 & IOP_MSK; + + sim_debug(DEBUG_EXP, dptr, + "iop_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + iop_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +/* start an iop operation */ +t_stat iop_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + uint16 chsa = GET_UADDR(uptr->u3); + + sim_debug(DEBUG_CMD, dptr, "iop_preio CMD %08x unit %02x chsa %04x\n", + uptr->u3, unit, chsa); + + if ((uptr->u3 & IOP_MSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "iop_preio unit %02x chsa %04x BUSY\n", unit, chsa); + return SNS_BSY; /* yes, return busy */ + } + + sim_debug(DEBUG_CMD, dptr, "iop_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + +/* start an I/O operation */ +t_stat iop_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + sim_debug(DEBUG_CMD, &iop_dev, + "IOP startcmd %02x controller/device %04x\n", + cmd, GET_UADDR(uptr->u3)); + if ((uptr->u3 & IOP_MSK) != 0) /* is unit busy */ + return SNS_BSY; /* yes, return busy */ + + /* process the commands */ + switch (cmd & 0xFF) { + /* UTX uses the INCH cmd to detect the IOP or MFP */ + /* IOP has INCH cmd of 0, while MFP uses 0x80 */ + case IOP_INCH: /* INCH command */ + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + uptr->u3 &= LMASK; /* leave only chsa */ + sim_debug(DEBUG_CMD, &iop_dev, + "iop_startcmd %04x: Cmd INCH iptr %06x INCHa %06x\n", + chan, iop_chp[0].ccw_addr, /* set inch buffer addr */ + iop_chp[0].chan_inch_addr); /* set inch buffer addr */ + + iop_chp[0].chan_inch_addr = iop_chp[0].ccw_addr; /* set inch buffer addr */ + iop_chp[0].base_inch_addr = iop_chp[0].ccw_addr; /* set inch buffer addr */ + iop_chp[0].max_inch_addr = iop_chp[0].ccw_addr + (128 * 8); /* set last inch buffer addr */ + + uptr->u3 |= IOP_INCH2; /* save INCH command as 0xf0 */ + sim_activate(uptr, 40); /* go on */ + return 0; /* no status change */ + break; + + case IOP_NOP: /* NOP command */ + sim_debug(DEBUG_CMD, &iop_dev, "iop_startcmd %04x: Cmd NOP\n", chan); + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + uptr->u3 &= LMASK; /* leave only chsa */ + uptr->u3 |= (cmd & IOP_MSK); /* save NOP command */ + sim_activate(uptr, 40); /* TRY 07-13-19 */ + return 0; /* no status change */ + break; + + default: /* invalid command */ + uptr->u5 |= SNS_CMDREJ; /* command rejected */ + sim_debug(DEBUG_CMD, &iop_dev, "iop_startcmd %04x: Cmd Invalid %02x status %02x\n", + chan, cmd, uptr->u5); + uptr->u3 &= LMASK; /* leave only chsa */ + uptr->u3 |= (cmd & IOP_MSK); /* save command */ + sim_activate(uptr, 40); /* force interrupt */ + return 0; /* no status change */ + break; + } + + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* not reachable for now */ +} + +/* Handle transfers for other sub-channels on IOP */ +t_stat iop_srv(UNIT *uptr) +{ + uint16 chsa = GET_UADDR(uptr->u3); + int cmd = uptr->u3 & IOP_MSK; + CHANP *chp = &iop_chp[0]; /* find the chanp pointer */ + uint32 mema = chp->ccw_addr; /* get inch or buffer addr */ + uint32 tstart; + + /* test for NOP or INCH cmds */ + if ((cmd != IOP_NOP) && (cmd != IOP_INCH2)) { /* NOP or INCH */ + uptr->u3 &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &iop_dev, + "iop_srv Unknown cmd %02x chan %02x: chnend|devend|unitexp\n", cmd, chsa); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* done */ + return SCPE_OK; + } else + + if (cmd == IOP_NOP) { /* NOP do nothing */ + uptr->u3 &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &iop_dev, "iop_srv INCH/NOP chan %02x: chnend|devend\n", chsa); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; + } else + + /* test for INCH cmd */ + if (cmd == IOP_INCH2) { /* INCH */ + sim_debug(DEBUG_CMD, &iop_dev, + "iop_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n", + mema, chsa, chp->ccw_addr, chp->ccw_count); + + /* now call set_inch() function to write and test inch buffer addresses */ + /* the chp->ccw_addr location contains the inch address */ + /* 1-256 wd buffer is provided for 128 status dbl words */ + tstart = set_inch(uptr, mema, 128); /* new address of 128 entries */ + if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->u5 |= SNS_CMDREJ; + uptr->u3 &= LMASK; /* nothing left, command complete */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + uptr->u3 &= LMASK; /* clear the cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + } + return SCPE_OK; +} + +t_stat iop_reset(DEVICE *dptr) +{ + /* add reset code here */ + return SCPE_OK; +} + +/* sho help iop */ +t_stat iop_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr) +{ + fprintf(st, "SEL-32 IOP Model 8000 Channel Controller at 0x7E00\r\n"); + fprintf(st, "The IOP fields all interrupts and status posting\r\n"); + fprintf(st, "for each of the controllers on the system.\r\n"); + fprintf(st, "Nothing can be configured for this Channel.\r\n"); + return SCPE_OK; +} + +const char *iop_desc(DEVICE *dptr) +{ + return("SEL-32 IOP Model 8000 Channel Controller @ 0x7E00"); +} + +#endif + diff --git a/SEL32/sel32_lpr.c b/SEL32/sel32_lpr.c new file mode 100644 index 00000000..91ea9345 --- /dev/null +++ b/SEL32/sel32_lpr.c @@ -0,0 +1,677 @@ +/* sel32_lpr.c: SEL32 922x & 924x High Speed Line Printer + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell and other SIMH contributers + + 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 + JAMES C. BEVIER 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. + + This is the standard line printer. + + These units each buffer one record in local memory and signal + ready when the buffer is full or empty. The channel must be + ready to recieve/transmit data when they are activated since + they will transfer their block during chan_cmd. All data is + transmitted as BCD characters. +*/ + +#include "sel32_defs.h" +#include + +/**** COMMANDS TO PRINT BUFFER THEN DO FORMS CONTROL */ +/* +LP.CMD1 DATAW X'01000000' PRINT ONLY - NO FORMS CONTROL +LP.CMD2 DATAW X'05000000' PRINT BUFFER, +LP.CMD3 DATAW X'15000000' PRINT BUFFER, +LP.CMD4 DATAW X'25000000' PRINT BUFFER, +LP.CMD5 DATAW X'35000000' PRINT BUFFER, +LP.CMD6 DATAW X'45000000' PRINT BUFFER, +LP.CMD7 DATAW X'85000000' PRINT BUFFER, , THEN CLEAR BUFFER +* +**** COMMANDS TO DO FORMS CONTROL AND THEN PRINT BUFFER. +**** NOTE: THESE COMMANDS ARE ARRANGED SO THAT BY USING THE INDEX +**** OF THE FORMS CONTROL TABLE AND A OFFSET INTO THIS TABLE +**** YOU CAN GET THE APPROPRIATE COMMAND FOR THE FC CHAR. +* +LP.CMD8 DATAW X'0D000000' , PRINT BUFFER, +LP.CMD9 DATAW X'4D000000' , PRINT BUFFER, + DATAW X'4D000000' , PRINT BUFFER, +LP.CMD10 DATAW X'2D000000' , PRINT BUFFER +LP.CMD11 DATAW X'1D000000' , PRINT BUFFER, +LP.CMD12 DATAW X'3D000000' , PRINT, (SPARE) +* +**** COMMANDS THAT DO ONLY FORMS CONTROL (NO PRINTING) +* +LP.CMD13 DATAW X'03000000' +LP.CMD14 DATAW X'47000000' + DATAW X'47000000' +LP.CMD15 DATAW X'27000000' +LP.CMD16 DATAW X'17000000' +LP.CMD17 DATAW X'37000000' (SPARE) +* +** LINE PRINTER FORMS CONTROL TABLE +* +LPFCTBL EQU $ + 2B DATAB C'+' 0x2b FORMS CONTROL FOR CR THEN PRINT + 31 DATAB C'1' 0x31 FORMS CONTROL FOR FF THEN PRINT + 2D DATAB C'-' 0x2d FORMS CONTROL FOR FF THEN PRINT + 30 DATAB C'0' 0x30 FORMS CONTROL FOR 2 LF'S THEN PRINT + 20 DATAB C' ' 0x20 FORMS CONTROL FOR LF THEN PRINT +*/ + +#if NUM_DEVS_LPR > 0 + +#define UNIT_LPR UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE | UNIT_SEQ + +#define CMD u3 +/* u3 holds command and status information */ + +#define LPR_INCH 0x00 /* INCH command */ +/* print buffer then CC commands */ +#define LPR_PBNCC 0x01 /* print only, no forms control */ +#define LPR_PBC 0x05 /* print buffer, then */ +#define LPR_PBL 0x15 /* print buffer, then */ +#define LPR_PBLL 0x25 /* print buffer, then */ +#define LPR_PBLLL 0x35 /* print buffer, then */ +#define LPR_PBF 0x45 /* print buffer, then */ +#define LPR_PBCCB 0x85 /* print buffer, then */ + /* Do CC then print commands then CC */ +#define LPR_CPBC 0x0d /* print buffer */ +#define LPR_LPBC 0x1d /* print buffer */ +#define LPR_LLPBC 0x2d /* print buffer */ +#define LPR_LLLPBC 0x3d /* print buffer */ +#define LPR_FPBC 0x4d /* print buffer */ + /* Do CC only, no print */ +#define LPR_NPC 0x03 /* */ +#define LPR_NPL 0x17 /* */ +#define LPR_NPLL 0x27 /* */ +#define LPR_NPLLL 0x37 /* */ +#define LPR_NPF 0x47 /* */ + +#define LPR_SNS 0x04 /* Sense command */ +#define LPR_CMDMSK 0xff /* Mask command part. */ +#define LPR_FULL 0x100 /* Buffer full (BOF) */ +#define LPR_PRE 0x200 /* Apply pre CC */ +#define LPR_POST 0x400 /* Apply post CC */ + +#define CNT u4 +/* u4 holds current line count */ + +/* channel status bits 13-15 */ +/* 0x0c - normal completion - OK & carriage is not at bottom of form */ +/* 0x0e - Unit check - Sense error present with SNS_PRINTF status */ +/* 0x0d - Unit exception - OK & carriage is at bottom of form */ + +#define SNS u5 +/* in u5 packs sense byte 0,1 and 3 */ +/* Sense byte 0 */ +#define SNS_CMDREJ 0x80000000 /* Command reject + Unit check */ +#define SNS_OPRINTR 0x40000000 /* Operator intervention required */ + /* reason code is in status byte 1 */ +#define SNS_BUSCHK 0x20000000 /* Parity error on bus */ +/* bits 3-7 are unused */ +#define SNS_NU3 0x10000000 /* Not used */ +#define SNS_NU4 0x08000000 /* Not used */ +#define SNS_NU5 0x04000000 /* Not used */ +#define SNS_NU6 0x02000000 /* Not used */ +#define SNS_NU7 0x01000000 /* Not used */ +#define SNS_BOF 0x01000000 /* Not used, temp setting for paper at BOT */ +/* Sense byte 1 */ +#define SNS_DEVVFY 0x00800000 /* Device Verify Interface Cable Disconnected */ + /* plus SNS_OPRINTR */ +#define SNS_DEVPWR 0x00400000 /* Device Powered Off + SNS_OPRINTR */ +#define SNS_DEVCHK 0x00200000 /* Device Check - Not Ready + SNS_OPRINTR */ +#define SNS_OFFLINE 0x00100000 /* Off Line + SNS_OPRINTR */ +#define SNS_NU2 0x00080000 /* Not used */ +#define SNS_NU1 0x00040000 /* Not used */ +#define SNS_BEGOF 0x00020000 /* Beginning of form */ +#define SNS_TOF 0x00010000 /* Top of form on printer */ +/* Sense byte 2-3 have remaining channel cnt of zero */ + +#define CBP u6 +/* u6 hold buffer position */ + +/* std devices. data structures + lpr_dev Line Printer device descriptor + lpr_unit Line Printer unit descriptor + lpr_reg Line Printer register list + lpr_mod Line Printer modifiers list +*/ + +struct _lpr_data +{ + uint8 lbuff[160]; /* Output line buffer */ +}; + +struct _lpr_data lpr_data[NUM_DEVS_LPR]; + +/* forward definitions */ +t_stat lpr_preio(UNIT *uptr, uint16 chan); +t_stat lpr_startcmd(UNIT *, uint16, uint8); +void lpr_ini(UNIT *, t_bool); +t_stat lpr_haltio(UNIT *uptr); +t_stat lpr_rschnlio(UNIT *uptr); +t_stat lpr_srv(UNIT *); +t_stat lpr_reset(DEVICE *); +t_stat lpr_attach(UNIT *, CONST char *); +t_stat lpr_detach(UNIT *); +t_stat lpr_setlpp(UNIT *, int32, CONST char *, void *); +t_stat lpr_getlpp(FILE *, UNIT *, int32, CONST void *); +t_stat lpr_help(FILE *, DEVICE *, UNIT *, int32, const char *); +const char *lpr_description (DEVICE *dptr); + +/* channel program information */ +CHANP lpr_chp[NUM_DEVS_LPR] = {0}; + +MTAB lpr_mod[] = { + {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LINESPERPAGE", "LINESPERPAGE", + &lpr_setlpp, &lpr_getlpp, NULL, "Number of lines per page"}, + {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, + &show_dev_addr, NULL}, + {0} +}; + +UNIT lpr_unit[] = { + {UDATA(&lpr_srv, UNIT_LPR, 66), 300, UNIT_ADDR(0x7EF8)}, /* A */ +#if NUM_DEVS_LPR > 1 + {UDATA(&lpr_srv, UNIT_LPR, 66), 300, UNIT_ADDR(0x7EF9)}, /* B */ +#endif +}; + +/* Device Information Block */ +DIB lpr_dib = { + lpr_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + lpr_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + lpr_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + lpr_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + lpr_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + lpr_unit, /* UNIT* units */ /* Pointer to units structure */ + lpr_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_DEVS_LPR, /* uint8 numunits */ /* number of units defined */ + 0x01, /* uint8 mask */ /* 2 devices - device mask */ + 0x7e00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE lpr_dev = { + "LPR", lpr_unit, NULL, lpr_mod, + NUM_DEVS_LPR, 8, 15, 1, 8, 8, + NULL, NULL, NULL, NULL, &lpr_attach, &lpr_detach, + /* ctxt is the DIB pointer */ + &lpr_dib, DEV_DISABLE|DEV_DEBUG, 0, dev_debug, +// &lpr_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &lpr_help, NULL, NULL, &lpr_description, +}; + +/* initialize the line printer */ +void lpr_ini(UNIT *uptr, t_bool f) { + uptr->CMD &= ~(LPR_CMDMSK); /* zero cmd */ + sim_cancel(uptr); /* stop any timers */ + uptr->SNS = 0; /* no status */ + uptr->CBP = 0; /* start of buffer */ + uptr->CNT = 0; /* restart line count */ +} + +/* handle rschnlio cmds for lpr */ +t_stat lpr_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); /* get device pointer */ + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & LPR_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, + "lpr_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + lpr_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +/* start a line printer operation */ +t_stat lpr_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + uint16 chsa = GET_UADDR(uptr->CMD); + + sim_debug(DEBUG_CMD, dptr, "lpr_preio CMD %08x unit %02x chsa %04x\n", + uptr->CMD, unit, chsa); + if ((uptr->CMD & LPR_CMDMSK) != 0) { /* just return if busy */ + sim_debug(DEBUG_CMD, dptr, + "lpr_preio unit %02x chsa %04x BUSY\n", unit, chsa); + return SNS_BSY; + } + + sim_debug(DEBUG_CMD, dptr, + "lpr_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + +/* start an I/O operation */ +t_stat lpr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + DEVICE *dptr = get_dev(uptr); /* get device pointer */ + + if ((uptr->CMD & LPR_CMDMSK) != 0) { /* unit busy */ + return SNS_BSY; /* yes, busy (already tested) */ + } + + uptr->CMD &= ~(LPR_POST|LPR_PRE); /* set no CC */ + if (((cmd & 0x03) == 0x03) || (cmd & 0x0f) == 0x0d) { + uptr->CMD |= LPR_PRE; /* apply pre CC */ + } + if (((cmd & 0x0f) == 0x05) || (cmd & 0x0f) == 0x0d) { + uptr->CMD |= LPR_POST; /* apply post CC */ + } + sim_debug(DEBUG_CMD, dptr, "lpr_startcmd Cmd %02x\n", cmd); + + /* process the command */ + switch (cmd & LPR_CMDMSK) { + case 0x00: /* INCH command */ + /* the IOP should already have the inch buffer set, so ignore */ + sim_debug(DEBUG_CMD, dptr, "lpr_startcmd %04x: Cmd INCH\n", chan); + return SNS_CHNEND|SNS_DEVEND; /* all is well */ + break; + + /* No CC */ + case 0x01: /* print only, no forms control */ + /* print buffer then CC commands */ + case 0x05: /* print buffer, then */ + case 0x15: /* print buffer, then */ + case 0x25: /* print buffer, then */ + case 0x35: /* print buffer, then */ + case 0x45: /* print buffer, then */ + case 0x85: /* print buffer, then */ + /* Do CC then print commands then CC */ + case 0x0d: /* print buffer */ + case 0x1d: /* print buffer */ + case 0x2d: /* print buffer */ + case 0x3d: /* print buffer */ + case 0x4d: /* print buffer */ + /* Do CC only, no print */ + case 0x03: /* */ + case 0x17: /* */ + case 0x27: /* */ + case 0x37: /* */ + case 0x47: /* */ + + /* process the command */ + sim_debug(DEBUG_CMD, dptr, + "lpr_startcmd %04x: Cmd %02x print\n", chan, cmd&LPR_CMDMSK); + uptr->CMD &= ~(LPR_CMDMSK); /* zero cmd */ + uptr->CMD |= (cmd & LPR_CMDMSK); /* save new command in CMD */ + sim_activate(uptr, 100); /* Start unit off */ + return 0; /* we are good to go */ + + case 0x4: /* Sense Status */ + sim_debug(DEBUG_CMD, dptr, + "lpr_startcmd %04x: Cmd %02x sense\n", chan, cmd&LPR_CMDMSK); + uptr->CMD &= ~(LPR_CMDMSK); /* zero cmd */ + uptr->CMD |= (cmd & LPR_CMDMSK); /* save new command in CMD */ + sim_activate(uptr, 100); /* Start unit off */ + return 0; /* we are good to go */ + + default: /* invalid command */ + sim_debug(DEBUG_EXP, dptr, + "lpr_startcmd %04x: Cmd %02x INVALID\n", chan, cmd&LPR_CMDMSK); + uptr->SNS |= SNS_CMDREJ; + break; + } + if (uptr->SNS & 0xff) + return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; + return SNS_CHNEND|SNS_DEVEND; +} + +/* Handle transfer of data for printer */ +t_stat lpr_srv(UNIT *uptr) { + int chsa = GET_UADDR(uptr->CMD); + int u = (uptr - lpr_unit); + int cmd = (uptr->CMD & 0xff); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + DEVICE *dptr = get_dev(uptr); /* get device pointer */ + + sim_debug(DEBUG_CMD, dptr, + "lpr_srv called chsa %04x cmd %02x CMD %08x addr %06x cnt %04x\n", + chsa, cmd, uptr->CMD, chp->ccw_addr, chp->ccw_count); + + /* using IOP lp status bit assignments */ + if (cmd == 0x04) { /* sense? */ + uint8 ch; /* get current status */ + ch = (uptr->SNS >> 24) & 0xff; /* Get status */ + ch &= ~SNS_BOF; /* remove BOF flag */ + if (chan_write_byte(chsa, &ch)) { /* write byte 0 status to memory */ + sim_debug(DEBUG_CMD, dptr, + "lpr_srv write1 error CMD %08x read %02x SNS %02x ccw_count %02x\n", + uptr->CMD, ch, uptr->SNS, chp->ccw_count); + uptr->CMD &= ~(LPR_CMDMSK); /* clear command */ + uptr->SNS = 0; /* no status */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); /* 4 byte req'd */ + return SCPE_OK; + } + ch = (uptr->SNS >> 16) & 0xff; /* Get status */ + if (chan_write_byte(chsa, &ch)) { /* write the status to memory */ + sim_debug(DEBUG_CMD, dptr, + "lpr_srv write2 error CMD %08x read %02x SNS %02x ccw_count %02x\n", + uptr->CMD, ch, uptr->SNS, chp->ccw_count); + uptr->CMD &= ~(LPR_CMDMSK); /* clear command */ + uptr->SNS = 0; /* no status */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); /* 4 byte req'd */ + return SCPE_OK; + } +#ifdef MPX_WANTS_ONLY_2_BYTES + ch = 0; /* byte 2 is always zero */ + if (chan_write_byte(chsa, &ch)) { /* write the status to memory */ + sim_debug(DEBUG_CMD, dptr, + "lpr_srv write3 error CMD %08x read %02x SNS %02x ccw_count %02x\n", + uptr->CMD, ch, uptr->SNS, chp->ccw_count); + uptr->CMD &= ~(LPR_CMDMSK); /* clear command */ + uptr->SNS = 0; /* no status */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); /* 4 byte req'd */ + return SCPE_OK; + } + ch = 0; /* byte 3 is always zero */ + if (chan_write_byte(chsa, &ch)) { /* write the status to memory */ + sim_debug(DEBUG_CMD, dptr, + "lpr_srv write4 error CMD %08x read %02x SNS %02x ccw_count %02x\n", + uptr->CMD, ch, uptr->SNS, chp->ccw_count); + uptr->CMD &= ~(LPR_CMDMSK); /* clear command */ + uptr->SNS = 0; /* no status */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); /* 4 byte req'd */ + return SCPE_OK; + } +#endif + sim_debug(DEBUG_CMD, dptr, + "lpr_srv sense write CMD %08x read %02x SNS %02x ccw_count %02x\n", + uptr->CMD, ch, uptr->SNS, chp->ccw_count); + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS = 0; /* no status */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */ + return SCPE_OK; + } + + /* NEW_02092022 */ + /* make sure we have a file attached, else give error */ + if ((uptr->flags & UNIT_ATT) == 0) { + uptr->CMD &= LMASK; /* make non-busy */ +// uptr->SNS |= SNS_DEVPWR; /* show powered off */ + uptr->SNS |= SNS_DEVCHK; /* show device check */ +// uptr->SNS |= SNS_OFFLINE; /* show printer offline */ + uptr->SNS |= SNS_OPRINTR; /* operator intervention required */ + sim_debug(DEBUG_CMD, dptr, + "lpr_startcmd Cmd %02x LPR not attached SNS %08x\n", cmd, uptr->SNS); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_CHECK); + return SCPE_OK; + } + + /* process any CC before printing buffer */ + if ((uptr->CMD & LPR_PRE) && (((cmd & 0x03) == 0x03) || + (cmd & 0x0f) == 0x0d)) { + uptr->CMD &= ~LPR_PRE; /* remove pre flag */ + /* we have CC to do */ + switch ((cmd & 0xf0) >> 4) { + case 0: /* (0x0d) */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0d; + break; + case 3: /* */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0a; + uptr->CNT++; /* increment the line count */ + /* drop thru */ + case 2: /* */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0a; + uptr->CNT++; /* increment the line count */ + /* drop thru */ + case 1: /* (0x0a) */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0a; + uptr->CNT++; /* increment the line count */ + break; + case 4: /* (0x0c) */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0d; /* add C/R */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0a; /* add L/F */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0c; /* add FF */ + uptr->CNT = 0; /* restart line count */ + /* set beginning of form and top of form */ + uptr->SNS |= (SNS_TOF|SNS_BEGOF); + break; + } + } + + /* Copy next byte from users buffer */ + while ((uptr->CMD & LPR_FULL) == 0) { /* copy in a char if not full */ + if(chan_read_byte(chsa, &lpr_data[u].lbuff[uptr->CBP])) { + uptr->CMD |= LPR_FULL; /* end of buffer or error */ + break; /* done reading */ + } else { + /* remove nulls */ + if (lpr_data[u].lbuff[uptr->CBP] == '\0') { + lpr_data[u].lbuff[uptr->CBP] = ' '; + } + /* remove backspace */ + if (lpr_data[u].lbuff[uptr->CBP] == 0x8) { + lpr_data[u].lbuff[uptr->CBP] = ' '; + } + uptr->CBP++; /* next buffer loc */ + } + } + + /* remove trailing blanks before we apply trailing carriage control */ + while (uptr->CBP > 0) { + if ((lpr_data[u].lbuff[uptr->CBP-1] == ' ') || + (lpr_data[u].lbuff[uptr->CBP-1] == '\0')) { + uptr->CBP--; + continue; + } + break; + } + + /* process any CC after printing buffer */ + if ((uptr->CMD & LPR_FULL) && (uptr->CMD & LPR_POST) && + ((cmd & 0x0f) == 0x0d)) { + /* we have CC to do */ + uptr->CMD &= ~LPR_POST; /* remove post flag */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0d; /* just a */ + } + + /* process any CC after printing buffer */ + if ((uptr->CMD & LPR_FULL) && (uptr->CMD & LPR_POST) && + ((cmd & 0x0f) == 0x05)) { + /* we have CC to do */ + uptr->CMD &= ~LPR_POST; /* remove post flag */ + switch ((cmd & 0xf0) >> 4) { + case 0: /* (0x0d) */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0d; + break; + case 3: /* */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0a; + uptr->CNT++; /* increment the line count */ + /* drop thru */ + case 2: /* */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0a; + uptr->CNT++; /* increment the line count */ + /* drop thru */ + case 1: /* (0x0a) */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0a; + uptr->CNT++; /* increment the line count */ + break; + case 4: /* (0x0c) */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0d; /* add C/R */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0a; /* add L/F */ + lpr_data[u].lbuff[uptr->CBP++] = 0x0c; /* add FF */ + uptr->CNT = 0; /* restart line count */ + /* set beginning of form and top of form */ + uptr->SNS |= (SNS_TOF|SNS_BEGOF); + break; + } + } + + /* print the line if buffer is full */ + if (uptr->CMD & LPR_FULL || uptr->CBP >= 156) { + lpr_data[u].lbuff[uptr->CBP] = 0x00; /* NULL terminate */ + sim_fwrite(&lpr_data[u].lbuff, 1, uptr->CBP, uptr->fileref); /* Print our buffer */ + sim_debug(DEBUG_DETAIL, dptr, "LPR %d %s\n", uptr->CNT, (char*)&lpr_data[u].lbuff); + uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK); /* clear old status */ + uptr->CBP = 0; /* start at beginning of buffer */ + if ((uint32)uptr->CNT > uptr->capac) { /* see if at max lines/page */ + uptr->CNT = 0; /* yes, restart count */ + uptr->SNS |= SNS_BOF; /* set BOF for SENSE */ + sim_debug(DEBUG_CMD, dptr, "lpr_srv Got BOF\n"); + /* IOP spec says to give unit exception if at BOF */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND|SNS_UNITEXP); /* we are done */ + } else { + uptr->SNS &= ~SNS_BOF; /* reset BOF for SENSE */ + if (uptr->CNT == 0) { + /* set beginning of form and top of form */ + uptr->SNS |= (SNS_TOF|SNS_BEGOF); + } + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */ + } + /* done, so no time out */ + return SCPE_OK; + } + + /* should not get here */ + return SCPE_OK; +} + +/* Handle haltio transfers for printer */ +t_stat lpr_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & LPR_CMDMSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_EXP, &lpr_dev, + "lpr_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + if ((uptr->CMD & LPR_CMDMSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, &con_dev, + "lpr_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + sim_cancel(uptr); /* stop timer */ + } else { + sim_debug(DEBUG_CMD, &con_dev, + "lpr_haltio HIO not busy chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + } + /* stop any I/O and post status and return error status */ + chp->ccw_count = 0; /* zero the count */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS = 0; /* no status */ + uptr->CBP = 0; /* start of buffer */ + sim_debug(DEBUG_CMD, &con_dev, + "lpr_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ + return SCPE_IOERR; /* tell chan code to post status */ +} + +/* Set the number of lines per page on printer */ +t_stat lpr_setlpp(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int i; + if (cptr == NULL) + return SCPE_ARG; + if (uptr == NULL) + return SCPE_IERR; + i = 0; + while(*cptr != '\0') { + if (*cptr < '0' || *cptr > '9') + return SCPE_ARG; + i = (i * 10) + (*cptr++) - '0'; + } + if (i < 20 || i > 100) + return SCPE_ARG; + uptr->capac = i; + uptr->CNT = 0; + /* set beginning of form and top of form */ + uptr->SNS |= (SNS_TOF|SNS_BEGOF); + return SCPE_OK; +} + +/* display the number of lines per page */ +t_stat lpr_getlpp(FILE *st, UNIT *uptr, int32 v, CONST void *desc) +{ + if (uptr == NULL) + return SCPE_IERR; + fprintf(st, "linesperpage=%02d", uptr->capac); + return SCPE_OK; +} + +/* attach a file to the line printer device */ +t_stat lpr_attach(UNIT *uptr, CONST char *file) +{ + t_stat r; + uint16 chsa = GET_UADDR(uptr->CMD); /* get address of lpr device */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + DEVICE *dptr = get_dev(uptr); /* get device pointer */ + DIB *dibp = 0; + + if ((r = attach_unit(uptr, file)) != SCPE_OK) + return r; + uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK); + uptr->CNT = 0; + uptr->SNS = 0; + /* set beginning of form and top of form */ + uptr->SNS |= (SNS_TOF|SNS_BEGOF); + uptr->capac = 66; + + /* check for valid configured lpr */ + /* must have valid DIB and Channel Program pointer */ + dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */ + if ((dib_unit[chsa] == NULL) || (dibp == NULL) || (chp == NULL)) { + sim_debug(DEBUG_CMD, dptr, + "ERROR===ERROR\nLPR device %s not configured on system, aborting\n", + dptr->name); + printf("ERROR===ERROR\nLPR device %s not configured on system, aborting\r\n", + dptr->name); + detach_unit(uptr); /* detach if error */ + return SCPE_UNATT; /* error */ + } + set_devattn(chsa, SNS_DEVEND); /* ready int???? */ + return SCPE_OK; +} + +/* help information for lpr */ +t_stat lpr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf (st, "SEL32 924x High Speed Line Printer\n"); + fprintf (st, "The Line printer can be configured to any number of\n"); + fprintf (st, "lines per page with the:\n"); + fprintf (st, "sim> SET LPRn LINESPERPAGE=n\n\n"); + fprintf (st, "The default is 66 lines per page.\n"); + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + return SCPE_OK; +} + +/* detach a file from the line printer */ +t_stat lpr_detach(UNIT * uptr) +{ + return detach_unit(uptr); +} + +const char *lpr_description (DEVICE *dptr) +{ + return "SEL32 924x High Speed Line Printer"; +} + +#endif diff --git a/SEL32/sel32_mfp.c b/SEL32/sel32_mfp.c new file mode 100644 index 00000000..c46a893b --- /dev/null +++ b/SEL32/sel32_mfp.c @@ -0,0 +1,357 @@ +/* sel32_mfp.c: SEL-32 Model 8002 MFP processor controller + + Copyright (c) 2018-2022, James C. Bevier + + 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 + JAMES C. BEVIER 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. + + This channel is the interrupt fielder for all of the MFP sub channels. It's + channel address is 7600. This code handles the INCH command for the MFP + devices and controls the status FIFO for the mfp devices on interrupts and + TIO instructions.. + + Possible devices: + The f8iop communication controller (TY76A0), (TY76B0), (TY76C0) + The ctiop console communications controller (CT76FC & CT76FD) + The lpiop line printer controller (LP76F8), (LP76F9) + The scsi SCSI disk controller (DM7600), (DM7640) + +*/ + +#include "sel32_defs.h" + +#if NUM_DEVS_MFP > 0 + +#define UNIT_MFP UNIT_IDLE | UNIT_DISABLE + +/* forward definitions */ +t_stat mfp_preio(UNIT *uptr, uint16 chan); +t_stat mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); +void mfp_ini(UNIT *uptr, t_bool f); +t_stat mfp_rschnlio(UNIT *uptr); +t_stat mfp_srv(UNIT *uptr); +t_stat mfp_reset(DEVICE *dptr); +t_stat mfp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *mfp_desc(DEVICE *dptr); + +/* Held in u3 is the device command and status */ +#define MFP_INCH 0x00 /* Initialize channel command */ +#define MFP_INCH2 0xf0 /* Initialize channel command after start */ +#define MFP_NOP 0x03 /* NOP command */ +#define MFP_SID 0x80 /* MFP status command */ +#define MFP_MSK 0xff /* Command mask */ + +/* Status held in u3 */ +/* controller/unit address in upper 16 bits */ +#define CON_INPUT 0x100 /* Input ready for unit */ +#define CON_CR 0x200 /* Output at beginning of line */ +#define CON_REQ 0x400 /* Request key pressed */ +#define CON_EKO 0x800 /* Echo input character */ +#define CON_OUTPUT 0x1000 /* Output ready for unit */ +#define CON_READ 0x2000 /* Read mode selected */ + +/* not used u4 */ + +/* in u5 packs sense byte 0,1 and 3 */ +/* Sense byte 0 */ +#define SNS_CMDREJ 0x80000000 /* Command reject */ +#define SNS_INTVENT 0x40000000 /* Unit intervention required */ +/* sense byte 3 */ +#define SNS_RDY 0x80 /* device ready */ +#define SNS_ONLN 0x40 /* device online */ + +/* std devices. data structures + + mfp_dev Console device descriptor + mfp_unit Console unit descriptor + mfp_reg Console register list + mfp_mod Console modifiers list +*/ + +struct _mfp_data +{ + uint8 ibuff[145]; /* Input line buffer */ + uint8 incnt; /* char count */ +} +mfp_data[NUM_UNITS_MFP]; + +/* channel program information */ +CHANP mfp_chp[NUM_UNITS_MFP] = {0}; + +MTAB mfp_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", + &set_dev_addr, &show_dev_addr, NULL, "Controller Channel address"}, + {0} +}; + +UNIT mfp_unit[] = { + {UDATA(&mfp_srv, UNIT_MFP, 0), 0, UNIT_ADDR(0x7600)}, /* Channel controller */ +}; + +//DIB mfp_dib = {NULL, mfp_startcmd, NULL, NULL, NULL, mfp_ini, mfp_unit, mfp_chp, NUM_UNITS_MFP, 0xff, 0x7600,0,0,0}; +DIB mfp_dib = { + mfp_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + mfp_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + NULL, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O HIO */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O HIO */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O TIO */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + mfp_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + mfp_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + mfp_unit, /* UNIT* units */ /* Pointer to units structure */ + mfp_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_MFP, /* uint8 numunits */ /* number of units defined */ + 0xff, /* uint8 mask */ /* 16 devices - device mask */ + 0x7600, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE mfp_dev = { + "MFP", mfp_unit, NULL, mfp_mod, + NUM_UNITS_MFP, 8, 15, 1, 8, 8, + NULL, NULL, &mfp_reset, /* examine, deposit, reset */ + NULL, NULL, NULL, /* boot, attach, detach */ + /* dib ptr, dev flags, debug flags, debug */ + &mfp_dib, DEV_CHAN|DEV_DIS|DEV_DISABLE|DEV_DEBUG, 0, dev_debug, +}; + +/* MFP controller routines */ +/* initialize the console chan/unit */ +void mfp_ini(UNIT *uptr, t_bool f) +{ + int unit = (uptr - mfp_unit); /* unit 0 */ + DEVICE *dptr = &mfp_dev; /* one and only dummy device */ + + mfp_data[unit].incnt = 0; /* no input data */ + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + sim_cancel(uptr); /* stop any timers */ + sim_debug(DEBUG_CMD, &mfp_dev, + "MFP init device %s controller/device %04x SNS %08x\n", + dptr->name, GET_UADDR(uptr->u3), uptr->u5); +} + +/* handle rschnlio cmds for disk */ +t_stat mfp_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->u3); + int cmd = uptr->u3 & MFP_MSK; + + sim_debug(DEBUG_EXP, dptr, + "mfp_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + mfp_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +/* start an mfp operation */ +t_stat mfp_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + uint16 chsa = GET_UADDR(uptr->u3); + + sim_debug(DEBUG_CMD, dptr, "mfp_preio CMD %08x unit %02x chsa %04x\n", + uptr->u3, unit, chsa); + + if ((uptr->u3 & MFP_MSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "mfp_preio unit %02x chsa %04x BUSY\n", unit, chsa); + return SNS_BSY; /* yes, return busy */ + } + + sim_debug(DEBUG_CMD, dptr, "mfp_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + +/* start an I/O operation */ +t_stat mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + sim_debug(DEBUG_CMD, &mfp_dev, + "MFP startcmd %02x controller/device %04x\n", + cmd, GET_UADDR(uptr->u3)); + if ((uptr->u3 & MFP_MSK) != 0) /* is unit busy */ + return SNS_BSY; /* yes, return busy */ + + /* process the commands */ + switch (cmd & 0xFF) { + /* UTX uses the INCH cmd to detect the MFP or MFP */ + /* MFP has INCH cmd of 0, while MFP uses 0x80 */ + case MFP_INCH: /* INCH command */ + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + uptr->u3 &= LMASK; /* leave only chsa */ + sim_debug(DEBUG_CMD, &mfp_dev, + "mfp_startcmd %04x: Cmd INCH iptr %06x INCHa %06x\n", + chan, mfp_chp[0].ccw_addr, /* set inch buffer addr */ + mfp_chp[0].chan_inch_addr); /* set inch buffer addr */ + + mfp_chp[0].chan_inch_addr = mfp_chp[0].ccw_addr; /* set inch buffer addr */ + mfp_chp[0].base_inch_addr = mfp_chp[0].ccw_addr; /* set inch buffer addr */ + mfp_chp[0].max_inch_addr = mfp_chp[0].ccw_addr + (128 * 8); /* set last inch buffer addr */ + + uptr->u3 |= MFP_INCH2; /* save INCH command as 0xf0 */ + sim_activate(uptr, 40); /* go on */ + return 0; /* no status change */ + break; + + case MFP_NOP: /* NOP command */ + sim_debug(DEBUG_CMD, &mfp_dev, "mfp_startcmd %04x: Cmd NOP\n", chan); + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + uptr->u3 &= LMASK; /* leave only chsa */ + uptr->u3 |= (cmd & MFP_MSK); /* save NOP command */ + sim_activate(uptr, 40); /* TRY 07-13-19 */ + return 0; /* no status change */ + break; + + case MFP_SID: /* status ID command */ + sim_debug(DEBUG_CMD, &mfp_dev, "mfp_startcmd %04x: Cmd SID\n", chan); + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + uptr->u3 &= LMASK; /* leave only chsa */ + uptr->u3 |= (cmd & MFP_MSK); /* save SID command */ + sim_activate(uptr, 40); /* TRY 07-13-19 */ + return 0; /* no status change */ + break; + + default: /* invalid command */ + uptr->u5 |= SNS_CMDREJ; /* command rejected */ + sim_debug(DEBUG_CMD, &mfp_dev, "mfp_startcmd %04x: Cmd Invalid %02x status %02x\n", + chan, cmd, uptr->u5); + uptr->u3 &= LMASK; /* leave only chsa */ + uptr->u3 |= (cmd & MFP_MSK); /* save command */ + sim_activate(uptr, 40); /* force interrupt */ + return 0; /* no status change */ + break; + } + + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* not reachable for now */ +} + +/* Handle transfers for other sub-channels on MFP */ +t_stat mfp_srv(UNIT *uptr) +{ + uint16 chsa = GET_UADDR(uptr->u3); + int cmd = uptr->u3 & MFP_MSK; + CHANP *chp = &mfp_chp[0]; /* find the chanp pointer */ + uint32 mema = chp->ccw_addr; /* get inch or buffer addr */ + uint32 tstart; + + /* test for NOP or INCH cmds */ + if ((cmd != MFP_NOP) && (cmd != MFP_INCH2) && (cmd != MFP_SID)) { /* NOP, SID or INCH */ + uptr->u3 &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &mfp_dev, + "mfp_srv Unknown cmd %02x chan %02x: chnend|devend|unitexp\n", cmd, chsa); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* done */ + return SCPE_OK; + } else + + if (cmd == MFP_NOP) { /* NOP do nothing */ + uptr->u3 &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &mfp_dev, "mfp_srv NOP chan %02x: chnend|devend\n", chsa); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; + } else + + /* 3 status wds are to be returned */ + /* Wd 1 MMXXXXXX board model # assume 00 00 08 02*/ + /* Wd 2 MMXXXXXX board firmware model # assume 00 00 08 02*/ + /* Wd 3 MMXXXXXX board firmware revision # assume 00 00 00 14*/ + if (cmd == MFP_SID) { /* send 12 byte Status ID data */ + uint8 ch; + + /* Word 0 */ /* board mod 4324724 = 0x0041fd74 */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 0 */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 1 */ + ch = 0x81; + chan_write_byte(chsa, &ch); /* write byte 2 */ + ch = 0x02; + chan_write_byte(chsa, &ch); /* write byte 3 */ + + /* Word 1 */ /* firmware 4407519 = 0x004340df */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 4 */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 5 */ + ch = 0x80; + chan_write_byte(chsa, &ch); /* write byte 6 */ + ch = 0x02; + chan_write_byte(chsa, &ch); /* write byte 7 */ + + /* Word 2 */ /* firmware rev 4259588 = 0x0040ff04 */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 8 */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 9 */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 10 */ + ch = 0x14; + chan_write_byte(chsa, &ch); /* write byte 11 */ + + uptr->u3 &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &mfp_dev, "mfp_srv SID chan %02x: chnend|devend\n", chsa); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; + } else + + /* test for INCH cmd */ + if (cmd == MFP_INCH2) { /* INCH */ + sim_debug(DEBUG_CMD, &mfp_dev, + "mfp_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n", + mema, chsa, chp->ccw_addr, chp->ccw_count); + + /* now call set_inch() function to write and test inch buffer addresses */ + /* the chp->ccw_addr location contains the inch address */ + /* 1-256 wd buffer is provided for 128 status dbl words */ + tstart = set_inch(uptr, mema, 128); /* new address of 128 entries */ + if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->u5 |= SNS_CMDREJ; + uptr->u3 &= LMASK; /* nothing left, command complete */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + uptr->u3 &= LMASK; /* clear the cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + } + return SCPE_OK; +} + +t_stat mfp_reset(DEVICE *dptr) +{ + /* add reset code here */ + return SCPE_OK; +} + +/* sho help mfp */ +t_stat mfp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr) +{ + fprintf(st, "SEL-32 MFP Model 8002 Channel Controller at 0x7600\r\n"); + fprintf(st, "The MFP fields all interrupts and status posting\r\n"); + fprintf(st, "for each of the controllers on the system.\r\n"); + fprintf(st, "Nothing can be configured for this Channel.\r\n"); + return SCPE_OK; +} + +const char *mfp_desc(DEVICE *dptr) +{ + return("SEL-32 MFP Model 8002 Channel Controller @ 0x7600"); +} + +#endif + diff --git a/SEL32/sel32_mt.c b/SEL32/sel32_mt.c new file mode 100644 index 00000000..33f7be68 --- /dev/null +++ b/SEL32/sel32_mt.c @@ -0,0 +1,1645 @@ +/* sel32_mt.c: SEL-32 8051 Buffered Tape Processor + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell and other SIMH contributers + + 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 + JAMES C. BEVIER 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. + + Magnetic tapes are represented as a series of variable records + of the form: + + 32b byte count + byte 0 + byte 1 + : + byte n-2 + byte n-1 + 32b byte count + + If the byte count is odd, the record is padded with an extra byte + of junk. File marks are represented by a byte count of 0. EOT is + represented as 0xffffffff (-1) byte count. +*/ + +#include "sel32_defs.h" +#include "sim_tape.h" + +#if NUM_DEVS_MT > 0 + +#define BUFFSIZE (64 * 1024) +#define UNIT_MT UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE + +#define CMD u3 +/* BTP tape commands */ +#define MT_INCH 0x00 /* Initialize channel command */ +#define MT_WRITE 0x01 /* Write command */ +#define MT_READ 0x02 /* Read command */ +#define MT_NOP 0x03 /* Control command */ +#define MT_SENSE 0x04 /* Sense command */ +#define MT_RDBK 0x0c /* Read Backward */ +#define MT_RDCMP 0x13 /* Read and compare command */ +#define MT_REW 0x23 /* Rewind command */ +#define MT_RUN 0x33 /* Rewind and unload */ +#define MT_FSR 0x43 /* Advance record */ +#define MT_BSR 0x53 /* Backspace record */ +#define MT_FSF 0x63 /* Advance to filemark */ +#define MT_BSF 0x73 /* Backspace to filemark */ +#define MT_SETM 0x83 /* Set Mode command */ +#define MT_WTM 0x93 /* Write Tape filemark */ +#define MT_ERG 0xA3 /* Erase 3.5 of tape */ +#define MT_MODEMSK 0xFF /* Mode Mask */ + +/* set mode bits for BTP (MT_SETM) */ +#define MT_MODE_AUTO 0x80 /* =0 Perform auto error recovery on read */ +#define MT_MODE_FORCE 0x80 /* =1 Read regardless if error recovery fails */ +#define MT_MDEN_800 0x40 /* =0 select 800 BPI NRZI mode 9 track only */ +#define MT_MDEN_1600 0x40 /* =1 select 1600 BPI PE mode 9 track only */ +#define MT_MDEN_6250 0x02 /* =0 Use mode from bit one for NRZI/PE */ +#define MT_MDEN_6250 0x02 /* =1 6250 BPI GCR mode 9 track only */ +#define MT_MDEN_SCATGR 0x01 /* =1 HSTP scatter/gather mode */ +#define MT_MDEN_MSK 0x42 /* Density mask */ + +#define MT_CTL_MSK 0x38 /* Mask for control flags */ +#define MT_CTL_NOP 0x00 /* Nop control mode */ +#define MT_CTL_NRZI 0x08 /* 9 track 800 bpi mode */ +#define MT_CTL_RST 0x10 /* Set density, odd, convert on, trans off */ +#define MT_CTL_NOP2 0x18 /* 9 track 1600 NRZI mode */ + +/* in u3 is device command code and status */ +#define MT_CMDMSK 0x00ff /* Command being run */ +#define MT_READDONE 0x0400 /* Read finished, end channel */ +#define MT_MARK 0x0800 /* Sensed tape mark in move command */ +#define MT_ODD 0x1000 /* Odd parity */ +#define MT_TRANS 0x2000 /* Translation turned on ignored 9 track */ +#define MT_CONV 0x4000 /* Data converter on ignored 9 track */ +#define MT_BUSY 0x8000 /* Flag to send a CUE */ + +#define POS u4 +/* in u4 is current buffer position */ + +#define SNS u5 +/* in u5 packs sense byte 0, 1, 2 and 3 */ +/* Sense byte 0 */ +#define SNS_CMDREJ 0x80000000 /* Command reject */ +#define SNS_INTVENT 0x40000000 /* Unit intervention required */ +#define SNS_SPARE1 0x20000000 /* Spare */ +#define SNS_EQUCHK 0x10000000 /* Equipment check */ +#define SNS_DATCHK 0x08000000 /* Data Check */ +#define SNS_OVRRUN 0x04000000 /* Data overrun */ +#define SNS_SPARE2 0x02000000 /* Spare */ +#define SNS_LOOKER 0x01000000 /* lookahead error */ + +/* Sense byte 1 */ +#define SNS_PEMODER 0x800000 /* PE tape mode error */ +#define SNS_TPECHK 0x400000 /* Tape PE mode check */ +#define SNS_FMRKDT 0x200000 /* File mark detected EOF */ +#define SNS_CORERR 0x100000 /* Corrected Error */ +#define SNS_HARDER 0x080000 /* Hard Error */ +#define SNS_MRLDER 0x040000 /* Mode register load error */ +#define SNS_DATAWR 0x020000 /* Data written */ +#define SNS_SPARE3 0x010000 /* Spare */ + +/* Sense byte 2 mode register bits */ +#define SNS_MREG0 0x8000 /* 0 - Auto retry on read error */ + /* 1 - Ignore read errors */ +#define SNS_MREG1 0x4000 /* 0 - NRZI */ + /* 1 - PE */ +#define SNS_MREG2 0x2000 /* Mode register bit 2 N/U */ +#define SNS_MREG3 0x1000 /* Mode register bit 3 N/U */ +#define SNS_MREG4 0x0800 /* Mode register bit 4 N/U */ +#define SNS_MREG5 0x0400 /* Mode register bit 5 N/U */ +#define SNS_MREG6 0x0200 /* Mode register bit 6 N/U */ +#define SNS_MREG7 0x0100 /* 1 - HSDP scatter/gather mode */ + +/* Sense byte 3 */ +/* data returned for SENSE cmd (0x04) */ +#define SNS_RDY 0x80 /* Drive Ready */ +#define SNS_ONLN 0x40 /* Drive Online */ +#define SNS_WRP 0x20 /* Drive is file protected (write ring missing) */ +#define SNS_NRZI 0x10 /* Drive is NRZI */ +#define SNS_SPARE4 0x08 /* Spare */ +#define SNS_LOAD 0x04 /* Drive is at load point */ +#define SNS_EOT 0x02 /* Drive is at EOT */ +#define SNS_SPARE5 0x01 /* Spare */ + +#define SNS_BYTE4 0x00 /* Hardware errors not supported */ +#define SNS_BYTE5 0x00 /* Hardware errors not supported */ + +#define MT_CONV1 0x40 +#define MT_CONV2 0x80 +#define MT_CONV3 0xc0 + +/* u6 holds the packed characters and unpack counter */ +#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF) +#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF + +/* forward definitions */ +t_stat mt_preio(UNIT *uptr, uint16 chan); +t_stat mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ; +t_stat mt_iocl(CHANP *chp, int32 tic_ok); +t_stat mt_srv(UNIT *uptr); +t_stat mt_boot(int32 unitnum, DEVICE *dptr); +void mt_ini(UNIT *uptr, t_bool); +t_stat mt_rschnlio(UNIT *uptr); +t_stat mt_haltio(UNIT *uptr); +t_stat mt_reset(DEVICE *dptr); +t_stat mt_attach(UNIT *uptr, CONST char *); +t_stat mt_detach(UNIT *uptr); +t_stat mt_help(FILE *, DEVICE *dptr, UNIT *uptr, int32, const char *); +const char *mt_description(DEVICE *); +extern uint32 readfull(CHANP *chp, uint32 maddr, uint32 *word); +extern uint16 loading; /* set when doing IPL */ +extern int irq_pend; /* pending interrupt flag */ +extern uint32 cont_chan(uint16 chsa); + +/* One buffer per channel */ +uint8 mt_buffer[NUM_DEVS_MT][BUFFSIZE]; +uint8 mt_busy[NUM_DEVS_MT]; + +/* Gould Buffered Tape Processor (BTP) - Model 8051 */ +/* Integrated channel controller */ + +/* Class F MT BTP I/O device status response in IOCD address pointer location */ +/* |-------+-------+-------+-------+-------+-------+-------+-------| */ +/* |0 0 0 0|0 0 0 0|0 0 1 1|1 1 1 1|1 1 1 1|2 2 2 2|2 2 2 2|2 2 3 3| */ +/* |0 1 2 3|4 5 6 7|8 9 0 1|2 3 4 5|6 7 8 9|0 1 2 3|4 5 6 7|8 9 3 1| */ +/* | Cond |0 0 0 0| Address of status doubleword or zero | */ +/* | Code | */ +/* |-------+-------+-------+-------+-------+-------+-------+-------| */ +/* */ +/* Bits 0-3 - Condition codes */ +/* 0000 - operation accepted will echo status not sent by the channel */ +/* 0001 - channel busy */ +/* 0010 - channel inop or undefined */ +/* 0011 - subchannel busy */ +/* 0100 - status stored */ +/* 0101 - unsupported transaction */ +/* 1000 - Operation accepted/queued, no echo status */ + +/* Status Doubleword */ +/* Word 1 */ +/* |-------+-------+-------+-------+-------+-------+-------+-------| */ +/* |0 0 0 0|0 0 0 0|0 0 1 1|1 1 1 1|1 1 1 1|2 2 2 2|2 2 2 2|2 2 3 3| */ +/* |0 1 2 3|4 5 6 7|8 9 0 1|2 3 4 5|6 7 8 9|0 1 2 3|4 5 6 7|8 9 3 1| */ +/* |Sub Address | 24 bit IOCD address | */ +/* |-------+-------+-------+-------+-------+-------+-------+-------| */ +/* Word 2 */ +/* |-------+-------+-------+-------+-------+-------+-------+-------| */ +/* |0 0 0 0|0 0 0 0|0 0 1 1|1 1 1 1|1 1 1 1|2 2 2 2|2 2 2 2|2 2 3 3| */ +/* |0 1 2 3|4 5 6 7|8 9 0 1|2 3 4 5|6 7 8 9|0 1 2 3|4 5 6 7|8 9 3 1| */ +/* | 16 bit of status | Residual Byte Count | */ +/* |-------+-------+-------+-------+-------+-------+-------+-------| */ + +/* Status Bits */ +/* Bit 00 - ECHO Halt I/O and Stop I/O function */ +/* Bit 01 - PCI Program Controlled Interrupt */ +/* Bit 02 - IL Incorrect Length */ +/* Bit 03 - CPC Channel Program Check */ +/* Bit 04 - CDC Channel Data Check */ +/* Bit 05 - CCC Channel Control Check */ +/* Bit 06 - IC Interface Check */ +/* Bit 07 - CHC Chaining Check */ +/* Bit 08 - DB Device Busy */ +/* Bit 09 - SM Status Modifier */ +/* Bit 10 - CNTE Controller End */ +/* Bit 11 - ATTN Attention */ +/* Bit 12 - CE Channel End */ +/* Bit 13 - DE Device End */ +/* Bit 14 - UC Unit Check */ +/* Bit 15 - UE Unit Exception */ + +/* 41 Word Main memory channel buffer provided by INCH command */ +/* when software is initializing the channel */ +/* Word 01 - Status Doubleword 1 - Word 1 */ +/* Word 02 - Status Doubleword 1 - Word 2 */ +/* Word 03 - Status Doubleword 2 - Word 1 */ +/* Word 04 - Status Doubleword 2 - Word 2 */ +/* Word 05 - BTP Error Recovery IOCD Address */ +/* Word 06 - Queue Command List Doubleword - Word 1 */ +/* Word 07 - Queue Command List Doubleword - Word 2 */ +/* Word 08 - 16 bit Logical Q-pointer | 16 bit Physical Q-pointer */ +/* Word 09 - 16 bit Active Retry Count | 16 bit Constant Retry Count */ +/* Word 10 - Accumulated Write Count - Drive 0 */ +/* Word 11 - Accumulated Read Count - Drive 0 */ +/* Word 12 - Write Error Count - Drive 0 */ +/* Word 13 - Read Error Count - Drive 0 */ +/* Word 14 - Accumulated Write Count - Drive 1 */ +/* Word 15 - Accumulated Read Count - Drive 1 */ +/* Word 16 - Write Error Count - Drive 1 */ +/* Word 17 - Read Error Count - Drive 1 */ +/* Word 18 - Accumulated Write Count - Drive 2 */ +/* Word 19 - Accumulated Read Count - Drive 2 */ +/* Word 20 - Write Error Count - Drive 2 */ +/* Word 21 - Read Error Count - Drive 2 */ +/* Word 22 - Accumulated Write Count - Drive 3 */ +/* Word 23 - Accumulated Read Count - Drive 3 */ +/* Word 24 - Write Error Count - Drive 3 */ +/* Word 25 - Read Error Count - Drive 3 */ +/* Word 26 - Accumulated Write Count - Drive 4 */ +/* Word 27 - Accumulated Read Count - Drive 4 */ +/* Word 28 - Write Error Count - Drive 4 */ +/* Word 29 - Read Error Count - Drive 4 */ +/* Word 30 - Accumulated Write Count - Drive 5 */ +/* Word 31 - Accumulated Read Count - Drive 5 */ +/* Word 32 - Write Error Count - Drive 5 */ +/* Word 33 - Read Error Count - Drive 5 */ +/* Word 34 - Accumulated Write Count - Drive 6 */ +/* Word 35 - Accumulated Read Count - Drive 6 */ +/* Word 36 - Write Error Count - Drive 6 */ +/* Word 37 - Read Error Count - Drive 6 */ +/* Word 38 - Accumulated Write Count - Drive 7 */ +/* Word 39 - Accumulated Read Count - Drive 7 */ +/* Word 40 - Write Error Count - Drive 7 */ +/* Word 41 - Read Error Count - Drive 7 */ + +int32 valid_dens = MT_800_VALID|MT_1600_VALID|MT_6250_VALID; +MTAB mt_mod[] = { + {MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL, NULL, NULL, + "Write ring in place"}, + {MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL, NULL, NULL, + "No write ring in place"}, + {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "DENSITY", "DENSITY", + &sim_tape_set_dens, &sim_tape_show_dens, &valid_dens, + "Set tape density"}, + {MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL, + "Set/Display tape format (SIMH, E11, TPC, P7B)"}, + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, + &show_dev_addr, NULL, "Device address"}, + {0} +}; + +UNIT mta_unit[] = { + /* Unit data layout for MT devices */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1000)}, /* 0 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1001)}, /* 1 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1002)}, /* 2 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1003)}, /* 3 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1004)}, /* 4 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1005)}, /* 5 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1006)}, /* 6 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1007)}, /* 7 */ +}; + +/* channel program information */ +CHANP mta_chp[NUM_UNITS_MT] = {0}; + +DIB mta_dib = { + mt_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + mt_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + mt_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + mt_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + mt_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + mta_unit, /* UNIT* units */ /* Pointer to units structure */ + mta_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_MT, /* uint8 numunits */ /* number of units defined */ + 0x07, /* uint8 mask */ /* 8 devices - device mask */ + 0x1000, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE mta_dev = { + "MTA", mta_unit, NULL, mt_mod, + NUM_UNITS_MT, 16, 24, 4, 16, 32, + NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, + /* ctxt is the DIB pointer */ + &mta_dib, DEV_BUF_NUM(0)|DEV_DIS|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug, + NULL, NULL, &mt_help, NULL, NULL, &mt_description + +}; + +#if NUM_DEVS_MT > 1 +/* channel program information */ +CHANP mtb_chp[NUM_UNITS_MT] = {0}; + +UNIT mtb_unit[] = { + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1800)}, /* 0 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1801)}, /* 1 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1802)}, /* 2 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1803)}, /* 3 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1804)}, /* 4 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1805)}, /* 5 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1806)}, /* 6 */ + {UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1807)}, /* 7 */ +}; + +/* device information block */ +DIB mtb_dib = { + mt_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + mt_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + mt_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + mt_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + mt_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + mtb_unit, /* UNIT* units */ /* Pointer to units structure */ + mtb_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_MT, /* uint8 numunits */ /* number of units defined */ + 0x07, /* uint8 mask */ /* 8 devices - device mask */ + 0x1800, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE mtb_dev = { + "MTB", mtb_unit, NULL, mt_mod, + NUM_UNITS_MT, 8, 15, 1, 8, 8, + NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, + &mtb_dib, DEV_BUF_NUM(0)|DEV_DIS|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug, + NULL, NULL, &mt_help, NULL, NULL, &mt_description +}; +#endif + +/* load in the IOCD and process the commands */ +/* return = 0 OK */ +/* return = 1 error, chan_status will have reason */ +t_stat mt_iocl(CHANP *chp, int32 tic_ok) +{ + uint32 word1 = 0; + uint32 word2 = 0; + int32 docmd = 0; + UNIT *uptr = chp->unitptr; /* get the unit ptr */ + uint16 chan = get_chan(chp->chan_dev); /* our channel */ + uint16 chsa = chp->chan_dev; + uint16 devstat = 0; + DEVICE *dptr = get_dev(uptr); + + /* check for valid iocd address if 1st iocd */ + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + if (chp->chan_caw & 0x3) { /* must be word bounded */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl iocd bad address chsa %02x caw %06x\n", + chsa, chp->chan_caw); + chp->ccw_addr = chp->chan_caw; /* set the bad iocl address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ + return 1; /* error return */ + } + } +loop: + sim_debug(DEBUG_EXP, dptr, + "mt_iocl @%06x @loop chan_status[%04x] %04x SNS %08x\n", + chp->chan_caw, chan, chp->chan_status, uptr->SNS); + + /* Abort if we have any errors */ + if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl ERROR1 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* return error */ + } + + /* Read in first CCW */ + if (readfull(chp, chp->chan_caw, &word1) != 0) { /* read word1 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl ERROR2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Read in second CCW */ + if (readfull(chp, chp->chan_caw+4, &word2) != 0) { /* read word2 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl ERROR3 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + sim_debug(DEBUG_CMD, dptr, + "mt_iocl @%06x read ccw chsa %04x IOCD wd 1 %08x wd 2 %08x SNS %08x\n", + chp->chan_caw, chp->chan_dev, word1, word2, uptr->SNS); + + chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */ + + /* Check if we had data chaining in previous iocd */ + /* if we did, use previous cmd value */ + if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + (chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "mt_iocl @%06x DO DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + } else + chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ + + if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl mem error PCHK chan_status[%04x] %04x addr %08x\n", + chan, chp->chan_status, word1 & MASK24); + return 1; /* error return */ + } + + chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2*/ + + /* validate the commands for the mt */ + switch (chp->ccw_cmd) { + case MT_WRITE: case MT_READ: case MT_NOP: case MT_SENSE: + case MT_RDBK: case MT_RDCMP: case MT_REW: case MT_RUN: case MT_FSR: + case MT_BSR: case MT_FSF: case MT_BSF: case MT_SETM: case MT_WTM: case MT_ERG: + /* the inch command must be first command issued */ + if ((!loading) && (chp->chan_inch_addr == 0)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl bad cmd %02x chan_status[%04x] %04x\n", + chp->ccw_cmd, chan, chp->chan_status); + return 1; /* error return */ + } + case MT_INCH: + break; + default: + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl bad cmd %02x chan_status[%04x] %04x\n", + chp->ccw_cmd, chan, chp->chan_status); + return 1; /* error return */ + } + + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + /* 1st command can not be a TIC */ + if (chp->ccw_cmd == CMD_TIC) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl TIC bad cmd chan_status[%04x] %04x\n", + chan, chp->chan_status); + return 1; /* error return */ + } + } + + /* TIC can't follow TIC or be first in command chain */ + /* diags send bad commands for testing. Use all of op */ + if (chp->ccw_cmd == CMD_TIC) { + if (tic_ok) { + if (((word1 & MASK24) == 0) || (word1 & 0x3)) { + sim_debug(DEBUG_EXP, dptr, + "mt_iocl tic cmd bad address chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + return 1; /* error return */ + } + tic_ok = 0; /* another tic not allowed */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + sim_debug(DEBUG_CMD, dptr, + "mt_iocl tic cmd ccw chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + goto loop; /* restart the IOCD processing */ + } + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl TIC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Check if we had data chaining in previous iocd */ + if ((chp->chan_info & INFO_SIOCD) || /* see if 1st IOCD in channel prog */ + (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + ((chp->ccw_flags & FLAG_DC) == 0))) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "mt_iocl @%06x DO CMD No DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + docmd = 1; /* show we have a command */ + } + + /* Set up for this command */ + chp->ccw_flags = (word2 >> 16) & 0xfc00; /* get flags from bits 0-4 of WD 2 of IOCD */ + chp->chan_status = 0; /* clear status for next IOCD */ + /* make a 24 bit address */ + chp->ccw_addr = word1 & MASK24; /* set the data/seek address */ + + if (chp->ccw_flags & FLAG_PCI) { /* do we have prog controlled int? */ + chp->chan_status |= STATUS_PCI; /* set PCI flag in status */ + irq_pend = 1; /* interrupt pending */ + } + + /* validate parts of IOCD2 that are reserved */ + if (word2 & 0x07ff0000) { /* bits 5-15 must be zero */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl IOCD2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* DC can only be used with a read/write cmd */ + if (chp->ccw_flags & FLAG_DC) { + if ((chp->ccw_cmd != MT_READ) && (chp->ccw_cmd != MT_WRITE) && + (chp->ccw_cmd != MT_RDBK)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid DC */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl DC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + } + + chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ + + sim_debug(DEBUG_XIO, dptr, + "mt_iocl @%06x read docmd %01x addr %06x count %04x chan %04x ccw_flags %04x\n", + chp->chan_caw, docmd, chp->ccw_addr, chp->ccw_count, chan, chp->ccw_flags); + + if (docmd) { /* see if we need to process a command */ + DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ + + uptr = chp->unitptr; /* get the unit ptr */ + if (dibp == 0 || uptr == 0) { + chp->chan_status |= STATUS_PCHK; /* program check if it is */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl bad dibp or uptr chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* if none, error */ + } + + sim_debug(DEBUG_XIO, dptr, + "mt_iocl @%06x before start_cmd chan %04x status %04x count %04x SNS %08x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, uptr->SNS); + + /* call the device startcmd function to process the current command */ + /* just replace device status bits */ + chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ + devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd); + chp->chan_status = (chp->chan_status & 0xff00) | devstat; + chp->chan_info &= ~INFO_SIOCD; /* show not first IOCD in channel prog */ + + sim_debug(DEBUG_XIO, dptr, + "mt_iocl @%06x after start_cmd chsa %04x status %08x count %04x SNS %08x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count, uptr->SNS); + + /* see if bad status */ + if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) { + chp->chan_status |= STATUS_CEND; /* channel end status */ + chp->ccw_flags = 0; /* no flags */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + sim_debug(DEBUG_EXP, dptr, + "mt_iocl bad status chsa %04x status %04x cmd %02x\n", + chsa, chp->chan_status, chp->ccw_cmd); + /* done with command */ + sim_debug(DEBUG_EXP, &cpu_dev, + "mt_iocl ERROR return chsa %04x status %08x\n", + chp->chan_dev, chp->chan_status); + return 1; /* error return */ + } + /* NOTE this code needed for MPX 1.X to run! */ + /* see if command completed */ + /* we have good status */ + if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_XIO, dptr, + "mt_iocl @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n", + chp->chan_caw, FIFO_Num(chsa), chan, chp->chan_status, chp->ccw_count); + } + } + /* the device processor returned OK (0), so wait for I/O to complete */ + /* nothing happening, so return */ + sim_debug(DEBUG_XIO, dptr, + "mt_iocl @%06x return, chsa %04x status %04x count %04x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count); + return 0; /* good return */ +} + +/* start a tape operation */ +t_stat mt_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + uint16 chsa = GET_UADDR(uptr->CMD); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_CMD, dptr, "mt_preio CMD %08x unit %02x chsa %04x incha %08x\n", + uptr->CMD, unit, chsa, chp->chan_inch_addr); + if ((!loading) && (chp->chan_inch_addr == 0)) { + sim_debug(DEBUG_CMD, dptr, + "mt_preio unit %02x chsa %04x NO INCH\n", unit, chsa); + /* no INCH yet, so do nothing */ + return SNS_CTLEND; + } + if ((uptr->CMD & MT_CMDMSK) != 0) { /* just return if busy */ + sim_debug(DEBUG_CMD, dptr, + "mt_preio unit %02x chsa %04x BUSY\n", unit, chsa); + return SNS_BSY; + } + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + /* set status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ + return SCPE_OK; /* good to go */ + } + + sim_debug(DEBUG_CMD, dptr, "mt_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + +/* start an I/O operation */ +t_stat mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_EXP, dptr, "mt_startcmd entry chan %04x cmd %02x\n", chan, cmd); + if (mt_busy[GET_DEV_BUF(dptr->flags)] != 0 || (uptr->CMD & MT_CMDMSK) != 0) { + sim_debug(DEBUG_EXP, dptr, "mt_startcmd busy %02x chan %04x flags %08x CMD %02x\n", + mt_busy[GET_DEV_BUF(dptr->flags)], chan, dptr->flags, uptr->CMD); + uptr->flags |= MT_BUSY; /* Flag we need to send CUE */ + return SNS_BSY; + } + + sim_debug(DEBUG_EXP, dptr, "mt_startcmd processing unit %01x cmd %02x\n", unit, cmd); + + switch (cmd & 0xFF) { + case 0x00: /* INCH command */ + sim_debug(DEBUG_CMD, dptr, "start INCH command\n"); + + sim_debug(DEBUG_CMD, dptr, + "mt_startcmd starting INCH cmd, chsa %04x MemBuf %08x cnt %04x\n", + chsa, chp->ccw_addr, chp->ccw_count); + + /* UTX_needs_interrupt */ + cmd = MT_CMDMSK; /* insert INCH cmd as 0xff */ + /* fall through */ + case 0x03: /* Tape motion commands or NOP */ + case 0x13: /* Read and compare command */ + case 0x23: /* Rewind command */ + case 0x33: /* Rewind and unload */ + case 0x43: /* Advance record */ + case 0x53: /* Backspace record */ + case 0x63: /* Advance filemark */ + case 0x73: /* Backspace filemark */ + case 0x83: /* Set Mode command */ + case 0x93: /* Write Tape filemark */ + case 0xA3: /* Erase 3.5 of tape */ + /* UTX_needs_interrupt on NOP or INCH */ + /* fall through */ + case 0x01: /* Write command */ + case 0x02: /* Read command */ + case 0x0C: /* Read backward */ + if (cmd == 0x01) + sim_debug(DEBUG_EXP, dptr, + "mt_startcmd WRITE chan %04x addr %06x cnt %04x\n", + chan, chp->ccw_addr, chp->ccw_count); + if (cmd == 0x02) + sim_debug(DEBUG_EXP, dptr, + "mt_startcmd READ chan %04x addr %06x cnt %04x\n", + chan, chp->ccw_addr, chp->ccw_count); + if (cmd != 0x03) { /* if this is a nop do not zero status */ + uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */ + } + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ + sim_debug(DEBUG_CMD, dptr, "mt_startcmd detached sense %08x chan %04x cmd %02x\n", + uptr->SNS, chan, cmd); + } else { + uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set ready status */ + if (sim_tape_wrp(uptr)) + uptr->SNS |= (SNS_WRP); /* write protected */ + if (sim_tape_bot(uptr)) + uptr->SNS |= (SNS_LOAD); /* tape at load point */ + if (sim_tape_eot(uptr)) + uptr->SNS |= (SNS_EOT); /* tape at EOM */ + sim_debug(DEBUG_CMD, dptr, "mt_startcmd attached sense %08x chan %04x cmd %02x\n", + uptr->SNS, chan, cmd); + } + /* Fall through */ + + case 0x04: /* Sense */ + uptr->CMD &= ~(MT_CMDMSK); /* clear out last cmd */ + uptr->CMD |= cmd & MT_CMDMSK; /* insert new cmd */ + CLR_BUF(uptr); /* buffer is empty */ + uptr->POS = 0; /* reset buffer position pointer */ + mt_busy[GET_DEV_BUF(dptr->flags)] = 1; /* show we are busy */ + sim_debug(DEBUG_EXP, dptr, "mt_startcmd sense %08x return OK chan %04x cmd %02x\n", + uptr->SNS, chan, cmd); + sim_activate(uptr, 20); /* Start unit off */ + return SCPE_OK; /* good to go */ + + default: /* invalid command */ + sim_debug(DEBUG_EXP, dptr, "mt_startcmd CMDREJ return chan %04x cmd %02x\n", + chan, cmd); + uptr->SNS |= SNS_CMDREJ; + /* send program check */ + return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* add DEVEND 08/16/20 */ + break; + } +} + +/* Map simH errors into machine errors */ +t_stat mt_error(UNIT *uptr, uint16 chsa, t_stat r, DEVICE *dptr) +{ + sim_debug(DEBUG_CMD, dptr, "mt_error status %08x\n", r); + mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1; /* not busy anymore */ + + switch (r) { /* switch on return value */ + case MTSE_OK: /* no error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */ + break; + + case MTSE_TMK: /* tape mark */ + sim_debug(DEBUG_CMD, dptr, "FILE MARK\n"); + uptr->SNS |= SNS_FMRKDT; /* file mark detected */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + + case MTSE_WRP: /* write protected */ + uptr->SNS |= SNS_WRP; /* write protected */ + sim_debug(DEBUG_CMD, dptr, "WRITE PROTECT %08x\n", r); /* operator intervention */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */ + break; + + case MTSE_UNATT: /* unattached */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ + sim_debug(DEBUG_CMD, dptr, "ATTENTION %08x\n", r); /* operator intervention */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + break; + + case MTSE_IOERR: /* IO error */ + case MTSE_FMT: /* invalid format */ + case MTSE_RECE: /* error in record */ + sim_debug(DEBUG_CMD, dptr, "ERROR %08x\n", r); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */ + break; + + case MTSE_BOT: /* beginning of tape */ + uptr->SNS |= SNS_LOAD; /* tape at BOT */ + sim_debug(DEBUG_CMD, dptr, "BOT\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + break; + + case MTSE_INVRL: /* invalid rec lnt */ + case MTSE_EOM: /* end of medium */ + uptr->SNS |= SNS_EOT; /* tape at EOT */ + sim_debug(DEBUG_CMD, dptr, "EOT\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + break; + } + return SCPE_OK; +} + +/* Handle processing of tape requests. */ +t_stat mt_srv(UNIT *uptr) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + int cmd = uptr->CMD & MT_CMDMSK; + int bufnum = GET_DEV_BUF(dptr->flags); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + t_mtrlnt reclen; + t_stat r = SCPE_ARG; /* Force error if not set */ + int i; + char *bufp; + uint32 mema, m, skip; + uint16 len; + uint8 ch; + + sim_debug(DEBUG_CMD, dptr, + "mt_srv unit %02x cmd %02x POS %x hwmark %03x\n", + unit, cmd, uptr->POS, uptr->hwmark); + + switch (cmd) { + case MT_CMDMSK: /* 0x0ff for inch 0x00 */ /* INCH is for channel, nothing for us */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "mt_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n", + mema, chsa, chp->ccw_addr, chp->ccw_count); + + if (len == 0) { + /* we have invalid count, error, bail out */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* the chp->ccw_addr location contains the inch address */ + /* call set_inch() to setup inch buffer */ + /* 4 wd buffer is provided for 2 status dbl words */ + i = set_inch(uptr, mema, 2); /* new address of 33 entries */ + + if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + /* set halfwords 16 & 17 to 5 as default retry count in inch data */ + /* UTX uses this value to see if the device is a buffered tape processor */ + /* they must be non-zero and equal to be BTP */ + WMH(mema+(16<<1),5); /* write left HW with count */ + WMH(mema+(17<<1),5); /* write right HW with count */ + sim_debug(DEBUG_CMD, dptr, + "mt_srv cmd INCH chsa %04x chsa %06x count %04x completed word 16 %08x\n", + chsa, mema, chp->ccw_count, RMW(mema+(8<<2))); + uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ + mt_busy[bufnum] &= ~1; /* make our buffer not busy */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + return SCPE_OK; + + case 0x80: /* other? */ /* default to NOP */ + sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 80 DIAG unit=%04x SNS %08x\n", unit, uptr->SNS); + ch = (uptr->SNS >> 24) & 0xff; /* get sense byte 0 status */ + sim_debug(DEBUG_CMD, dptr, "sense unit %02x byte 0 %02x\n", unit, ch); + chan_write_byte(chsa, &ch); /* write byte 0 */ + ch = (uptr->SNS >> 16) & 0xff; /* get sense byte 1 status */ + sim_debug(DEBUG_CMD, dptr, "sense unit %02x byte 1 %02x\n", unit, ch); + chan_write_byte(chsa, &ch); /* write byte 1 */ + ch = (uptr->SNS >> 8) & 0xff; /* get sense byte 2 status */ + sim_debug(DEBUG_CMD, dptr, "sense unit %02x byte 2 %02x\n", unit, ch); + chan_write_byte(chsa, &ch); /* write byte 2 */ + ch = (uptr->SNS >> 0) & 0xff; /* get sense byte 3 status */ + sim_debug(DEBUG_CMD, dptr, "sense unit %02x byte 3 %02x\n", unit, ch); + chan_write_byte(chsa, &ch); /* write byte 3 */ + /* write zero extra status */ + for (ch=4; ch < 0xc; ch++) { + uint8 zc = 0; + chan_write_byte(chsa, &zc); /* write zero byte */ + sim_debug(DEBUG_CMD, dptr, + "sense unit %02x byte %1x %02x\n", unit, ch, zc); + } + uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ + mt_busy[bufnum] &= ~1; /* make our buffer not busy */ + uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */ + if ((uptr->flags & UNIT_ATT) == 0) /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + else + uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + sim_debug(DEBUG_CMD, dptr, "mt_srv DIAG SNS %08x char complete unit=%02x\n", + uptr->SNS, unit); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + return SCPE_OK; + + case MT_NOP: /* 0x03 */ /* NOP motion command */ + uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ + mt_busy[bufnum] &= ~1; /* make our buffer not busy */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + return SCPE_OK; + + case MT_SENSE: /* 0x04 */ /* get sense data */ + /* write requested status */ + len = chp->ccw_count; /* command count */ + for (i=0; i<4; i++) { + ch = 0; + if (i<4) + ch = (uptr->SNS >> (24-(i*8))) & 0xff; /* get 8 bits of status */ + chan_write_byte(chsa, &ch); /* write zero byte */ + sim_debug(DEBUG_CMD, dptr, + "sense unit %02x byte %1x %02x\n", unit, i, ch); + } + uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ + mt_busy[bufnum] &= ~1; /* make our buffer not busy */ + uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */ + if (!(uptr->flags & UNIT_ATT)) /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + else + uptr->SNS |= (SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + sim_debug(DEBUG_CMD, dptr, "mt_srv SENSE %08x char complete unit=%02x\n", + uptr->SNS, unit); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + return SCPE_OK; + + case MT_SETM: /* 0x83 */ /* set mode byte */ + sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x83 SETM unit=%02x\n", unit); + /* Grab data until channel has no more */ + if (chan_read_byte(chsa, &ch)) { + if (uptr->POS > 0) { /* Only if data in record */ + reclen = uptr->hwmark; /* set record length */ + ch = mt_buffer[bufnum][0]; /* get the first byte read */ + sim_debug(DEBUG_CMD, dptr, + "Write mode data done unit %02x chars %02x mode %02x\n", unit, reclen, ch); + /* put mode bits into byte 2 of SNS */ + uptr->SNS = (uptr->SNS & 0xffff00ff) | (ch << 8); + uptr->POS = 0; /* no bytes anymore */ + uptr->CMD &= ~MT_CMDMSK; /* no cmd to do */ + mt_busy[bufnum] &= ~1; /* set not busy */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return end status */ + } + } else { + mt_buffer[bufnum][uptr->POS++] = ch; /* save the character read in */ + sim_debug(DEBUG_CMD, dptr, "Write mode data in unit %02x POS %04x mode %02x\n", + unit, uptr->POS, ch); + uptr->hwmark = uptr->POS; /* set high water mark */ + sim_activate(uptr, 30); /* wait time */ + } + return SCPE_OK; + default: + break; + } + + /* only run these commands if we have a tape attached */ + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ + mt_busy[bufnum] &= ~1; /* make our buffer not busy */ + /* we are completed with unit check status */ + uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + switch (cmd) { + case MT_READ: /* 0x02 */ /* read a record from the device */ +reread: + if (uptr->CMD & MT_READDONE) { /* is the read complete */ + uptr->SNS &= ~(SNS_LOAD|SNS_EOT); /* reset BOT & EOT */ + if (sim_tape_eot(uptr)) { /* see if at EOM */ + uptr->SNS |= SNS_EOT; /* set EOT status */ + } + + uptr->CMD &= ~(MT_CMDMSK|MT_READDONE); /* clear all but readdone & cmd */ + uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ + mt_busy[bufnum] &= ~1; /* not busy anymore */ + sim_debug(DEBUG_CMD, dptr, + "mt_srv READ %04x char complete unit=%02x sense %08x\n", + uptr->POS, unit, uptr->SNS); + if (uptr->SNS & SNS_EOT) + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* set CE, DE, UE */ + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* set CE, DE */ + break; + } + /* read is not completed, get an input char */ + /* If empty buffer, fill */ + if (BUF_EMPTY(uptr)) { + m = chp->ccw_addr & MASK24; /* memory buffer address */ + /* buffer is empty, so fill it with next record data */ + if ((r = sim_tape_rdrecf(uptr, &mt_buffer[bufnum][0], &reclen, BUFFSIZE)) != MTSE_OK) { + sim_debug(DEBUG_CMD, dptr, "mt_srv READ fill buffer unit=%02x\n", unit); + uptr->CMD &= ~(MT_CMDMSK|MT_READDONE); /* clear all but readdone & cmd */ + return mt_error(uptr, chsa, r, dptr); /* process any error & return status */ + } + uptr->SNS &= ~(SNS_LOAD|SNS_EOT); /* reset BOT & EOT */ + uptr->POS = 0; /* reset buffer position */ + uptr->hwmark = reclen; /* set buffer chars read in */ + sim_debug(DEBUG_CMD, dptr, "mt_srv READ fill buffer %06x complete count %04x\n", m, reclen); + + bufp = dump_buf(&mt_buffer[bufnum][0], 0, 16); + sim_debug(DEBUG_CMD, dptr, "mt_srv READ buf %s\n", bufp); + bufp = dump_buf(&mt_buffer[bufnum][0], 16, 16); + sim_debug(DEBUG_CMD, dptr, "mt_srv READ buf %s\n", bufp); + bufp = dump_buf(&mt_buffer[bufnum][0], 32, 16); + sim_debug(DEBUG_CMD, dptr, "mt_srv READ buf %s\n", bufp); + + m = chp->ccw_addr & MASK24; /* memory buffer address */ + bufp = dump_mem(m, 16); + sim_debug(DEBUG_CMD, dptr, "mt_srv READ mem %s\n", bufp); + bufp = dump_mem(m+16, 16); + sim_debug(DEBUG_CMD, dptr, "mt_srv READ mem %s\n", bufp); + bufp = dump_mem(m+32, 16); + sim_debug(DEBUG_CMD, dptr, "mt_srv READ mem %s\n", bufp); + } + /* get a char from the buffer */ + ch = mt_buffer[bufnum][uptr->POS++]; + + /* Send character over to channel */ + if (chan_write_byte(chsa, &ch)) { + sim_debug(DEBUG_CMD, dptr, + "Read unit %02x EOR cnt %04x hwm %04x\n", unit, uptr->POS-1, uptr->hwmark); + /* If not read whole record, skip till end */ + if ((uint32)uptr->POS < uptr->hwmark) { + /* Send dummy character to force SLI */ + chan_write_byte(chsa, &ch); /* write the byte */ + sim_debug(DEBUG_CMD, dptr, "Read unit %02x send dump SLI\n", unit); + sim_activate(uptr, (uptr->hwmark-uptr->POS) * 4); /* wait again */ + uptr->CMD |= MT_READDONE; /* read is done */ + break; + } + sim_debug(DEBUG_CMD, dptr, + "Read data @1 unit %02x cnt %04x ch %02x hwm %04x\n", + unit, uptr->POS, ch, uptr->hwmark); +#ifndef OLDWAY + uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ + mt_busy[bufnum] &= ~1; /* set not busy */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return end status */ +#else + sim_activate(uptr, 50); + uptr->CMD |= MT_READDONE; /* read is done */ + break; +#endif + } else { + sim_debug(DEBUG_DATA, dptr, + "Read data @2 unit %02x cnt %04x ch %02x hwm %04x\n", + unit, uptr->POS, ch, uptr->hwmark); + if ((uint32)uptr->POS >= uptr->hwmark) { /* In IRG */ + /* Handle end of data record */ + sim_debug(DEBUG_CMD, dptr, + "Read end of data unit %02x cnt %04x ch %02x hwm %04x\n", + unit, uptr->POS, ch, uptr->hwmark); + uptr->CMD |= MT_READDONE; /* read is done */ + goto reread; + } else + goto reread; + } + break; + + case MT_WRITE: /* 0x01 */ /* write record */ + /* Check if write protected */ + if (sim_tape_wrp(uptr)) { + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= ~MT_CMDMSK; + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, "Write write protected unit=%02x\n", unit); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + +rewrite: + /* Grab data until channel has no more */ + if (chan_read_byte(chsa, &ch)) { + if (uptr->POS > 0) { /* Only if data in record */ + reclen = uptr->hwmark; + sim_debug(DEBUG_CMD, dptr, "Write unit=%02x Block %04x chars\n", + unit, reclen); + r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen); + uptr->POS = 0; + uptr->CMD &= ~MT_CMDMSK; + mt_error(uptr, chsa, r, dptr); /* Record errors */ + } + } else { + mt_buffer[bufnum][uptr->POS++] = ch; + sim_debug(DEBUG_DATA, dptr, "Write data unit=%02x %04x %02x\n", + unit, uptr->POS, ch); + uptr->hwmark = uptr->POS; + goto rewrite; + } + break; + + case MT_RDBK: /* 0x0C */ /* Read Backwards */ + if (uptr->CMD & MT_READDONE) { + uptr->CMD &= ~(MT_CMDMSK|MT_READDONE); + mt_busy[bufnum] &= ~1; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + + /* If at end of record, fill buffer */ + if (BUF_EMPTY(uptr)) { + if (sim_tape_bot(uptr)) { + uptr->CMD &= ~MT_CMDMSK; + mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + sim_debug(DEBUG_CMD, dptr, "Read backward unit=%02x\n", unit); + if ((r = sim_tape_rdrecr(uptr, &mt_buffer[bufnum][0], &reclen, BUFFSIZE)) != MTSE_OK) { + uptr->CMD &= ~(MT_CMDMSK|MT_READDONE); + return mt_error(uptr, chsa, r, dptr); + } + uptr->POS = reclen; + uptr->hwmark = reclen; + sim_debug(DEBUG_CMD, dptr, "Binary Block %04x chars\n", reclen); + } + + ch = mt_buffer[bufnum][--uptr->POS]; + + if (chan_write_byte(chsa, &ch)) { + sim_debug(DEBUG_CMD, dptr, "Read unit=%02x EOR cnt %04x\n", + unit, uptr->POS); + /* If not read whole record, skip till end */ + if (uptr->POS >= 0) { + sim_activate(uptr, (uptr->POS) * 10); + uptr->CMD |= MT_READDONE; + return SCPE_OK; + } + uptr->CMD &= ~MT_CMDMSK; + mt_busy[bufnum] &= ~1; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + } else { + sim_debug(DEBUG_CMD, dptr, "Read data unit=%02x %04x %02x\n", + unit, uptr->POS, ch); + if (uptr->POS == 0) { /* In IRG */ + uptr->CMD &= ~MT_CMDMSK; + mt_busy[bufnum] &= ~1; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + } else + sim_activate(uptr, 30); + } + break; + + case MT_WTM: /* 0x93 */ /* Write tape filemark */ + if (uptr->POS == 0) { + if (sim_tape_wrp(uptr)) { + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= ~MT_CMDMSK; + mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + uptr->POS ++; + sim_activate(uptr, 100); + } else { + sim_debug(DEBUG_CMD, dptr, "Write Mark unit=%02x\n", unit); + uptr->CMD &= ~(MT_CMDMSK); + r = sim_tape_wrtmk(uptr); + chan_end(chsa, SNS_DEVEND); + mt_busy[bufnum] &= ~1; + } + break; + + case MT_BSR: /* 0x53 */ /* Backspace record */ + sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x53 BSR unit %02x POS %x SNS %08x\n", + unit, uptr->POS, uptr->SNS); + switch (uptr->POS ) { + case 0: + if (sim_tape_bot(uptr)) { + uptr->CMD &= ~MT_CMDMSK; + mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + uptr->POS++; + sim_activate(uptr, 30); + break; + case 1: + uptr->POS++; + r = sim_tape_sprecr(uptr, &reclen); + sim_debug(DEBUG_CMD, dptr, "Backspace rec unit %02x POS %x r %x\n", + unit, uptr->POS, r); + /* SEL requires Unit Except & EOF on EOF */ + if (r == MTSE_TMK) { /* test for EOF */ + uptr->POS++; + sim_debug(DEBUG_CMD, dptr, "BSR got EOF MARK\n"); + sim_activate(uptr, 30); + /* SEL requires Unit Except & BOT on BOT */ + } else if (r == MTSE_BOT) { + uptr->POS+= 2; + sim_debug(DEBUG_CMD, dptr, "BSR got BOT\n"); + sim_activate(uptr, 30); + } else { + sim_debug(DEBUG_CMD, dptr, "Backspace reclen %04x SNS %08x\n", reclen, uptr->SNS); + sim_activate(uptr, 30); + } + break; + case 2: + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, "Backspace record completed with NO status\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + case 3: /* EOF */ + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + uptr->SNS |= SNS_FMRKDT; /* file mark detected */ + sim_debug(DEBUG_CMD, dptr, "Backspace record completed with EOF status\n"); + chan_end(chsa, SNS_DEVEND|SNS_UNITEXP); + break; + case 4: /* BOT */ + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + uptr->SNS |= SNS_LOAD; /* set BOT detected */ + sim_debug(DEBUG_CMD, dptr, "Backspace record completed with BOT status\n"); + chan_end(chsa, SNS_DEVEND|SNS_UNITEXP); + break; + } + break; + + case MT_BSF: /* 0x73 */ /* Backspace file */ + sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x73 BSF unit %02x POS %04x\n", + unit, uptr->POS); + switch(uptr->POS) { + case 0: + if (sim_tape_bot(uptr)) { + uptr->CMD &= ~MT_CMDMSK; + mt_busy[bufnum] &= ~1; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + uptr->POS++; + sim_activate(uptr, 100); + break; + case 1: +//#define NBSF +#ifdef NBSF + skip = 1; /* skip 1 file */ +#endif + uptr->SNS &= ~(SNS_LOAD|SNS_EOT|SNS_FMRKDT); /* reset BOT, EOT, EOF */ +#ifdef NBSF + /* using the backspace file call does not work with MPX */ + r = sim_tape_spfiler(uptr, skip, &reclen); + uptr->POS++; +#else + r = sim_tape_sprecr(uptr, &reclen); +#endif + sim_debug(DEBUG_CMD, dptr, "Backspace file unit=%02x r %x\n", unit, r); + if (r == MTSE_TMK) { + uptr->POS++; + sim_debug(DEBUG_CMD, dptr, "BSF got EOF MARK\n"); + sim_activate(uptr, 30); + } else if (r == MTSE_BOT) { + uptr->POS+= 2; + sim_debug(DEBUG_CMD, dptr, "BSF got BOT\n"); + sim_activate(uptr, 30); + } else { + /* already there */ + sim_debug(DEBUG_CMD, dptr, "Backspace file reclen %04x\n", reclen); + sim_activate(uptr, 20); + } + break; +#ifdef NBSF + case 2: + uptr->CMD &= ~(MT_CMDMSK); + /* no EOF detected, but we did go back 1 record */ + uptr->SNS |= SNS_FMRKDT; /* file mark detected */ + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, "Backspace file Completed with NO EOF status\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + break; +#endif +#ifdef NBSF + case 3: /* File Mark */ +#else + case 2: /* File Mark */ +#endif + uptr->CMD &= ~(MT_CMDMSK); + uptr->SNS |= SNS_FMRKDT; /* file mark detected */ + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, "Backspace file Completed with EOF status\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + break; +#ifdef NBSF + case 4: /* BOT */ +#else + case 3: /* BOT */ +#endif + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + uptr->SNS |= SNS_LOAD; /* set BOT detected */ + sim_debug(DEBUG_CMD, dptr, "Backspace file Completed with BOT status\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + break; + } + break; + + case MT_FSR: /* 0x43 */ /* Advance record */ + switch(uptr->POS) { + case 0: + sim_debug(DEBUG_CMD, dptr, "Skip rec entry unit=%02x POS %x\n", unit, uptr->POS); + uptr->POS++; + sim_activate(uptr, 30); + break; + case 1: + uptr->POS++; + uptr->SNS &= ~(SNS_LOAD|SNS_EOT|SNS_FMRKDT); /* reset BOT, EOT, EOF */ + r = sim_tape_sprecf(uptr, &reclen); + sim_debug(DEBUG_CMD, dptr, "Skip rec unit=%02x r %x\n", unit, r); + if (r == MTSE_TMK) { + uptr->POS = 3; + uptr->SNS |= SNS_FMRKDT; /* file mark detected */ + sim_debug(DEBUG_CMD, dptr, "FSR got EOF MARK\n"); + sim_activate(uptr, 30); + } else if (r == MTSE_EOM) { + uptr->POS = 4; + uptr->SNS |= SNS_EOT; /* set EOT status */ + sim_debug(DEBUG_CMD, dptr, "FSR got EOT\n"); + sim_activate(uptr, 30); + } else { + sim_debug(DEBUG_CMD, dptr, "FSR skipped %04x byte record\n", + reclen); + sim_activate(uptr, 30); + } + break; + case 2: + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, "Skip record Completed\n"); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + break; + case 3: + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, "Skip record now at EOF\n"); + chan_end(chsa, SNS_DEVEND|SNS_UNITEXP); + break; + case 4: + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, "Skip record now at EOT\n"); + chan_end(chsa, SNS_DEVEND|SNS_UNITEXP); + break; + } + break; + + case MT_FSF: /* 0x63 */ /* advance filemark */ + switch(uptr->POS) { + case 0: + sim_debug(DEBUG_CMD, dptr, + "Skip file entry sense %08x unit %02x\n", uptr->SNS, unit); + uptr->POS++; + sim_activate(uptr, 30); + break; + case 1: + skip = 1; /* skip forward 1 file */ + uptr->POS++; + uptr->SNS &= ~(SNS_LOAD|SNS_EOT|SNS_FMRKDT); /* reset BOT, EOT, EOF */ + r = sim_tape_spfilef(uptr, skip, &reclen); + sim_debug(DEBUG_CMD, dptr, "Skip file unit=%02x r %x\n", unit, r); + if (r == MTSE_TMK) { + uptr->POS++; + uptr->SNS |= SNS_FMRKDT; /* file mark detected */ + sim_debug(DEBUG_CMD, dptr, "FSF EOF MARK sense %08x\n", uptr->SNS); + sim_activate(uptr, 30); + } else if (r == MTSE_EOM) { + uptr->SNS |= SNS_EOT; /* set EOT status */ + sim_debug(DEBUG_CMD, dptr, "FSF EOT sense %08x\n", uptr->SNS); + uptr->POS+= 2; + sim_activate(uptr, 30); + } else { + sim_debug(DEBUG_CMD, dptr, "FSF skipped %04x file\n", reclen); + sim_activate(uptr, 30); + } + break; + case 2: + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, + "Skip file done sense %08x unit %02x\n", uptr->SNS, unit); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + break; + case 3: + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, + "Skip file got EOF sense %08x unit %02x\n", uptr->SNS, unit); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + break; + case 4: + uptr->CMD &= ~(MT_CMDMSK); + uptr->SNS |= SNS_EOT; /* set EOT status */ + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, + "Skip file got EOT sense %08x unit %02x\n", uptr->SNS, unit); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + break; + } + break; + + case MT_ERG: /* 0xA3 */ /* Erace 3.5 in tape */ + switch (uptr->POS) { + case 0: + if (sim_tape_wrp(uptr)) { + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= ~MT_CMDMSK; + mt_busy[bufnum] &= ~1; + chan_end(chsa, SNS_DEVEND|SNS_UNITEXP); + } else { + uptr->POS ++; + sim_activate(uptr, 50); + } + break; + case 1: + sim_debug(DEBUG_CMD, dptr, "Erase unit=%02x\n", unit); + r = sim_tape_wrgap(uptr, 35); + sim_activate(uptr, 100); + uptr->POS++; + break; + case 2: + uptr->CMD &= ~(MT_CMDMSK); + mt_busy[bufnum] &= ~1; + /* we are done dev|chan end */ + chan_end(chsa, SNS_DEVEND); + break; + } + break; + + case MT_REW: /* 0x23 */ /* rewind tape */ + if (uptr->POS == 0) { + uptr->POS++; + sim_debug(DEBUG_CMD, dptr, "Start rewind unit %02x\n", unit); + sim_activate(uptr, 2500); + } else { + sim_debug(DEBUG_CMD, dptr, "Rewind complete unit %02x\n", unit); + uptr->CMD &= ~(MT_CMDMSK); + r = sim_tape_rewind(uptr); + uptr->SNS |= SNS_LOAD; /* set BOT */ + mt_busy[bufnum] &= ~1; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + } + break; + + case MT_RUN: /* 0x33 */ /* Rewind and unload tape */ + if (uptr->POS == 0) { + uptr->POS++; + mt_busy[bufnum] &= ~1; + sim_debug(DEBUG_CMD, dptr, "Start rewind/unload unit %02x\n", unit); + sim_activate(uptr, 300); + } else { + sim_debug(DEBUG_CMD, dptr, "Unload unit=%02x\n", unit); + uptr->CMD &= ~(MT_CMDMSK); + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ + r = sim_tape_detach(uptr); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ + } + break; + } + return SCPE_OK; +} + +/* initialize the tape chan/unit */ +void mt_ini(UNIT *uptr, t_bool f) +{ + DEVICE *dptr = get_dev(uptr); + if (MT_DENS(uptr->dynflags) == 0) + uptr->dynflags |= MT_DENS_6250 << UNIT_S_DF_TAPE; + + uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */ + uptr->SNS = 0; /* clear sense data */ + uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set initial status */ + mt_busy[GET_DEV_BUF(dptr->flags)] = 0; /* set not busy */ + sim_cancel(uptr); /* cancel any timers */ + sim_debug(DEBUG_EXP, dptr, "MT init device %s unit %02x\n", + dptr->name, GET_UADDR(uptr->CMD)); +} + +/* handle rschnlio cmds for tape */ +t_stat mt_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & MT_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, "mt_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + mt_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +/* Handle haltio transfers for mag tape */ +t_stat mt_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & MT_CMDMSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + DEVICE *dptr = get_dev(uptr); + + sim_debug(DEBUG_EXP, dptr, + "mt_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + if (cmd != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "mt_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + sim_cancel(uptr); /* stop timer */ + } else { + sim_debug(DEBUG_CMD, dptr, + "mt_haltio HIO not busy chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + } + /* stop any I/O and post status and return error status */ + uptr->CMD &= LMASK; /* make non-busy */ + uptr->POS = 0; /* clear position data */ + uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */ + chp->ccw_count = 0; /* zero the count */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + sim_debug(DEBUG_CMD, dptr, + "mt_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ + return SCPE_IOERR; /* tell chan code to post status */ +} +/* reset the mag tape */ +t_stat mt_reset(DEVICE *dptr) +{ + /* nothing to do?? */ + sim_debug(DEBUG_EXP, dptr, "MT reset name %s\n", dptr->name); + return SCPE_OK; +} + +/* attach the specified file to the tape device */ +t_stat mt_attach(UNIT *uptr, CONST char *file) +{ + uint16 chsa = GET_UADDR(uptr->CMD); /* get address of mt device */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + DEVICE *dptr = get_dev(uptr); /* get device pointer */ + t_stat r; + DIB *dibp = 0; + + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, "ERROR===ERROR\nMT device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nMT device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + /* mount the specified file to the MT */ + if ((r = sim_tape_attach(uptr, file)) != SCPE_OK) { + fprintf(sim_deb, "mt_attach ERROR filename %s status %08x\r\n", file, r); + return r; /* report any error */ + } + sim_debug(DEBUG_EXP, dptr, "mt_attach complete filename %s\n", file); + uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */ + uptr->POS = 0; /* clear position data */ + uptr->SNS = 0; /* clear sense data */ + uptr->SNS |= SNS_ONLN; /* 0x40 Drive Online */ + + /* check for valid configured tape */ + /* must have valid DIB and Channel Program pointer */ + dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */ + if ((dib_unit[chsa] == NULL) || (dibp == NULL) || (chp == NULL)) { + sim_debug(DEBUG_CMD, dptr, + "ERROR===ERROR\nMT device %s not configured on system, aborting\n", + dptr->name); + printf("ERROR===ERROR\nMT device %s not configured on system, aborting\r\n", + dptr->name); + fprintf(sim_deb, "ERROR===ERROR\nMT device %s not configured on system, aborting\r\n", + dptr->name); + detach_unit(uptr); /* detach if error */ + return SCPE_UNATT; /* error */ + } + set_devattn(chsa, SNS_DEVEND); /* ready int???? */ + return SCPE_OK; /* return good status */ +} + +/* detach the MT device and unload any tape */ +t_stat mt_detach(UNIT *uptr) +{ + DEVICE *dptr = get_dev(uptr); /* get device pointer */ + sim_debug(DEBUG_EXP, dptr, "mt_detach\n"); + uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */ + uptr->POS = 0; /* clear position data */ + uptr->SNS = 0; /* clear sense data */ + uptr->flags &= ~MTUF_WRP; /* clear write protect */ + uptr->flags &= ~UNIT_RO; /* clear read only */ + return sim_tape_detach(uptr); +} + +/* boot from the specified tape unit */ +t_stat mt_boot(int32 unit_num, DEVICE *dptr) +{ + UNIT *uptr = &dptr->units[unit_num]; /* find tape unit pointer */ + + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nMT device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + sim_debug(DEBUG_EXP, dptr, "MT Boot dev/unit %04x\n", GET_UADDR(uptr->CMD)); + printf("MT Boot dev/unit %04x\r\n", GET_UADDR(uptr->CMD)); + if ((uptr->flags & UNIT_ATT) == 0) { /* Is MT device already attached? */ + sim_debug(DEBUG_EXP, dptr, + "MT Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + printf("MT Boot attach error dev/unit %04x\r\n", GET_UADDR(uptr->CMD)); + return SCPE_UNATT; /* not attached, return error */ + } + SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ + SPAD[0xf8] = 0xF000; /* show as F class device */ + + uptr->CMD &= ~0xffff; /* clear out old status */ + return chan_boot(GET_UADDR(uptr->CMD), dptr); /* boot the ch/sa */ +} + +t_stat mt_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + char buffer[256]; + fprintf (st, "%s\n\n", mt_description(dptr)); + fprintf (st, "The mag tape drives support the BOOT command\n\n"); + (void)sim_tape_density_supported (buffer, sizeof(buffer), valid_dens); + fprintf (st, " The density of the mag tape drive can be set with\n"); + fprintf (st, " SET %s DENSITY=%s\n\n", dptr->name, buffer); + sim_tape_attach_help (st, dptr, uptr, flag, cptr); + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + return SCPE_OK; +} + +const char *mt_description(DEVICE *dptr) +{ + return "8051 Buffered Tape Processor"; +} + +#endif /* NUM_DEVS_MT */ diff --git a/SEL32/sel32_scfi.c b/SEL32/sel32_scfi.c new file mode 100644 index 00000000..8785a199 --- /dev/null +++ b/SEL32/sel32_scfi.c @@ -0,0 +1,1997 @@ +/* sel32_scfi.c: SEL-32 SCFI SCSI Disk Controller + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell and other SIMH contributers + + 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 + JAMES C. BEVIER 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 "sel32_defs.h" + +/* uncomment to use fast sim_activate times when running UTX */ +/* UTX gets an ioi error for dm0801 if slow times are used */ +/* dm0801 is not even a valid unit number for UDP controller */ +#define FAST_FOR_UTX + +#if NUM_DEVS_SCFI > 0 + +#define UNIT_SCFI UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE + +/* useful conversions */ +/* Fill STAR value from cyl, trk, sec data */ +#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff)) +/* convert STAR value to number of sectors */ +#define STAR2SEC(star,spt,spc) ((star&0xff)+(((star>>8)&0xff)*spt)+(((star>>16)&0xffff)*spc)) +/* convert STAR value to number of heads or tracks */ +#define STAR2TRK(star,tpc) (((star>>16)&0xffff)*tpc+((star>>8)&0x0ff)) +/* convert STAR value to number of cylinders */ +#define STAR2CYL(star) ((star>>16)&RMASK) +/* convert byte value to number of sectors mod sector size */ +#define BYTES2SEC(bytes,ssize) (((bytes) + (ssize-1)) >> 10) +/* get sectors per track for specified type */ +#define SPT(type) (scfi_type[type].spt) +/* get sectors per cylinder for specified type */ +#define SPC(type) (scfi_type[type].spt*scfi_type[type].nhds) +/* get number of tracks for specified type */ +#define TRK(type) (scfi_type[type].cyl*scfi_type[type].nhds) +/* get number of cylinders for specified type */ +#define CYL(type) (scfi_type[type].cyl) +/* get number of heads for specified type */ +#define HDS(type) (scfi_type[type].nhds) +/* get disk capacity in sectors for specified type */ +#define CAP(type) (CYL(type)*HDS(type)*SPT(type)) +/* get number of bytes per sector for specified type */ +#define SSB(type) (scfi_type[type].ssiz*4) +/* get disk capacity in bytes for specified type */ +#define CAPB(type) (CAP(type)*SSB(type)) +/* get disk geometry as STAR value for specified type */ +#define GEOM(type) (CHS2STAR(CYL(type),HDS(type),SPT(type))) + +/* INCH command information */ +/* +WD 0 - Data address +WD 1 - Flags - 0 -36 byte count + +Data - 224 word INCH buffer address (SST) +WD 1 Drive 0 Attribute register +WD 2 Drive 1 Attribute register +WD 3 Drive 2 Attribute register +WD 4 Drive 3 Attribute register +WD 5 Drive 4 Attribute register +WD 6 Drive 5 Attribute register +WD 7 Drive 6 Attribute register +WD 8 Drive 7 Attribute register + +Memory attribute register layout +bits 0-7 - Flags + bits 0&1 - 00=Reserved, 01=MHD, 10=FHD, 11=MHD with FHD option + bit 2 - 1=Cartridge module drive + bit 3 - 0=Reserved + bit 4 - 1=Drive not present + bit 5 - 1=Dual Port + bit 6&7 - 0=Reserved +bits 8-15 - sector count (sectors per track)(F16=16, F20=20) +bits 16-23 - MHD Head count (number of heads on MHD) +bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option of + mini-module) +*/ + +/* 224 word INCH Buffer layout */ +/* 128 word subchannel status storage (SST) */ +/* 66 words of program status queue (PSQ) */ +/* 26 words of scratchpad */ +/* 4 words of label buffer registers */ + +#define CMD u3 +/* u3 */ +/* in u3 is device command code and status */ +#define DSK_CMDMSK 0x00ff /* Command being run */ +#define DSK_STAR 0x0100 /* STAR value in u4 */ +#define DSK_NU2 0x0200 /* */ +#define DSK_READDONE 0x0400 /* Read finished, end channel */ +#define DSK_ENDDSK 0x0800 /* Sensed end of disk */ +#define DSK_SEEKING 0x1000 /* Disk is currently seeking */ +#define DSK_READING 0x2000 /* Disk is reading data */ +#define DSK_WRITING 0x4000 /* Disk is writing data */ +#define DSK_BUSY 0x8000 /* Disk is busy */ +/* commands */ +#define DSK_INCH 0x00 /* Initialize channel */ +#define DSK_ICH 0xFF /* Initialize controller */ +#define DSK_INCH2 0xF0 /* Initialize channel for processing */ +#define DSK_WD 0x01 /* Write data */ +#define DSK_RD 0x02 /* Read data */ +#define DSK_NOP 0x03 /* No operation */ +#define DSK_SNS 0x04 /* Sense */ +#define DSK_SCK 0x07 /* Seek cylinder, track, sector */ +#define DSK_TIC 0x08 /* Transfer in channel */ +#define DSK_FNSK 0x0B /* Format for no skip */ +#define DSK_LPL 0x13 /* Lock protected label */ +#define DSK_LMR 0x1F /* Load mode register */ +#define DSK_RES 0x23 /* Reserve */ +#define DSK_WSL 0x31 /* Write sector label */ +#define DSK_RSL 0x32 /* Read sector label */ +#define DSK_REL 0x33 /* Release */ +#define DSK_XEZ 0x37 /* Rezero */ +#define DSK_POR 0x43 /* Priority Override */ +#define DSK_IHA 0x47 /* Increment head address */ +#define DSK_SRM 0x4F /* Set reserve track mode */ +#define DSK_WTL 0x51 /* Write track label */ +#define DSK_RTL 0x52 /* Read track label */ +#define DSK_XRM 0x5F /* Reset reserve track mode */ +#define DSK_RAP 0xA2 /* Read angular positions */ +#define DSK_TESS 0xAB /* Test STAR (subchannel target address register) */ +#define DSK_REC 0xB2 /* Read ECC correction mask */ +#define DSK_ICH 0xFF /* Initialize Controller */ + +#define STAR u4 +/* u4 - sector target address register (STAR) */ +/* Holds the current cylinder, head(track), sector */ +#define DISK_CYL 0xFFFF0000 /* cylinder mask */ +#define DISK_TRACK 0x0000FF00 /* track mask */ +#define DISK_SECTOR 0x000000ff /* sector mask */ + +#define SNS u5 +/* u5 */ +/* Sense byte 0 - mode register */ +#define SNS_DROFF 0x80000000 /* Drive Carriage will be offset */ +#define SNS_TRKOFF 0x40000000 /* Track offset: 0=positive, 1=negative */ +#define SNS_RDTMOFF 0x20000000 /* Read timing offset = 1 */ +#define SNS_RDSTRBT 0x10000000 /* Read strobe timing: 1=positive, 0=negative */ +#define SNS_DIAGMOD 0x08000000 /* Diagnostic Mode ECC Code generation and checking */ +#define SNS_RSVTRK 0x04000000 /* Reserve Track mode: 1=OK to write, 0=read only */ +#define SNS_FHDOPT 0x02000000 /* FHD or FHD option = 1 */ +#define SNS_RESERV 0x01000000 /* Reserved */ + +/* Sense byte 1 */ +#define SNS_CMDREJ 0x800000 /* Command reject */ +#define SNS_INTVENT 0x400000 /* Unit intervention required */ +#define SNS_SPARE1 0x200000 /* Spare */ +#define SNS_EQUCHK 0x100000 /* Equipment check */ +#define SNS_DATCHK 0x080000 /* Data Check */ +#define SNS_OVRRUN 0x040000 /* Data overrun/underrun */ +#define SNS_DSKFERR 0x020000 /* Disk format error */ +#define SNS_DEFTRK 0x010000 /* Defective track encountered */ + +/* Sense byte 2 */ +#define SNS_LAST 0x8000 /* Last track flag encountered */ +#define SNS_AATT 0x4000 /* At Alternate track */ +#define SNS_WPER 0x2000 /* Write protection error */ +#define SNS_WRL 0x1000 /* Write lock error */ +#define SNS_MOCK 0x0800 /* Mode check */ +#define SNS_INAD 0x0400 /* Invalid memory address */ +#define SNS_RELF 0x0200 /* Release fault */ +#define SNS_CHER 0x0100 /* Chaining error */ + +/* Sense byte 3 */ +#define SNS_REVL 0x80 /* Revolution lost */ +#define SNS_DADE 0x40 /* Disc addressing or seek error */ +#define SNS_BUCK 0x20 /* Buffer check */ +#define SNS_ECCS 0x10 /* ECC error in sector label */ +#define SNS_ECCD 0x08 /* ECC error in data */ +#define SNS_ECCT 0x04 /* ECC error in track label */ +#define SNS_RTAE 0x02 /* Reserve track access error */ +#define SNS_UESS 0x01 /* Uncorrectable ECC error */ + +#define SNS2 us9 +/* us9 */ +/* us9 holds bytes 4 & 5 of the status for the drive */ + +/* Sense byte 4 */ +#define SNS_SEND 0x8000 /* Seek End */ +#define SNS_USEL 0x4000 /* Unit Selected */ +#define SNS_SPC0 0x2000 /* Sector Pulse Count B0 */ +#define SNS_SPC1 0x1000 /* Sector Pulse Count B1 */ +#define SNS_SPC2 0x0800 /* Sector Pulse Count B2 */ +#define SNS_SPC3 0x0400 /* Sector Pulse Count B3 */ +#define SNS_SPC4 0x0200 /* Sector Pulse Count B4 */ +#define SNS_SPC5 0x0100 /* Sector Pulse Count B5 */ + +/* Sense byte 5 */ +#define SNS_FLT 0x80 /* Disk Drive fault */ +#define SNS_SKER 0x40 /* Seek error */ +#define SNS_ONC 0x20 /* On Cylinder */ +#define SNS_UNR 0x10 /* Unit Ready */ +#define SNS_WRP 0x08 /* Write Protected */ +#define SNS_BUSY 0x04 /* Drive is busy */ +#define SNS_NU1 0x02 /* Spare 1 */ +#define SNS_NU2 0x01 /* Spare 2 */ + +#define CHS u6 +/* u6 holds the current cyl, hd, sec for the drive */ + +/* this attribute information is provided by the INCH command */ +/* for each device and is not used. It is reconstructed from */ +/* the scfi_t structure data for the assigned disk */ +/* +bits 0-7 - Flags + bits 0&1 - 00=Reserved, 01=MHD, 10=FHD, 11=MHD with FHD option + bit 2 - 1=Cartridge module drive + bit 3 - 0=Reserved + bit 4 - 1=Drive not present + bit 5 - 1=Dual Port + bit 6 - 0=Reserved 00 768 byte sec + bit 7 - 0=Reserved 01 1024 byte sec +bits 8-15 - sector count (sectors per track)(F16=16, F20=20) +bits 16-23 - MHD Head count (number of heads on MHD) +bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option of + mini-module) +*/ + +/* Not Used up7 */ + +/* disk definition structure */ +struct scfi_t +{ + const char *name; /* Device ID Name */ + uint16 nhds; /* Number of heads */ + uint16 ssiz; /* sector size in words */ + uint16 spt; /* # sectors per track(head) */ + uint16 ucyl; /* Number of cylinders used */ + uint16 cyl; /* Number of cylinders on disk */ + uint8 type; /* Device type code */ + /* bit 1 mhd */ + /* bits 6/7 = 0 768 byte blk */ /* not used on UDP/DPII */ + /* = 1 1024 byte blk */ /* not used on UDP/DPII */ +} + +/* BM SIZ TOT AL U */ +/* DF0B, 1, 8, 20, 192, 1, 1712, 54760, SF336 */ +/* DF0C, 1, 8, 20, 192, 1, 4082, 130612, SG102 */ +/* DF0D, 1, 8, 20, 192, 1, 3491, 111705, SG654 */ +/* */ +/* DF0B, 1, 8, 20, 192, 1, 1711, 54752, SG038 */ +/* DF0C, 1, 16, 20, 192, 1, 2732, 87424, SG120 */ +/* DF0D, 1, 8, 20, 192, 1, 3491, 111680, SG076 */ +/* DF0E, 1, 16, 20, 192, 1, 2732, 87424, SG121 */ +scfi_type[] = +{ + /* Class F Disc Devices */ + /* MPX SCSI disks for SCFI controller */ + {"MH1GB", 1, 192, 40, 34960, 34960, 0x40}, /*0 69920 1000M */ + {"SG038", 1, 192, 20, 21900, 21900, 0x40}, /*1 21900 38M */ + {"SG120", 1, 192, 40, 34970, 34970, 0x40}, /*2 69940 1200M */ + {"SG076", 1, 192, 20, 46725, 46725, 0x40}, /*3 46725 760M */ + {"SG121", 1, 192, 20, 34970, 34970, 0x40}, /*4 69940 1210M */ + {"SD150", 9, 192, 24, 963, 967, 0x40}, /*5 8820 150M 208872 sec */ + {"SD300", 9, 192, 32, 1405, 1409, 0x40}, /*6 8828 300M 396674 sec */ + {"SD700", 15, 192, 35, 1542, 1546, 0x40}, /*7 8833 700M 797129 sec */ + {"SD1200",15, 192, 49, 1927, 1931, 0x40}, /*8 8835 1200M 1389584 sec */ + {NULL, 0} +}; + +t_stat scfi_preio(UNIT *uptr, uint16 chan); +t_stat scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); +t_stat scfi_haltio(UNIT *uptr); +t_stat scfi_iocl(CHANP *chp, int32 tic_ok); +t_stat scfi_srv(UNIT *uptr); +t_stat scfi_boot(int32 unitnum, DEVICE *dptr); +void scfi_ini(UNIT *, t_bool); +t_stat scfi_rschnlio(UNIT *uptr); +t_stat scfi_reset(DEVICE *); +t_stat scfi_attach(UNIT *, CONST char *); +t_stat scfi_detach(UNIT *); +t_stat scfi_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat scfi_get_type(FILE *st, UNIT *uptr, int32 v, CONST void *desc); +t_stat scfi_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *scfi_description (DEVICE *dptr); +extern uint32 inbusy; +extern uint32 outbusy; +extern uint32 readfull(CHANP *chp, uint32 maddr, uint32 *word); +extern int irq_pend; /* go scan for pending int or I/O */ +extern UNIT itm_unit; +extern uint32 PSD[]; /* PSD */ +extern uint32 cont_chan(uint16 chsa); + +/* channel program information */ +CHANP sda_chp[NUM_UNITS_SCFI] = {0}; + +MTAB scfi_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "TYPE", "TYPE", + &scfi_set_type, &scfi_get_type, NULL, "Type of disk"}, + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, + &show_dev_addr, NULL, "Device channel address"}, + {0}, +}; + +UNIT sda_unit[] = { +/* SET_TYPE(2) SG120 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(2), 0), 0, UNIT_ADDR(0x400)}, /* 0 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(2), 0), 0, UNIT_ADDR(0x410)}, /* 1 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(2), 0), 0, UNIT_ADDR(0x420)}, /* 2 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(2), 0), 0, UNIT_ADDR(0x430)}, /* 3 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(2), 0), 0, UNIT_ADDR(0x440)}, /* 4 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(2), 0), 0, UNIT_ADDR(0x450)}, /* 5 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(2), 0), 0, UNIT_ADDR(0x460)}, /* 6 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(2), 0), 0, UNIT_ADDR(0x470)}, /* 7 */ +}; + +DIB sda_dib = { + scfi_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + scfi_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + scfi_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + scfi_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + scfi_iocl, /* t_stat (*iocl_io)(CHANP *chp, int32 tik_ok)) */ /* Process IOCL */ + scfi_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + sda_unit, /* UNIT* units */ /* Pointer to units structure */ + sda_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_SCFI, /* uint8 numunits */ /* number of units defined */ + 0x70, /* uint8 mask */ /* 8 devices - device mask */ + 0x0400, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0}, /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE sda_dev = { + "SDA", sda_unit, NULL/*sda_reg*/, scfi_mod, + NUM_UNITS_SCFI, 16, 24, 4, 16, 32, + NULL, NULL, &scfi_reset, &scfi_boot, &scfi_attach, &scfi_detach, + /* ctxt is the DIB pointer */ + &sda_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &scfi_help, NULL, NULL, &scfi_description +}; + +#if NUM_DEVS_SCFI > 1 +/* channel program information */ +CHANP sdb_chp[NUM_UNITS_SCFI] = {0}; + +UNIT sdb_unit[] = { +/* SET_TYPE(0) DM1GB */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(0), 0), 0, UNIT_ADDR(0xC00)}, /* 0 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(0), 0), 0, UNIT_ADDR(0xC10)}, /* 1 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(0), 0), 0, UNIT_ADDR(0xC20)}, /* 2 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(0), 0), 0, UNIT_ADDR(0xC30)}, /* 3 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(0), 0), 0, UNIT_ADDR(0xC40)}, /* 4 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(0), 0), 0, UNIT_ADDR(0xC50)}, /* 5 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(0), 0), 0, UNIT_ADDR(0xC60)}, /* 6 */ + {UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(0), 0), 0, UNIT_ADDR(0xC70)}, /* 7 */ +}; + +DIB sdb_dib = { + scfi_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + scfi_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + scfi_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + scfi_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + scfi_iocl, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + scfi_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + sdb_unit, /* UNIT* units */ /* Pointer to units structure */ + sdb_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_SCFI, /* uint8 numunits */ /* number of units defined */ + 0x70, /* uint8 mask */ /* 16 devices - device mask */ + 0x0C00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0}, /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE sdb_dev = { + "SDB", sdb_unit, NULL, /*sdb_reg*/, scfi_mod, + NUM_UNITS_SCFI, 16, 24, 4, 16, 32, + NULL, NULL, &scfi_reset, &scfi_boot, &scfi_attach, &scfi_detach, + /* ctxt is the DIB pointer */ + &sdb_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &scfi_help, NULL, NULL, &scfi_description +}; +#endif + +/* convert sector disk address to star values (c,h,s) */ +uint32 scfisec2star(uint32 daddr, int type) +{ + uint32 sec = daddr % scfi_type[type].spt; /* get sector value */ + uint32 spc = scfi_type[type].nhds * scfi_type[type].spt; /* sec per cyl */ + uint32 cyl = daddr / spc; /* cylinders */ + uint32 hds = (daddr % spc) / scfi_type[type].spt; /* heads */ + + /* now return the star value */ + return (CHS2STAR(cyl,hds,sec)); /* return STAR */ +} + +/* start a disk operation */ +t_stat scfi_preio(UNIT *uptr, uint16 chan) +{ + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int unit = (uptr - dptr->units); + + sim_debug(DEBUG_DETAIL, dptr, + "scfi_preio CMD %08x unit %02x\n", uptr->CMD, unit); + if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */ + return SNS_BSY; + } + + sim_debug(DEBUG_DETAIL, dptr, + "scfi_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + +/* load in the IOCD and process the commands */ +/* return = 0 OK */ +/* return = 1 error, chan_status will have reason */ +t_stat scfi_iocl(CHANP *chp, int32 tic_ok) +{ + uint32 word1 = 0; + uint32 word2 = 0; + int32 docmd = 0; + UNIT *uptr = chp->unitptr; /* get the unit ptr */ + uint16 chan = get_chan(chp->chan_dev); /* our channel */ + uint16 chsa = chp->chan_dev; /* our chan/sa */ + uint16 devstat = 0; + DEVICE *dptr = get_dev(uptr); + + /* check for valid iocd address if 1st iocd */ + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + if (chp->chan_caw & 0x3) { /* must be word bounded */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl iocd bad address chsa %02x caw %06x\n", + chsa, chp->chan_caw); + chp->ccw_addr = chp->chan_caw; /* set the bad iocl address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + return 1; /* error return */ + } + } +loop: + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl @%06x entry PSD %08x chan_status[%04x] %04x\n", + chp->chan_caw, PSD[0], chan, chp->chan_status); + + /* Abort if we have any errors */ + if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl ERROR1 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* return error */ + } + + /* Read in first CCW */ + if (readfull(chp, chp->chan_caw, &word1) != 0) { /* read word1 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl ERROR2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Read in second CCW */ + if (readfull(chp, chp->chan_caw+4, &word2) != 0) { /* read word2 from memory */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl ERROR3 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + sim_debug(DEBUG_CMD, dptr, + "scfi_iocl @%06x read ccw chan %02x IOCD wd 1 %08x wd 2 %08x\n", + chp->chan_caw, chan, word1, word2); + + chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */ + + /* Check if we had data chaining in previous iocd */ + /* if we did, use previous cmd value */ + if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + (chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "scfi_iocl @%06x DO DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + } else + chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ + + if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl bad IOCD1 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2 */ + + /* validate the commands for the disk */ + switch (chp->ccw_cmd) { + case DSK_WD: case DSK_RD: case DSK_INCH: case DSK_NOP: case DSK_ICH: + case DSK_SCK: case DSK_XEZ: case DSK_LMR: case DSK_WSL: case DSK_RSL: + case DSK_IHA: case DSK_WTL: case DSK_RTL: case DSK_RAP: case DSK_TESS: + case DSK_FNSK: case DSK_REL: case DSK_RES: case DSK_POR: case DSK_TIC: + case DSK_REC: + case DSK_SNS: + break; + default: + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl bad cmd chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + /* 1st command can not be a TIC or NOP */ + if ((chp->ccw_cmd == DSK_NOP) || (chp->ccw_cmd == CMD_TIC)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl TIC/NOP bad cmd chan_status[%04x] %04x\n", + chan, chp->chan_status); + return 1; /* error return */ + } + } + + /* TIC can't follow TIC or be first in command chain */ + /* diags send bad commands for testing. Use all of op */ + if (chp->ccw_cmd == CMD_TIC) { + if (tic_ok) { + if (((word1 & MASK24) == 0) || (word1 & 0x3)) { + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl tic cmd bad address chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + uptr->SNS |= SNS_INAD; /* invalid address status */ + return 1; /* error return */ + } + tic_ok = 0; /* another tic not allowed */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + sim_debug(DEBUG_CMD, dptr, + "scfi_iocl tic cmd ccw chan %02x tic caw %06x IOCD wd 1 %08x\n", + chan, chp->chan_caw, word1); + goto loop; /* restart the IOCD processing */ + } + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */ + if (((word1 & MASK24) == 0) || (word1 & 0x3)) + uptr->SNS |= SNS_INAD; /* invalid address status */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl TIC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* Check if we had data chaining in previous iocd */ + if ((chp->chan_info & INFO_SIOCD) || /* see if 1st IOCD in channel prog */ + (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + ((chp->ccw_flags & FLAG_DC) == 0))) { /* last IOCD have DC set? */ + sim_debug(DEBUG_CMD, dptr, + "scfi_iocl @%06x DO CMD No DC, ccw_flags %04x cmd %02x\n", + chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); + docmd = 1; /* show we have a command */ + } + + /* Set up for this command */ + chp->ccw_flags = (word2 >> 16) & 0xf000; /* get flags from bits 0-4 of WD 2 of IOCD */ + chp->chan_status = 0; /* clear status for next IOCD */ + /* make a 24 bit address */ + chp->ccw_addr = word1 & MASK24; /* set the data/seek address */ + + /* validate parts of IOCD2 that are reserved */ + if (word2 & 0x0fff0000) { /* bits 5-15 must be zero */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl IOCD2 chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + + /* DC can only be used with a read/write cmd */ + if (chp->ccw_flags & FLAG_DC) { + if ((chp->ccw_cmd != DSK_RD) && (chp->ccw_cmd != DSK_WD)) { + chp->chan_status |= STATUS_PCHK; /* program check for invalid DC */ + uptr->SNS |= SNS_CHER; /* chaining error */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl DC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); + return 1; /* error return */ + } + } + + chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ + + sim_debug(DEBUG_XIO, dptr, + "scfi_iocl @%06x read docmd %01x addr %06x count %04x chan %04x ccw_flags %04x\n", + chp->chan_caw, docmd, chp->ccw_addr, chp->ccw_count, chan, chp->ccw_flags); + + if (docmd) { /* see if we need to process a command */ + DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ + + uptr = chp->unitptr; /* get the unit ptr */ + if (dibp == 0 || uptr == 0) { + chp->chan_status |= STATUS_PCHK; /* program check if it is */ + return 1; /* if none, error */ + } + + sim_debug(DEBUG_XIO, dptr, + "scfi_iocl @%06x before start_cmd chan %04x status %04x count %04x SNS %08x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, uptr->u5); + + /* call the device startcmd function to process the current command */ + /* just replace device status bits */ + chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ + devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd); + chp->chan_status = (chp->chan_status & 0xff00) | devstat; + chp->chan_info &= ~INFO_SIOCD; /* show not first IOCD in channel prog */ + + sim_debug(DEBUG_XIO, dptr, + "scfi_iocl @%06x after start_cmd chan %04x status %08x count %04x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count); + + /* see if bad status */ + if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) { + chp->chan_status |= STATUS_CEND; /* channel end status */ + chp->ccw_flags = 0; /* no flags */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + sim_debug(DEBUG_EXP, dptr, + "scfi_iocl bad status chsa %04x status %04x cmd %02x\n", + chsa, chp->chan_status, chp->ccw_cmd); + /* done with command */ + sim_debug(DEBUG_EXP, &cpu_dev, + "scfi_iocl ERROR return chsa %04x status %08x\n", + chp->chan_dev, chp->chan_status); + return 1; /* error return */ + } + /* NOTE this code needed for MPX 1.X to run! */ + /* see if command completed */ + /* we have good status */ + if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + sim_debug(DEBUG_XIO, dptr, + "scfi_iocl @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n", + chp->chan_caw, FIFO_Num(chsa), chan, chp->chan_status, chp->ccw_count); + } + } + /* the device processor returned OK (0), so wait for I/O to complete */ + /* nothing happening, so return */ + sim_debug(DEBUG_XIO, dptr, + "scfi_iocl @%06x return, chan %04x status %04x count %04x irq_pend %1x\n", + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, irq_pend); + return 0; /* good return */ +} + +t_stat scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int32 unit = (uptr - dptr->units); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_CMD, dptr, + "scfi_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n", + chsa, unit, cmd, uptr->CMD); + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + sim_debug(DEBUG_EXP, dptr, "scfi_startcmd unit %02x not attached\n", unit); + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + if (cmd != DSK_SNS) /* we are completed with unit check status */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; + } + + if ((uptr->CMD & DSK_CMDMSK) != 0) { + sim_debug(DEBUG_EXP, dptr, "scfi_startcmd unit %02x busy\n", unit); + uptr->CMD |= DSK_BUSY; /* Flag we are busy */ + return SNS_BSY; + } + uptr->SNS2 |= SNS_USEL; /* unit selected */ + sim_debug(DEBUG_CMD, dptr, + "scfi_startcmd CMD continue unit=%02x cmd %02x iocla %06x cnt %04x\n", + unit, cmd, chp->chan_caw, chp->ccw_count); + + /* Unit is online, so process a command */ + switch (cmd) { + + case DSK_INCH: /* INCH cmd 0x0 */ + sim_debug(DEBUG_CMD, dptr, + "scfi_startcmd starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n", + chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count); + + uptr->SNS &= ~SNS_CMDREJ; /* not rejected yet */ + uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */ +#ifdef FAST_FOR_UTX + sim_activate(uptr, 20); /* start things off */ +#else + sim_activate(uptr, 250); /* start things off */ +#endif + return SCPE_OK; /* good to go */ + break; + + case DSK_NOP: /* NOP 0x03 */ + if ((cmd == DSK_NOP) && + (chp->chan_info & INFO_SIOCD)) { /* is NOP 1st IOCD? */ + chp->chan_caw -= 8; /* backup iocd address for diags */ + break; /* yes, can't be 1st */ + } + case DSK_ICH: /* 0xFF Initialize controller */ + case DSK_SCK: /* Seek command 0x07 */ + case DSK_XEZ: /* Rezero & Read IPL record 0x37 */ + case DSK_WD: /* Write command 0x01 */ + case DSK_RD: /* Read command 0x02 */ + case DSK_LMR: /* read mode register 0x1F */ + case DSK_WSL: /* WSL 0x31 */ + case DSK_RSL: /* RSL 0x32 */ + case DSK_IHA: /* 0x47 Increment head address */ + case DSK_WTL: /* WTL 0x51 */ + case DSK_RTL: /* RTL 0x52 */ + case DSK_RAP: /* 0xA2 Read angular positions */ + case DSK_TESS: /* TESS 0xAB Test STAR */ + case DSK_FNSK: /* 0x0B Format for no skip */ + case DSK_REC: /* 0xB2 Read ECC correction mask */ + case DSK_RES: /* 0x23 Reserve */ + case DSK_REL: /* 0x33 Release */ + uptr->SNS &= ~MASK24; /* clear data & leave mode */ + uptr->SNS2 = (SNS_UNR|SNS_ONC|SNS_USEL);/* reset status to on cyl & ready */ + case DSK_SNS: /* Sense 0x04 */ + uptr->CMD |= cmd; /* save cmd */ + sim_debug(DEBUG_CMD, dptr, + "scfi_startcmd starting disk cmd %02x chsa %04x\n", + cmd, chsa); +#ifdef FAST_FOR_UTX + sim_activate(uptr, 20); /* start things off */ +#else + sim_activate(uptr, 250); /* start things off */ +#endif + return SCPE_OK; /* good to go */ + break; + } + + sim_debug(DEBUG_EXP, dptr, + "scfi_startcmd done with bad disk cmd %02x chsa %04x SNS %08x\n", + cmd, chsa, uptr->SNS); + uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ + return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* return error */ +} + +/* Handle haltio transfers for disk */ +t_stat scfi_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int cmd = uptr->CMD & DSK_CMDMSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_EXP, dptr, + "scfi_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "scfi_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + /* stop any I/O and post status and return error status */ + sim_cancel(uptr); /* clear the input timer */ + chp->ccw_count = 0; /* zero the count */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* stop any chaining */ + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + sim_debug(DEBUG_CMD, dptr, + "scfi_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force end */ + return CC1BIT | SCPE_IOERR; /* DIAGS want just an interrupt */ + } + uptr->CMD &= LMASK; /* make non-busy */ + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + sim_debug(DEBUG_CMD, dptr, + "scfi_haltio HIO I/O not busy chsa %04x cmd = %02x\n", chsa, cmd); + return CC1BIT | SCPE_OK; /* not busy return */ +} + +/* Handle processing of disk requests. */ +t_stat scfi_srv(UNIT *uptr) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + CHANP *chp = find_chanp_ptr(chsa);/* get channel prog pointer */ + int cmd = uptr->CMD & DSK_CMDMSK; + int type = GET_TYPE(uptr->flags); + uint32 tcyl=0, trk=0, cyl=0, sec=0; + int unit = (uptr - dptr->units); + int len = chp->ccw_count; + int i; + uint32 mema; /* memory address */ + uint8 ch; + uint16 ssize = scfi_type[type].ssiz * 4; /* disk sector size in bytes */ + uint32 tstart; + uint8 buf[1024]; + uint8 buf2[1024]; + + sim_debug(DEBUG_CMD, dptr, + "scfi_srv entry unit %02x CMD %08x chsa %04x count %04x %x/%x/%x \n", + unit, uptr->CMD, chsa, chp->ccw_count, + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + if (cmd != DSK_SNS) { /* we are completed with unit check status */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + } + + sim_debug(DEBUG_CMD, dptr, + "scfi_srv cmd=%02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count); + + switch (cmd) { + case 0: /* No command, stop disk */ + break; + + case DSK_ICH: /* 0xFF Initialize controller */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "scfi_srv cmd CONT ICH %06x chsa %04x addr %06x count %04x completed\n", + chp->chan_inch_addr, chsa, mema, chp->ccw_count); + if (len == 0x14) { + /* read all 20 bytes, stopping every 4 bytes to make words */ + /* the first word has the inch buffer address */ + /* the next 4 words have drive data for each unit */ + /* WARNING 4 drives must be defined for this controller */ + /* so we will not have a map fault */ + for (i=0; i < 20; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (((i+1)%4) == 0) { /* see if we have a word yet */ + if (i == 3) { + /* inch buffer address */ + mema = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | (buf[3]); + sim_debug(DEBUG_CMD, dptr, + "scfi_srv cmd CONT ICH %06x chsa %04x mema %06x completed\n", + chp->chan_inch_addr, chsa, mema); + } else { + /* drive attribute registers */ + /* may want to use this later */ + /* clear warning errors */ + tstart = (buf[i-3]<<24) | (buf[i-2]<<16) | (buf[i-1]<<8) | (buf[i]); + sim_debug(DEBUG_CMD, dptr, + "scfi_srv cmd CONT ICH %06x chsa %04x data %06x completed\n", + chp->chan_inch_addr, chsa, tstart); + } + } + } + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + } + + /* to use this inch method, byte count must be 896 */ + if (len != 896) { + /* we have invalid count, error, bail out */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* now call set_inch() function to write and test inch buffer addresses */ + /* 1-224 wd buffer is provided, status is 128 words offset from start */ + mema += (128*4); /* offset to inch buffers */ + tstart = set_inch(uptr, mema, 33); /* new address of 33 entries */ + if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + case DSK_INCH2: /* use 0xF0 for inch, just need int */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "scfi_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n", + chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count); + + /* mema has IOCD word 1 contents. For the disk processor it contains */ + /* a pointer to the INCH buffer followed by 8 drive attribute words that */ + /* contains the flags, sector count, MHD head count, and FHD count */ + /* len has the byte count from IOCD wd2 and should be 0x24 (36) */ + /* the INCH buffer address must be set for the parent channel as well */ + /* as all other devices on the channel. Call set_inch() to do this for us */ + /* just return OK and channel software will use u4 as status buffer addr */ + + /* see if New SCFI controller */ + if (len == 4) { + /* get just the INCH addr */ + for (i=0; i < 4; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + } + /* inch buffer address */ + mema = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | (buf[3]); + goto gohere; + } + + if (len != 36) { + /* we have invalid count, error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* read all 36 bytes, stopping every 4 bytes to make words */ + /* the first word has the inch buffer address */ + /* the next 8 words have drive data for each unit */ + /* WARNING 8 drives must be defined for this controller */ + /* so we will not have a map fault */ + for (i=0; i < 36; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (((i+1)%4) == 0) { /* see if we have a word yet */ + if (i == 3) + /* inch buffer address */ + mema = (buf[0]<<24) | (buf[1]<<16) | + (buf[2]<<8) | (buf[3]); + else + /* drive attribute registers */ + /* may want to use this later */ + /* clear warning errors */ + tstart = (buf[i-3]<<24) | (buf[i-2]<<16) + | (buf[i-1]<<8) | (buf[i]); + } + } +gohere: + /* now call set_inch() function to write and test inch buffer addresses */ + /* 1-224 wd buffer is provided, status is 128 words offset from start */ + mema += (128*4); /* offset to inch buffers */ + i = set_inch(uptr, mema, 33); /* new address of 33 entries */ + if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "scfi_srv cmd INCH %06x chsa %04x addr %06x count %04x completed\n", + chp->chan_inch_addr, chsa, mema, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_RES: /* 0x23 Reserve */ + case DSK_REL: /* 0x33 Release */ + case DSK_POR: /* 0x43 Priority Override */ + case DSK_REC: /* 0xB2 Read ECC correction mask */ + case DSK_TESS: /* 0xAB Test STAR (subchannel target address register) */ + case DSK_FNSK: /* 0x0B Format for no skip */ + case DSK_RAP: /* 0xA2 Read angular positions */ + case DSK_IHA: /* 0x47 Increment head address */ + case DSK_RSL: /* RSL 0x32 */ + case DSK_WSL: /* WSL 0x31 write sector labels */ + case DSK_RTL: /* RTL 0x52 */ + case DSK_WTL: /* WTL 0x51 */ + case DSK_NOP: /* NOP 0x03 */ + /* diags want chan prog check and cmd reject if 1st cmd of IOCL */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "scfi_srv cmd NOP chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_SNS: /* 0x04 */ /* Sense */ + sim_debug(DEBUG_CMD, dptr, "scfi_startcmd CMD sense\n"); + + /* count must be 12 or 14, if not prog check */ + if (len != 12 && len != 14) { + sim_debug(DEBUG_CMD, dptr, + "scfi_srv Sense bad count unit=%02x count%04x\n", unit, len); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK|STATUS_LENGTH); + break; + } + /* bytes 0,1 - Cyl entry from CHS reg */ + ch = (uptr->CHS >> 24) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense CHS b0 unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->CHS >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense CHS b1 unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 2 - Track entry from CHS reg */ + ch = (uptr->CHS >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense CHS b2 unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 3 - Sector entry from CHS reg */ + ch = (uptr->CHS) & 0xff; + sec = ch; + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense CHS b3 unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 4 - mode reg, byte 0 of SNS */ + ch = (uptr->SNS >> 24) & 0xff; /* return the sense data */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* bytes 5-7 - status bytes, bytes 1-3 of SNS */ + ch = (uptr->SNS >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 8-11 - drive mode register entries from assigned disk */ + ch = scfi_type[type].type & 0x40; /* zero bits 0, 2-7 in type byte */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv datr unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = scfi_type[type].spt & 0xff; /* get sectors per track */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv datr unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = scfi_type[type].nhds & 0xff; /* get # MHD heads */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv datr unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = 0; /* no FHD heads */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv datr unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 12 & 13 are optional, so check if read done */ + /* TODO add drive status bits here */ + if ((test_write_byte_end(chsa)) == 0) { + /* bytes 12 & 13 contain drive related status */ + uptr->SNS2 |= (SNS_SEND|SNS_USEL); /* selected & seek end */ + /* bits 2-7 have sector pulse count */ + ch = ((sec * 2) % SPT(type)) & 0x3f;/* get index cnt */ + uptr->SNS2 = (uptr->SNS2 & 0xc0ff) | ((((uint32)ch) & 0x3f) << 8); + ch = (uptr->SNS2 >> 8) & 0xff; /* seek end and unit selected for now */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv dsr unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ + ch = uptr->SNS2 & 0xff; /* drive on cylinder and ready for now */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv dsr unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + } + uptr->SNS &= 0xff000000; /* reset status */ + uptr->SNS2 = 0; /* reset status */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_SCK: /* Seek cylinder, track, sector 0x07 */ + /* If we are waiting on seek to finish, check if there yet. */ + if (uptr->CMD & DSK_SEEKING) { + /* see if on cylinder yet */ + if (STAR2CYL(uptr->STAR) == STAR2CYL(uptr->CHS)) { + /* we are on cylinder, seek is done */ + sim_debug(DEBUG_CMD, dptr, + "scfi_srv seek on cylinder unit %02x new %04x old %04x\n", + unit, uptr->STAR>>16, uptr->CHS>>16); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS2 |= (SNS_SEND|SNS_ONC); /* On cylinder & seek done */ + /* we have already seeked to the required sector */ + /* we do not need to seek again, so move on */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + break; + } else { + /* we have wasted enough time, we are there */ + /* we are on cylinder, seek is done */ + sim_debug(DEBUG_CMD, dptr, "scfi_srv seek over on cylinder unit=%02x %04x %04x\n", + unit, uptr->STAR >> 16, uptr->CHS >> 16); + uptr->CHS = uptr->STAR; /* we are there */ +#ifdef FAST_FOR_UTX + sim_activate(uptr, 15); /* start things off */ +#else + sim_activate(uptr, 150); /* start things off */ +#endif + break; + } + } + + /* not seeking, so start a new seek */ + /* set buf data to current STAR values */ + tcyl = STAR2CYL(uptr->CHS); /* get current cyl */ + + /* the value is really a sector offset for the disk */ + /* but will treat as c/h/s for processing */ + /* the cyl, trk, and sect are ready to update */ + sim_debug(DEBUG_CMD, dptr, + "scfi_srv current STAR unit=%02x star %02x %02x %02x %02x\n", + unit, (uptr->CHS >> 24) & 0xff, (uptr->CHS >> 16) & 0xff, + (uptr->CHS >> 8) & 0xff, (uptr->CHS) & 0xff); + + if (len != 4) { + sim_debug(DEBUG_EXP, dptr, + "scfi_srv SEEK bad count unit %02x count %04x\n", unit, len); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK|STATUS_LENGTH); + break; + } + + /* Read in 4 character required seek code */ + for (i = 0; i < 4; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + if (i == 0) { + sim_debug(DEBUG_DETAIL, dptr, + "scfi_srv seek error unit=%02x\n", unit); + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* Disc addressing or seek error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + chp->ccw_count = len; /* restore count, huh? */ + return SCPE_OK; + break; + } + /* just read the next byte */ + } + } + chp->ccw_count = len; /* restore count for diag, huh? */ + /* the value is really a sector offset for the disk */ + /* but will treat as c/h/s for processing */ + /* the cyl, trk, and sect are ready to update */ + sim_debug(DEBUG_CMD, dptr, + "scfi_srv STAR unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + /* save STAR (target sector) data in STAR */ + uptr->STAR = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); + cyl = STAR2CYL(uptr->STAR); /* get the cylinder */ + trk = buf[2]; /* get the track */ + sec = buf[3]; /* get sec */ + + sim_debug(DEBUG_DETAIL, dptr, + "scfi_srv NEW SEEK cyl %04x trk %02x sec %02x unit=%02x\n", + cyl&0xffff, trk, buf[3], unit); + + /* Check if seek valid */ + if (uptr->STAR >= CAP(type)) { + + sim_debug(DEBUG_EXP, dptr, + "scfi_srv seek ERROR cyl %04x trk %02x sec %02x unit=%02x\n", + cyl, trk, buf[3], unit); + + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_DADE; /* set error status */ + uptr->SNS2 |= (SNS_SKER|SNS_SEND); + + /* set new STAR value, even if invalid */ + uptr->CHS = uptr->STAR; + + /* we have an error, tell user */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* end command */ + break; + } + + /* calc the new sector address of data */ + /* calculate file position in bytes of requested sector */ + /* file offset in bytes */ + tstart = uptr->STAR * SSB(type); + uptr->CHS = uptr->STAR; + + sim_debug(DEBUG_DETAIL, dptr, + "scfi_srv seek start %06x trk %04x sec %02x\n", + tstart, trk, buf[3]); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "scfi_srv Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* Check if already on correct cylinder */ + /* if not, do a delay to slow things down */ + if (tcyl != cyl) { + int diff = ((int)tcyl - (int)cyl); + if (diff < 0) + diff = -diff; + /* Do a fake seek to kill time */ + uptr->CMD |= DSK_SEEKING; /* show we are seeking */ + sim_debug(DEBUG_EXP, dptr, + "scfi_srv seeking unit=%02x to %04x/%02x/%02x from cyl %04x (%04x)\n", + unit, cyl, trk, buf[3], tcyl, cyl); +#ifdef FAST_FOR_UTX + sim_activate(uptr, 15); /* start things off */ +#else + sim_activate(uptr, 200+diff); /* start us off */ +#endif + } else { + /* we are on cylinder/track/sector, so go on */ + sim_debug(DEBUG_DETAIL, dptr, + "scfi_srv done seeking to %04x cyl %04x trk %02x sec %02x\n", + tstart, cyl, trk, buf[3]); + /* set new STAR value */ + uptr->CHS = uptr->STAR; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + } + break; + + case DSK_XEZ: /* 0x37 */ /* Rezero & Read IPL record */ + + sim_debug(DEBUG_CMD, dptr, "XEZ REZERO IPL unit=%02x seek 0\n", unit); + /* Do a seek to 0 */ + tcyl = STAR2CYL(uptr->CHS); /* get current cyl */ + uptr->STAR = 0; /* set STAR to 0, 0, 0 */ + uptr->CHS = 0; /* set current CHS to 0, 0, 0 */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CMD |= DSK_SCK; /* show as seek command */ + tstart = 0; /* byte offset is 0 */ + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "scfi_srv Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* we are on cylinder/track/sector zero, so go on */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv done seek trk 0\n"); + uptr->CMD |= DSK_SEEKING; /* show we are seeking */ + sim_debug(DEBUG_EXP, dptr, + "scfi_srv XEZ seeking unit=%02x to cyl 0000 from cyl %04x\n", + unit, tcyl); + sim_activate(uptr, 15); /* start things off */ + break; + + case DSK_LMR: /* 0x1F */ + sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x\n", unit); + /* Read in 1 character of mode data */ + if (chan_read_byte(chsa, &buf[0])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x old %x new %x\n", + unit, (uptr->SNS)&0xff, buf[0]); + uptr->CMD &= LMASK; /* remove old cmd */ + uptr->SNS &= MASK24; /* clear old mode data */ + uptr->SNS |= (buf[0] << 24); /* save mode value */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_RD: /* Read Data command 0x02 */ + if ((uptr->CMD & DSK_READING) == 0) { /* see if we are reading data */ + uptr->CMD |= DSK_READING; /* read from disk starting */ + sim_debug(DEBUG_CMD, dptr, + "DISK READ starting CMD %08x chsa %04x buffer %06x count %04x\n", + uptr->CMD, chsa, chp->ccw_addr, chp->ccw_count); + } + + if (uptr->CMD & DSK_READING) { /* see if we are reading data */ + /* get file offset in sectors */ + tstart = uptr->CHS; + /* file offset in bytes */ + tstart = tstart * SSB(type); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "scfi_srv READ, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "DISK READ reading CMD %08x chsa %04x tstart %04x buffer %06x count %04x\n", + uptr->CMD, chsa, tstart, chp->ccw_addr, chp->ccw_count); + + /* read in a sector of data from disk */ + if ((len=sim_fread(buf, 1, ssize, uptr->fileref)) != ssize) { + sim_debug(DEBUG_EXP, dptr, + "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", + len, ssize, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_DETAIL, dptr, + "scfi_srv after READ chsa %04x buffer %06x count %04x\n", + chsa, chp->ccw_addr, chp->ccw_count); + sim_debug(DEBUG_DETAIL, dptr, + "scfi_srv after READ buffer %06x count %04x data %02x%02x%02x%02x %02x%02x%02x%02x\n", +// chp->ccw_addr, chp->ccw_count, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + chp->ccw_addr, chp->ccw_count, buf[1016], buf[1017], buf[1018], buf[1019], + buf[1020], buf[1021], buf[1022], buf[1023]); + + uptr->CHS++; /* next sector number */ + /* process the next sector of data */ + for (i=0; ichan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + sim_debug(DEBUG_CMD, dptr, + "SCFI Read %04x bytes leaving %04x from diskfile %04x/%02x/%02x\n", + i, chp->ccw_count, ((uptr->CHS)>>16)&0xffff, + ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + } + + sim_debug(DEBUG_CMD, dptr, + "SCFI READ %04x bytes leaving %4x to be read to %06x from diskfile %04x/%02x/%02x\n", + ssize, chp->ccw_count, chp->ccw_addr, + ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + + /* get sector offset */ + tstart = uptr->CHS; + + /* see if over end of disk */ + if (tstart >= (uint32)CAP(type)) { + /* EOM reached, abort */ + sim_debug(DEBUG_EXP, dptr, + "DISK Read reached EOM for read from disk @ /%04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CHS = 0; /* reset cylinder position */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* see if we are done reading data */ + if (test_write_byte_end(chsa)) { + sim_debug(DEBUG_CMD, dptr, + "DISK Read complete for read from diskfile %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + + sim_debug(DEBUG_CMD, dptr, + "DISK sector read complete, %x bytes to go from diskfile %04x/%02x/%02x\n", + chp->ccw_count, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); +#ifdef FAST_FOR_UTX + sim_activate(uptr, 15); /* start things off */ +#else + sim_activate(uptr, 150); /* wait to read next sector */ +#endif + break; + } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + break; + + case DSK_WD: /* Write Data command 0x01 */ + if ((uptr->CMD & DSK_WRITING) == 0) { /* see if we are writing data */ + sim_debug(DEBUG_CMD, dptr, + "DISK WRITE starting unit=%02x CMD %08x write %04x from %06x to %03x/%02x/%02x\n", + unit, uptr->CMD, chp->ccw_count, chp->ccw_addr, + ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + + if (uptr->SNS & 0xf0000000) { /* see if any mode bit 0-3 is set */ + uptr->SNS |= SNS_MOCK; /* mode check error */ + chp->chan_status |= STATUS_PCHK; /* channel prog check */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; + } + uptr->CMD |= DSK_WRITING; /* write to disk starting */ + } + if (uptr->CMD & DSK_WRITING) { /* see if we are writing data */ + /* get file offset in sectors */ + tstart = uptr->CHS; + /* file offset in bytes */ + tstart = tstart * SSB(type); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "scfi_srv WRITE, Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* process the next sector of data */ + tcyl = 0; /* used here as a flag for short read */ + for (i=0; ichan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* if error on reading 1st byte, we are done writing */ + if ((i == 0) || (chp->chan_status & STATUS_PCHK)) { + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "DISK Wrote %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + else + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + ch = 0; /* finish out the sector with zero */ + tcyl++; /* show we have no more data to write */ + } + buf2[i] = ch; /* save the char */ + } + + /* get file offset in sectors */ + tstart = uptr->CHS; + + /* write the sector to disk */ + if ((i=sim_fwrite(buf2, 1, ssize, uptr->fileref)) != ssize) { + sim_debug(DEBUG_EXP, dptr, + "Error %08x on write %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + i, ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_DETAIL, dptr, + "scfi_srv after WRITE buffer %06x count %04x data %02x%02x%02x%02x %02x%02x%02x%02x\n", + chp->ccw_addr, chp->ccw_count, buf2[1016], buf2[1017], buf2[1018], buf2[1019], + buf2[1020], buf2[1021], buf2[1022], buf2[1023]); + + sim_debug(DEBUG_CMD, dptr, + "DISK WR to sec end %04x bytes end %04x to diskfile cyl %04x hds %02x sec %02x\n", + len, ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + + uptr->CHS++; /* next sector number */ + if (tcyl != 0) { /* see if done with write command */ + sim_debug(DEBUG_CMD, dptr, + "DISK WroteB %04x bytes to diskfile cyl %04x hds %02x sec %02x\n", + ssize, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + } + /* get sector offset */ + tstart = uptr->CHS; + + /* see if over end of disk */ + if (tstart >= (uint32)CAP(type)) { + /* EOM reached, abort */ + sim_debug(DEBUG_EXP, dptr, + "DISK Write reached EOM for write to disk @ %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CHS = 0; /* reset cylinder position */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + /* see if we are done reading data */ + if (test_write_byte_end(chsa)) { + sim_debug(DEBUG_CMD, dptr, + "DISK Write complete for read from diskfile %04x/%02x/%02x\n", + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + +#ifdef FAST_FOR_UTX + sim_activate(uptr, 15); /* start things off */ +#else + sim_activate(uptr, 150); /* wait to read next sector */ +#endif + break; + } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + break; + + default: + sim_debug(DEBUG_EXP, dptr, "invalid command %02x unit %02x\n", cmd, unit); + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|STATUS_PCHK); /* return Prog Check */ + break; + } + sim_debug(DEBUG_DETAIL, dptr, + "scfi_srv done cmd %02x chsa %04x chs %04x/%02x/%02x\n", + cmd, chsa, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); + return SCPE_OK; +} + +/* handle rschnlio cmds for disk */ +t_stat scfi_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & DSK_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, + "scfi_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + scfi_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +/* initialize the disk */ +void scfi_ini(UNIT *uptr, t_bool f) +{ + DEVICE *dptr = get_dev(uptr); + int i = GET_TYPE(uptr->flags); + + /* start out at sector 0 */ + uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */ + uptr->STAR = 0; /* set STAR to cyl/hd/sec = 0 */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* total sectors on disk */ + uptr->capac = CAP(i); /* size in sectors */ + sim_cancel(uptr); /* stop any timers */ + + sim_debug(DEBUG_EXP, &sda_dev, "SDA init device %s on unit SDA%04x cap %x %d\n", + dptr->name, GET_UADDR(uptr->CMD), uptr->capac, uptr->capac); +} + +t_stat scfi_reset(DEVICE *dptr) +{ + /* add reset code here */ + return SCPE_OK; +} + +/* create the disk file for the specified device */ +int scfi_format(UNIT *uptr) { + int type = GET_TYPE(uptr->flags); + DEVICE *dptr = get_dev(uptr); + uint32 ssize = SSB(type); /* disk sector size in bytes */ + uint32 tsize = SPT(type); /* get track size in sectors */ + uint32 csize = SPC(type); /* get cylinder size in sectors */ + uint32 cyl = CYL(type); /* get # cylinders */ + uint32 cap = CAP(type); /* disk capacity in sectors */ + uint32 cylv = cyl; /* number of cylinders */ + uint8 *buff; + int32 i; + t_stat oldsw = sim_switches; /* save switches */ + + /* last sector address of disk (cyl * hds * spt) - 1 */ + uint32 laddr = CAP(type) - 1; /* last sector of disk */ + + /* make up dummy defect map */ + uint32 dmap[4] = {0xf0000000 | (cap-1), 0x8a000000, + 0x9a000000 | (cap-1), 0xf4000000}; + + + /* see if -i or -n specified on attach command */ + if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) { + sim_switches = 0; /* simh tests 'N' & 'Y' switches */ + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { + sim_switches = oldsw; + return 1; + } + sim_switches = oldsw; /* restore switches */ + } + + /* seek to sector 0 */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + + /* get buffer for track data in bytes */ + if ((buff = (uint8 *)calloc(csize*ssize, sizeof(uint8))) == 0) { + detach_unit(uptr); + return SCPE_ARG; + } + sim_debug(DEBUG_CMD, dptr, + "Creating disk file of trk size %04x bytes, capacity %d\n", + tsize*ssize, cap*ssize); + + /* write zeros to each track of the disk */ + for (cyl = 0; cyl < cylv; cyl++) { + if ((sim_fwrite(buff, 1, csize*ssize, uptr->fileref)) != csize*ssize) { + sim_debug(DEBUG_EXP, dptr, + "Error on write to diskfile cyl %04x\n", cyl); + free(buff); /* free cylinder buffer */ + buff = 0; + return 1; + } + if ((cyl % 100) == 0) + fputc('.', stderr); + } + fputc('\r', stderr); + fputc('\n', stderr); + free(buff); /* free cylinder buffer */ + buff = 0; + + /* byte swap the buffer for dmap */ + for (i=0; i<4; i++) { + dmap[i] = (((dmap[i] & 0xff) << 24) | ((dmap[i] & 0xff00) << 8) | + ((dmap[i] & 0xff0000) >> 8) | ((dmap[i] >> 24) & 0xff)); + } + + /* now seek to end of disk and write the dmap data to last sector */ + /* write dmap data to last sector on disk */ + if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */ + sim_debug(DEBUG_EXP, dptr, + "Error on last sector seek to sect %06x offset %06x\n", + cap-1, (cap-1)*ssize); + return 1; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_EXP, dptr, + "Error writing DMAP to sect %06x offset %06x\n", + cap-1, (cap-1)*ssize); + return 1; + } + + printf("Disk %s has %x (%d) cyl, %x (%d) hds, %x (%d) sec\r\n", + scfi_type[type].name, CYL(type), CYL(type), HDS(type), HDS(type), + SPT(type), SPT(type)); + + /* seek home again */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + return 0; /* good or error */ +} + +/* attach the selected file to the disk */ +t_stat scfi_attach(UNIT *uptr, CONST char *file) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + CHANP *chp = find_chanp_ptr(chsa);/* get channel prog pointer */ + int type = GET_TYPE(uptr->flags); + DEVICE *dptr = get_dev(uptr); + DIB *dibp = 0; + t_stat r, s; + uint32 ssize; /* sector size in bytes */ + uint32 info, good; + uint8 buff[1024]; + int i, j; + + /* last sector address of disk (cyl * hds * spt) - 1 */ + uint32 laddr = CAP(type) - 1; /* last sector of disk */ + /* get sector address of utx diag map (DMAP) track 0 pointer */ + /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ + /* 0x9a000000 + (cyl-1), 0xf4000000 */ + /* defect map */ + uint32 dmap[4] = {0xf0000000 | (CAP(type)-1), 0x8a000000, + 0x9a000000 | (CAP(type)-1), 0xf4000000}; + + for (i=0; i<4; i++) { /* byte swap data for last sector */ + dmap[i] = (((dmap[i] & 0xff) << 24) | ((dmap[i] & 0xff00) << 8) | + ((dmap[i] & 0xff0000) >> 8) | ((dmap[i] >> 24) & 0xff)); + } + + /* see if valid disk entry */ + if (scfi_type[type].name == 0) { /* does the assigned disk have a name */ + detach_unit(uptr); /* no, reject */ + return SCPE_FMT; /* error */ + } + + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, + "ERROR===ERROR\nSCFI Disk device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nSCFI Disk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + /* have simulator attach the file to the unit */ + if ((r = attach_unit(uptr, file)) != SCPE_OK) + return r; + + uptr->capac = CAP(type); /* disk capacity in sectors */ + ssize = SSB(type); /* get sector size in bytes */ + for (i=0; i<(int)ssize; i++) + buff[i] = 0; /* zero the buffer */ + + sim_debug(DEBUG_CMD, dptr, + "SCFI Disk %s cyl %d hds %d sec %d ssiz %d capacity %d\n", + scfi_type[type].name, scfi_type[type].cyl, scfi_type[type].nhds, + scfi_type[type].spt, ssize, uptr->capac); /* disk capacity */ + printf("SCFI Disk %s cyl %d hds %d sec %d ssiz %d capacity %d\r\n", + scfi_type[type].name, scfi_type[type].cyl, scfi_type[type].nhds, + scfi_type[type].spt, ssize, uptr->capac); /* disk capacity */ + + /* see if -i or -n specified on attach command */ + if ((sim_switches & SWMASK('N')) || (sim_switches & SWMASK('I'))) { + goto fmt; /* user wants new disk */ + } + + /* seek to end of disk */ + if ((sim_fseek(uptr->fileref, 0, SEEK_END)) != 0) { + sim_debug(DEBUG_CMD, dptr, "SCFI Disk attach SEEK end failed\n"); + printf( "SCFI Disk attach SEEK end failed\r\n"); + goto fmt; /* not setup, go format */ + } + + s = ftell(uptr->fileref); /* get current file position */ + if (s == 0) { + sim_debug(DEBUG_CMD, dptr, "SCFI Disk attach ftell failed s=%06d\n", s); + printf("SCFI Disk attach ftell failed s=%06d\r\n", s); + goto fmt; /* not setup, go format */ + } + sim_debug(DEBUG_CMD, dptr, + "SCFI Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type)); + printf("SCFI Disk attach ftell value s=%06d b=%06d CAP %06d\r\n", s/ssize, s, CAP(type)); + + if (((int)s/(int)ssize) < ((int)CAP(type))) { /* full sized disk? */ + j = (CAP(type) - (s/ssize)); /* get # sectors to write */ + sim_debug(DEBUG_CMD, dptr, + "SCFI Disk attach for MPX 1.X needs %04d more sectors added to disk\n", j); + printf("SCFI Disk attach for MPX 1.X needs %04d more sectors added to disk\r\n", j); + /* must be MPX 1.X disk, extend to MPX 3.X size */ + /* write sectors of zero to end of disk to fill it out */ + for (i=0; ifileref) != ssize)) { + sim_debug(DEBUG_CMD, dptr, "SCFI Disk attach fread ret = %04d\n", r); + printf("SCFI Disk attach fread ret = %04d\r\n", r); + goto fmt; /* not setup, go format */ + } + } + s = ftell(uptr->fileref); /* get current file position */ + sim_debug(DEBUG_CMD, dptr, + "SCFI Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\n", + s/ssize, s); + printf("SCFI Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\r\n", + s/ssize, s); + } + + /* seek last sector of disk */ + if ((sim_fseek(uptr->fileref, (CAP(type)-1)*ssize, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, "SCFI Disk attach SEEK last sector failed\n"); + printf("SCFI Disk attach SEEK last sector failed\r\n"); + goto fmt; + } + + /* see if there is disk size-1 in last sector of disk, if not add it */ + if ((r = sim_fread(buff, sizeof(uint8), ssize, uptr->fileref) != ssize)) { + sim_debug(DEBUG_CMD, dptr, "SCFI Disk format fread error = %04d\n", r); + printf("SCFI Disk format fread error = %04d\r\n", r); +add_size: + if (ssize == 768) { + /* assume we have MPX 1x, and go on */ + /* write dmap data to last sector on disk for mpx 1.x */ + if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */ + sim_debug(DEBUG_CMD, dptr, + "SCFI Error on last sector seek to sect %06d offset %06d bytes\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + printf("SCFI Error on last sector seek to sect %06d offset %06d bytes\r\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + goto fmt; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "SCFI Error writing DMAP to sect %06x offset %06d bytes\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + printf("SCFI Error writing DMAP to sect %06x offset %06d bytes\r\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + goto fmt; + } + + /* seek last sector of disk */ + if ((sim_fseek(uptr->fileref, (CAP(type))*ssize, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, "SCFI Disk attach SEEK last sector failed\n"); + printf( "SCFI Disk attach SEEK last sector failed\r\n"); + goto fmt; + } + s = ftell(uptr->fileref); /* get current file position */ + sim_debug(DEBUG_CMD, dptr, + "SCFI Disk attach MPX file extended & sized secs %06d bytes %06d\n", s/ssize, s); + printf("SCFI Disk attach MPX file extended & sized secs %06d bytes %06d\r\n", s/ssize, s); + goto ldone; + } else { + /* error if UTX */ + detach_unit(uptr); /* if error, abort */ + return SCPE_FMT; /* error */ + } + } else { + /* if not disk size, go add it in for MPX, error if UTX */ + if ((buff[0] | buff[1] | buff[2] | buff[3]) == 0) { + sim_debug(DEBUG_CMD, dptr, + "SCFI Disk format0 buf0 %02x buf1 %02x buf2 %02x buf3 %02x\n", + buff[0], buff[1], buff[2], buff[3]); + goto add_size; + } + } + + info = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3]; + good = 0xf0000000 | (CAP(type)-1); + /* check for 0xf0ssssss where ssssss is disk size-1 in sectors */ + if (info != good) { + sim_debug(DEBUG_CMD, dptr, + "SCFI Disk format error buf0 %02x buf1 %02x buf2 %02x buf3 %02x\n", + buff[0], buff[1], buff[2], buff[3]); + printf( + "SCFI Disk format error buf0 %02x buf1 %02x buf2 %02x buf3 %02x\r\n", + buff[0], buff[1], buff[2], buff[3]); +fmt: + /* format the drive */ + if (scfi_format(uptr)) { + detach_unit(uptr); /* if no space, error */ + return SCPE_FMT; /* error */ + } + } +ldone: + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + detach_unit(uptr); /* detach if error */ + return SCPE_FMT; /* error */ + } + + /* start out at sector 0 */ + uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */ + + sim_debug(DEBUG_CMD, dptr, + "SCFI Attach %s %04x cyl %d hds %d spt %d spc %d cap sec %d cap bytes %d\n", + scfi_type[type].name, chsa, CYL(type), HDS(type), SPT(type), SPC(type), + CAP(type), CAPB(type)); + printf("SCFI Attach %s %04x cyl %d hds %d spt %d spc %d cap sec %d cap bytes %d\r\n", + scfi_type[type].name, chsa, CYL(type), HDS(type), SPT(type), SPC(type), + CAP(type), CAPB(type)); + + sim_debug(DEBUG_CMD, dptr, + "SCFI File %s at chsa %04x attached to %s is ready\n", + file, chsa, scfi_type[type].name); + printf("SCFI File %s at chsa %04x attached to %s is ready\r\n", + file, chsa, scfi_type[type].name); + + /* check for valid configured disk */ + /* must have valid DIB and Channel Program pointer */ + dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */ + if ((dib_unit[chsa] == NULL) || (dibp == NULL) || (chp == NULL)) { + sim_debug(DEBUG_EXP, dptr, + "ERROR===ERROR\nSCFI device %s not configured on system, aborting\n", + dptr->name); + printf("ERROR===ERROR\nSCFI device %s not configured on system, aborting\r\n", + dptr->name); + detach_unit(uptr); /* detach if error */ + return SCPE_UNATT; /* error */ + } + set_devattn(chsa, SNS_DEVEND); + return SCPE_OK; +} + +/* detach a disk device */ +t_stat scfi_detach(UNIT *uptr) { + uptr->SNS = 0; /* clear sense data */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + return detach_unit(uptr); /* tell simh we are done with disk */ +} + +/* boot from the specified disk unit */ +t_stat scfi_boot(int32 unit_num, DEVICE *dptr) { + UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */ + + sim_debug(DEBUG_CMD, dptr, + "SCFI Disk Boot dev/unit %x\n", GET_UADDR(uptr->CMD)); + + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nSCFI Disk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + if ((uptr->flags & UNIT_ATT) == 0) { + sim_debug(DEBUG_EXP, dptr, + "SCFI Disk Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + printf("SCFI Disk Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + return SCPE_UNATT; /* attached? */ + } + SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ + SPAD[0xf8] = 0xF000; /* show as F class device */ + + /* now boot the disk */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + return chan_boot(GET_UADDR(uptr->CMD), dptr); /* boot the ch/sa */ +} + +/* Disk option setting commands */ +/* set the disk type attached to unit */ +t_stat scfi_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int i; + + if (cptr == NULL) /* any disk name input? */ + return SCPE_ARG; /* arg error */ + if (uptr == NULL) /* valid unit? */ + return SCPE_IERR; /* no, error */ + if (uptr->flags & UNIT_ATT) /* is unit attached? */ + return SCPE_ALATT; /* no, error */ + + /* now loop through the units and find named disk */ + for (i = 0; scfi_type[i].name != 0; i++) { + if (strcmp(scfi_type[i].name, cptr) == 0) { + uptr->flags &= ~UNIT_TYPE; /* clear the old UNIT type */ + uptr->flags |= SET_TYPE(i); /* set the new type */ + /* set capacity of disk in sectors */ + uptr->capac = CAP(i); + return SCPE_OK; + } + } + return SCPE_ARG; +} + +t_stat scfi_get_type(FILE *st, UNIT *uptr, int32 v, CONST void *desc) +{ + if (uptr == NULL) + return SCPE_IERR; + fputs("TYPE=", st); + fputs(scfi_type[GET_TYPE(uptr->flags)].name, st); + return SCPE_OK; +} + +/* help information for disk */ +t_stat scfi_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + int i; + fprintf (st, "SEL-32 SCFI Disk Processor\r\n"); + fprintf (st, "Use:\r\n"); + fprintf (st, " sim> SET %sn TYPE=type\r\n", dptr->name); + fprintf (st, "Type can be: "); + for (i = 0; scfi_type[i].name != 0; i++) { + fprintf(st, "%s", scfi_type[i].name); + if (scfi_type[i+1].name != 0) + fprintf(st, ", "); + } + fprintf (st, ".\nEach drive has the following storage capacity:\r\n"); + for (i = 0; scfi_type[i].name != 0; i++) { + int32 size = CAPB(i); /* disk capacity in bytes */ + size /= 1024; /* make KB */ + size = (10 * size) / 1024; /* size in MB * 10 */ + fprintf(st, " %-8s %4d.%1d MB cyl %3d hds %3d sec %3d blk %3d\r\n", + scfi_type[i].name, size/10, size%10, CYL(i), HDS(i), SPT(i), SSB(i)); + } + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + return SCPE_OK; +} + +const char *scfi_description (DEVICE *dptr) +{ + return "SEL-32 SCFI Disk Processor"; +} + +#endif diff --git a/SEL32/sel32_scsi.c b/SEL32/sel32_scsi.c new file mode 100644 index 00000000..8540f9a5 --- /dev/null +++ b/SEL32/sel32_scsi.c @@ -0,0 +1,2068 @@ +/* sel32_scsi.c: SEL-32 MFP SCSI Disk controller + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell and other SIMH contributers + + 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 + JAMES C. BEVIER 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 "sel32_defs.h" + +/* uncomment to use fast sim_activate times when running UTX */ +/* UTX gets an ioi error for dm0801 if slow times are used */ +/* dm0801 is not even a valid unit number for UDP controller */ +#define FAST_FOR_UTX + +#if NUM_DEVS_SCSI > 0 + +#define UNIT_SCSI UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE + +/* useful conversions */ +/* Fill STAR value from cyl, trk, sec data */ +#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff)) +/* convert STAR value to number of sectors */ +#define STAR2SEC(star,spt,spc) ((star&0xff)+(((star>>8)&0xff)*spt)+((star>>16)*spc)) +/* convert STAR value to number of heads or tracks */ +#define STAR2TRK(star,tpc) ((star >> 16) * tpc + ((star >> 8) & 0x0ff)) +/* convert STAR value to number of cylinders */ +#define STAR2CYL(star) ((star >> 16) & RMASK) +/* convert byte value to number of sectors mod sector size */ +#define BYTES2SEC(bytes,ssize) (((bytes) + (ssize-1)) >> 10) +/* get sectors per track for specified type */ +#define SPT(type) (scsi_type[type].spt) +/* get sectors per cylinderfor specified type */ +#define SPC(type) (scsi_type[type].spt*scsi_type[type].nhds) +/* get number of cylinders for specified type */ +#define CYL(type) (scsi_type[type].cyl) +/* get number of heads for specified type */ +#define HDS(type) (scsi_type[type].nhds) +/* get disk capacity in sectors for specified type */ +#define CAP(type) (CYL(type)*HDS(type)*SPT(type)) +/* get number of bytes per sector for specified type */ +#define SSB(type) (scsi_type[type].ssiz*4) +/* get disk capacity in bytes for specified type */ +#define CAPB(type) (CAP(type)*SSB(type)) +/* get disk geometry as STAR value for specified type */ +#define GEOM(type) (CHS2STAR(CYL(type),HDS(type),SPT(type))) + +/* INCH command information */ +/* +WD 0 - Data address +WD 1 - Flags - 0 -36 byte count + +Data - 224 word INCH buffer address (SST) +WD 1 Drive 0 Attribute register +WD 2 Drive 1 Attribute register +WD 3 Drive 2 Attribute register +WD 4 Drive 3 Attribute register +WD 5 Drive 4 Attribute register +WD 6 Drive 5 Attribute register +WD 7 Drive 6 Attribute register +WD 8 Drive 7 Attribute register + +Memory attribute register layout +bits 0-7 - Flags + bits 0&1 - 00=Reserved, 01=MHD, 10=FHD, 11=MHD with FHD option + bit 2 - 1=Cartridge module drive + bit 3 - 0=Reserved + bit 4 - 1=Drive not present + bit 5 - 1=Dual Port + bit 6 - 0=Blk size 00=768 byte blk + bit 7 - 0=Blk size 01=1024 byte blk +bits 8-15 - sector count (sectors per track)(F16=16, F20=20) +bits 16-23 - MHD Head count (number of heads on MHD) +bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option of + mini-module) +*/ + + +/* 224 word INCH Buffer layout */ +/* 128 word subchannel status storage (SST) */ +/* 66 words of program status queue (PSQ) */ +/* 26 words of scratchpad */ +/* 4 words of label buffer registers */ + +/* track label / sector label definations */ +/* + short lcyl; cylinder + char ltkn; track + char lid; sector id + char lflg1; track/sector status flags + bit 0 good + 1 alternate + 2 spare + 3 reserved + 4 flaw + 5 last track + 6 start of alternate + char lflg2; + short lspar1; + short lspar2; + short ldef1; + int ldeallp; DMAP block number trk0 + int lumapp; UMAP block number sec1 + short ladef3; + short laltcyl; + char lalttk; sectors per track + char ldscnt; number of heads + char ldatrflg; device attributes + bit 0 n/u + 1 disk is mhd + 2 n/u + 3 n/u + 4 n/u + 5 dual ported + 6/7 00 768 bytes/blk + 01 1024 bytes/blk + 10 2048 bytes/blk + char ldatrscnt; sectors per track (again) + char ldatrmhdc; MHD head count + char ldatrfhdc; FHD head count + */ + +#define CMD u3 +/* u3 */ +/* in u3 is device command code and status */ +#define DSK_CMDMSK 0x00ff /* Command being run */ +#define DSK_STAR 0x0100 /* STAR value in u4 */ +#define DSK_NU 0x0200 /* Not used */ +#define DSK_READDONE 0x0400 /* Read finished, end channel */ +#define DSK_ENDDSK 0x0800 /* Sensed end of disk */ +#define DSK_SEEKING 0x1000 /* Disk is currently seeking */ +#define DSK_READING 0x2000 /* Disk is reading data */ +#define DSK_WRITING 0x4000 /* Disk is writing data */ +#define DSK_BUSY 0x8000 /* Disk is busy */ +/* commands */ +#define DSK_INCH 0x00 /* Initialize channel */ +#define DSK_INCH2 0xF0 /* Initialize channel for processing */ +#define DSK_WD 0x01 /* Write data */ +#define DSK_RD 0x02 /* Read data */ +#define DSK_NOP 0x03 /* No operation */ +#define DSK_SNS 0x04 /* Sense */ +#define DSK_SCK 0x07 /* Seek cylinder, track, sector */ +#define DSK_TIC 0x08 /* Transfer in channel */ +//#define DSK_FNSK 0x0B /* Format for no skip */ +#define DSK_RBLK 0x13 /* Reassign Block */ +#define DSK_LMR 0x1F /* Load mode register */ +#define DSK_RWD 0x23 /* Rewind */ +//#define DSK_WSL 0x31 /* Write sector label */ +//#define DSK_RSL 0x32 /* Read sector label */ +//#define DSK_REL 0x33 /* Release */ +#define DSK_XEZ 0x37 /* Rezero */ +//#define DSK_ADV 0x43 /* Advance Record */ +//#define DSK_IHA 0x47 /* Increment head address */ +//#define DSK_SRM 0x4F /* Set reserve track mode */ +//#define DSK_WTL 0x51 /* Write track label */ +//#define DSK_RTL 0x52 /* Read track label */ +#define DSK_RCAP 0x53 /* Read Capacity */ +//#define DSK_XRM 0x5F /* Reset reserve track mode */ +//#define DSK_RAP 0xA2 /* Read angular positions */ +#define DSK_RES 0xA3 /* Reserve Unit */ +//#define DSK_TESS 0xAB /* Test STAR (subchannel target address register) */ +#define DSK_INQ 0xB3 /* Inquiry */ +#define DSK_REL 0xC3 /* Release Unit */ +#define DSK_TCMD 0xD3 /* Transfer Command Packet (specifies CDB to send) */ +//#define DSK_ICH 0xFF /* Initialize Controller */ +#define DSK_FRE 0xF3 /* Reserved */ +#define DSK_SID 0x80 /* MFP status command */ + +#define STAR u4 +/* u4 - sector target address register (STAR) */ +/* Holds the current cylinder, head(track), sector */ +#define DISK_CYL 0xFFFF0000 /* cylinder mask */ +#define DISK_TRACK 0x0000FF00 /* track mask */ +#define DISK_SECTOR 0x000000ff /* sector mask */ + +#define SNS u5 +/* u5 */ +/* Sense byte 0 - mode register */ +#define SNS_DROFF 0x80000000 /* Drive Carriage will be offset */ +#define SNS_TRKOFF 0x40000000 /* Track offset: 0=positive, 1=negative */ +#define SNS_RDTMOFF 0x20000000 /* Read timing offset = 1 */ +#define SNS_RDSTRBT 0x10000000 /* Read strobe timing: 1=positive, 0=negative */ +#define SNS_DIAGMOD 0x08000000 /* Diagnostic Mode ECC Code generation and checking */ +#define SNS_RSVTRK 0x04000000 /* Reserve Track mode: 1=OK to write, 0=read only */ +#define SNS_FHDOPT 0x02000000 /* FHD or FHD option = 1 */ +//#define SNS_RESERV 0x01000000 /* Reserved */ +#define SNS_TCMD 0x01000000 /* Presessing CMD cmd chain */ + +/* Sense byte 1 */ +#define SNS_CMDREJ 0x800000 /* Command reject */ +#define SNS_INTVENT 0x400000 /* Unit intervention required */ +#define SNS_SPARE1 0x200000 /* Spare */ +#define SNS_EQUCHK 0x100000 /* Equipment check */ +#define SNS_DATCHK 0x080000 /* Data Check */ +#define SNS_OVRRUN 0x040000 /* Data overrun/underrun */ +#define SNS_DSKFERR 0x020000 /* Disk format error */ +#define SNS_DEFTRK 0x010000 /* Defective track encountered */ + +/* Sense byte 2 */ +#define SNS_LAST 0x8000 /* Last track flag encountered */ +#define SNS_AATT 0x4000 /* At Alternate track */ +#define SNS_WPER 0x2000 /* Write protection error */ +#define SNS_WRL 0x1000 /* Write lock error */ +#define SNS_MOCK 0x0800 /* Mode check */ +#define SNS_INAD 0x0400 /* Invalid memory address */ +#define SNS_RELF 0x0200 /* Release fault */ +#define SNS_CHER 0x0100 /* Chaining error */ + +/* Sense byte 3 */ +#define SNS_REVL 0x80 /* Revolution lost */ +#define SNS_DADE 0x40 /* Disc addressing or seek error */ +#define SNS_BUCK 0x20 /* Buffer check */ +#define SNS_ECCS 0x10 /* ECC error in sector label */ +#define SNS_ECCD 0x08 /* ECC error iin data */ +#define SNS_ECCT 0x04 /* ECC error in track label */ +#define SNS_RTAE 0x02 /* Reserve track access error */ +#define SNS_UESS 0x01 /* Uncorrectable ECC error */ + +#define CHS u6 +/* u6 holds the current cyl, hd, sec for the drive */ + +/* this attribute information is provided by the INCH command */ +/* for each device and is not used. It is reconstructed from */ +/* the disk_t structure data for the assigned disk */ +/* +bits 0-7 - Flags + bits 0&1 - 00=Reserved, 01=MHD, 10=FHD, 11=MHD with FHD option + bit 2 - 1=Cartridge module drive + bit 3 - 0=Reserved + bit 4 - 1=Drive not present + bit 5 - 1=Dual Port + bit 6 - 0=Reserved 00 768 byte sec + bit 7 - 0=Reserved 01 1024 byte sec +bits 8-15 - sector count (sectors per track)(F16=16, F20=20) +bits 16-23 - MHD Head count (number of heads on MHD) +bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option of + mini-module) +*/ + +/* INCH addr up7 */ + +/* disk definition structure */ +struct scsi_t +{ + const char *name; /* Device ID Name */ + uint16 nhds; /* Number of heads */ + uint16 ssiz; /* sector size in words */ + uint16 spt; /* # sectors per track(head) */ + uint16 ucyl; /* Number of cylinders used */ + uint16 cyl; /* Number of cylinders on disk */ + uint8 type; /* Device type code */ + /* bit 1 mhd */ + /* bits 6/7 = 0 768 byte blk */ /* not used on UDP/DPII */ + /* = 1 1024 byte blk */ /* not used on UDP/DPII */ +} + +scsi_type[] = +{ + /* Class F Disc Devices */ + /* MPX SCSI disks for SCSI controller */ + {"SD150", 9, 192, 24, 963, 967, 0x40}, /*0 8820 150M 208872 sec */ + {"SD300", 9, 192, 32, 1405, 1409, 0x40}, /*1 8828 300M 396674 sec */ + {"SD700", 15, 192, 35, 1542, 1546, 0x40}, /*2 8833 700M 797129 sec */ + {"SD1200", 15, 192, 49, 1927, 1931, 0x40}, /*3 8835 1200M 1389584 sec */ + {"SD2400", 19, 192, 59, 2703, 2707, 0x40}, /*4 8842 2400M 2909128 sec */ + {"SH1200", 15, 192, 50, 1868, 1872, 0x40}, /*5 8832 1200M 1395014 sec */ + {"SH2550", 19, 192, 55, 2703, 2707, 0x40}, /*6 8834 2550M 2909128 sec */ + {"SH5150", 21, 192, 83, 3707, 3711, 0x40}, /*7 0000 5150M 5581145 sec */ + {"8820", 9, 256, 18, 963, 967, 0x41}, /*8 8820 150M 156654 sec */ + {"8821", 9, 256, 36, 963, 967, 0x41}, /*9 8828 300M 313308 sec */ + {"8833", 18, 256, 20, 1542, 1546, 0x41}, /*10 8833 700M 556560 sec */ + {"8835", 18, 256, 20, 1927, 1931, 0x41}, /*11 8835 1200M 695160 sec */ + /* For UTX */ + {NULL, 0} +}; + +t_stat scsi_preio(UNIT *uptr, uint16 chan); +t_stat scsi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); +t_stat scsi_haltio(UNIT *uptr); +t_stat scsi_srv(UNIT *); +t_stat scsi_boot(int32 unitnum, DEVICE *); +void scsi_ini(UNIT *, t_bool); +t_stat scsi_rschnlio(UNIT *uptr); +t_stat scsi_reset(DEVICE *); +t_stat scsi_attach(UNIT *, CONST char *); +t_stat scsi_detach(UNIT *); +t_stat scsi_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat scsi_get_type(FILE * st, UNIT *uptr, int32 v, CONST void *desc); +t_stat scsi_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *scsi_description (DEVICE *dptr); + +/* One buffer per unit */ +//#define BUFFSIZE (256) +#define BUFFSIZE (512) +uint8 scsi_buf[NUM_DEVS_SCSI][NUM_UNITS_SCSI][BUFFSIZE]; +uint8 scsi_pcmd[NUM_DEVS_SCSI][NUM_UNITS_SCSI]; + +/* channel program information */ +CHANP sba_chp[NUM_UNITS_SCSI] = {0}; + +MTAB scsi_mod[] = { + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "TYPE", "TYPE", + &scsi_set_type, &scsi_get_type, NULL, "Type of disk"}, + {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, + &show_dev_addr, NULL, "Device channel address"}, + {0} +}; + +UNIT sba_unit[] = { +/* SET_TYPE(0) SD150 */ + {UDATA(&scsi_srv, UNIT_SCSI|SET_TYPE(0), 0), 0, UNIT_ADDR(0x7600)}, /* 0 */ + {UDATA(&scsi_srv, UNIT_SCSI|SET_TYPE(0), 0), 0, UNIT_ADDR(0x7608)}, /* 1 */ +}; + +DIB sba_dib = { + scsi_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + scsi_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + scsi_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + scsi_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + scsi_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + sba_unit, /* UNIT* units */ /* Pointer to units structure */ + sba_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_SCSI, /* uint8 numunits */ /* number of units defined */ + 0x38, /* uint8 mask */ /* 8 devices - device mask */ + 0x7600, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE sba_dev = { + "SBA", sba_unit, NULL, scsi_mod, + NUM_UNITS_SCSI, 16, 24, 4, 16, 32, + NULL, NULL, &scsi_reset, &scsi_boot, &scsi_attach, &scsi_detach, + /* ctxt is the DIB pointer */ + &sba_dib, DEV_BUF_NUM(0)|DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &scsi_help, NULL, NULL, &scsi_description +}; + +#if NUM_DEVS_SCSI > 1 + +/* channel program information */ +CHANP sbb_chp[NUM_UNITS_SCSI] = {0}; + +UNIT sbb_unit[] = { +/* SET_TYPE(0) DM150 */ + {UDATA(&scsi_srv, UNIT_SCSI|SET_TYPE(0), 0), 0, UNIT_ADDR(0x7640)}, /* 0 */ + {UDATA(&scsi_srv, UNIT_SCSI|SET_TYPE(0), 0), 0, UNIT_ADDR(0x7648)}, /* 1 */ +}; + +//DIB sdb_dib = {scsi_preio, scsi_startcmd, NULL, NULL, NULL, +//scsi_ini, sdb_unit, sdb_chp, NUM_UNITS_SCSI, 0x0f, 0x0c00, 0, 0, 0}; + +DIB sbb_dib = { + scsi_preio, /* t_stat (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ + scsi_startcmd, /* t_stat (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ + scsi_haltio, /* t_stat (*halt_io)(UNIT *uptr) */ /* Halt I/O */ + NULL, /* t_stat (*stop_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* t_stat (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* t_stat (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ + scsi_rschnlio, /* t_stat (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + NULL, /* t_stat (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ + scsi_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + sbb_unit, /* UNIT* units */ /* Pointer to units structure */ + sbb_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ + NUM_UNITS_SCSI, /* uint8 numunits */ /* number of units defined */ + 0x38, /* uint8 mask */ /* 2 devices - device mask */ + 0x7600, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + {0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +}; + +DEVICE sbb_dev = { + "SBB", sbb_unit, NULL, scsi_mod, + NUM_UNITS_SCSI, 16, 24, 4, 16, 32, + NULL, NULL, &scsi_reset, &scsi_boot, &scsi_attach, &scsi_detach, + /* ctxt is the DIB pointer */ + &sbb_dib, DEV_BUF_NUM(1)|DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug, + NULL, NULL, &scsi_help, NULL, NULL, &scsi_description +}; +#endif + +/* convert sector disk address to star values (c,h,s) */ +uint32 scsisec2star(uint32 daddr, int type) +{ + int32 sec = daddr % scsi_type[type].spt; /* get sector value */ + int32 spc = scsi_type[type].nhds * scsi_type[type].spt; /* sec per cyl */ + int32 cyl = daddr / spc; /* cylinders */ + int32 hds = (daddr % spc) / scsi_type[type].spt; /* heads */ + + /* now return the star value */ + return (CHS2STAR(cyl,hds,sec)); /* return STAR */ +} + +/* start a disk operation */ +t_stat scsi_preio(UNIT *uptr, uint16 chan) +{ + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int unit = (uptr - dptr->units); + + sim_debug(DEBUG_CMD, dptr, "scsi_preio CMD %08x unit=%02x\n", uptr->CMD, unit); + if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */ + return SNS_BSY; + } + sim_debug(DEBUG_CMD, dptr, "scsi_preio unit %02x chsa %04x OK\n", unit, chsa); + return 0; /* good to go */ +} + +t_stat scsi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + + sim_debug(DEBUG_CMD, dptr, + "scsi_startcmd unit %02x cmd %02x CMD %08x SNS %08x\n", + unit, cmd, uptr->CMD, uptr->SNS); + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + if (cmd != DSK_SNS) /* we are completed with unit check status */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; + } + + if ((uptr->CMD & DSK_CMDMSK) != 0) { + uptr->CMD |= DSK_BUSY; /* Flag we we are busy */ + return SNS_BSY; + } + if ((uptr->CMD & 0xff00) != 0) { /* if any status info, we are busy */ + return SNS_BSY; + } + sim_debug(DEBUG_CMD, dptr, "scsi_startcmd enter unit=%02x cmd %02x\n", unit, cmd); + + /* Unit is online, so process a command */ + switch (cmd) { + + case DSK_INCH: /* INCH 0x00 */ + sim_debug(DEBUG_CMD, dptr, + "scsi_startcmd starting INCH %06x cmd, chsa %04x MemBuf %08x cnt %04x\n", + uptr->u4, chsa, chp->ccw_addr, chp->ccw_count); + + uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */ + /* leave the TCMD bit */ + uptr->SNS &= ~MASK24; /* clear all but old mode data */ +#ifdef FAST_FOR_UTX +//zz sim_activate(uptr, 100); /* start things off */ + sim_activate(uptr, 30); /* start things off */ +#else + sim_activate(uptr, 100); /* start things off */ +#endif + return 0; + break; + + case DSK_SCK: /* Seek command 0x07 */ + case DSK_XEZ: /* Rezero & Read IPL record 0x1f */ + case DSK_WD: /* Write command 0x01 */ + case DSK_RD: /* Read command 0x02 */ + case DSK_LMR: /* read mode register */ + case DSK_NOP: /* NOP 0x03 */ + case DSK_RCAP: /* Read Capacity 0x53 */ + /* Transfer Command Packet (specifies CDB to send) */ + case DSK_TCMD: /* Transfer command packet 0xD3 */ + case DSK_SID: /* channel Sense 0x80 */ + /* leave the TCMD bit */ + uptr->SNS &= ~MASK24; /* clear all but old mode data */ + case DSK_SNS: /* Sense 0x04 */ + uptr->CMD |= cmd; /* save cmd */ + sim_debug(DEBUG_CMD, dptr, + "scsi_startcmd starting disk cmd %02x chsa %04x\n", cmd, chsa); + sim_activate(uptr, 100); /* start things off */ + return 0; + break; + } + sim_debug(DEBUG_CMD, dptr, + "scsi_startcmd done with scsi_startcmd %02x chsa %04x SNS %08x\n", + cmd, chsa, uptr->SNS); + if (uptr->SNS & 0xff) /* any other cmd is error */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; +#ifdef FAST_FOR_UTX +//zz sim_activate(uptr, 100); /* start things off */ + sim_activate(uptr, 20); /* start things off */ +#else + sim_activate(uptr, 100); /* start things off */ +#endif + return SNS_CHNEND|SNS_DEVEND; +} + +/* Handle processing of disk requests. */ +t_stat scsi_srv(UNIT *uptr) +{ + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + /* get pointer to Dev Info Blk for this device */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + int cmd = uptr->CMD & DSK_CMDMSK; + int type = GET_TYPE(uptr->flags); + int unit = (uptr - dptr->units); + int bufnum = GET_DEV_BUF(dptr->flags); + int len=0; + int i; + uint32 cap = CAP(type); + uint32 mema; /* memory address */ + uint8 ch; + int32 ssize = scsi_type[type].ssiz*4; /* Size of one sector in bytes */ + uint32 tstart = 0; /* Location of start of cyl/track/sect in data */ + uint8 buf2[1024]; + uint8 buf[1024]; + + sim_debug(DEBUG_DETAIL, &sba_dev, + "scsi_srv entry unit %02x CMD %08x chsa %04x count %04x %x/%x/%x \n", + unit, uptr->CMD, chsa, chp->ccw_count, + STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff)); + + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + if (cmd != DSK_SNS) /* we are completed with unit check status */ + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; + } + + sim_debug(DEBUG_CMD, dptr, + "scsi_srv cmd=%02x chsa %04x count %04x SNS %02x\n", + cmd, chsa, chp->ccw_count, uptr->SNS); + switch (cmd) { + case 0: /* No command, stop disk */ + break; + + case DSK_INCH2: /* use 0xF0 for inch, just need int */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv starting INCH cmd, chsa %04x MemBuf %06x cnt %04x\n", + chsa, chp->ccw_addr, chp->ccw_count); + +#if 0 + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ +#endif + /* mema has IOCD word 1 contents. For the MFP (scsi processor) */ + /* a pointer to the INCH buffer. The INCH buffer address must be */ + /* set for the parent channel as well as all other devices on the */ + /* channel. Call set_inch() to do this for us. Just return OK and */ + /* channel software will use the status buffer addr */ + + /* now call set_inch() function to write and test inch buffer addresses */ + /* 1-256 wd buffer is provided for 128 status dbl words */ + i = set_inch(uptr, mema, 128); /* new address of 33 entries */ + if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + uptr->CMD &= LMASK; /* remove old cmd */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv cmd INCH chsa %04x chsa %06x count %04x completed\n", + chsa, mema, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_NOP: /* NOP 0x03 */ + uptr->CMD &= LMASK; /* remove old cmd */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv cmd NOP chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + /* 3 status wds are to be returned */ + /* Wd 1 MMXXXXXX board model # assume 00 00 08 02*/ + /* Wd 2 MMXXXXXX board firmware model # assume 00 00 08 02*/ + /* Wd 3 MMXXXXXX board firmware revision # assume 00 00 00 14*/ + case DSK_SID: /* 0x80 */ /* this is really for the MFP controller */ + /* send 12 byte Status ID data */ + /* Word 0 */ /* board mod 4324724 = 0x0041fd74 */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 0 */ + ch = 0x41; + chan_write_byte(chsa, &ch); /* write byte 1 */ + ch = 0xfd; + chan_write_byte(chsa, &ch); /* write byte 2 */ + ch = 0x74; + chan_write_byte(chsa, &ch); /* write byte 3 */ + + /* Word 1 */ /* firmware 4407519 = 0x004340df */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 4 */ + ch = 0x43; + chan_write_byte(chsa, &ch); /* write byte 5 */ + ch = 0x40; + chan_write_byte(chsa, &ch); /* write byte 6 */ + ch = 0xdf; + chan_write_byte(chsa, &ch); /* write byte 7 */ + + /* Word 2 */ /* firmware rev 4259588 = 0x0040ff04 */ + ch = 0x00; + chan_write_byte(chsa, &ch); /* write byte 8 */ + ch = 0x40; + chan_write_byte(chsa, &ch); /* write byte 9 */ + ch = 0xff; + chan_write_byte(chsa, &ch); /* write byte 10 */ + ch = 0x04; + chan_write_byte(chsa, &ch); /* write byte 11 */ + + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "scsi_srv SID chan %02x: chnend|devend\n", chsa); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case DSK_SNS: /* 0x4 */ + sim_debug(DEBUG_CMD, dptr, "scsi_startcmd CMD sense\n"); + + /* bytes 0,1 - Cyl entry from CHS reg */ + ch = (uptr->CHS >> 24) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense CHS b0 unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->CHS >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense CHS b1 unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 2 - Track entry from CHS reg */ + ch = (uptr->CHS >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense CHS b2 unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 3 - Sector entry from CHS reg */ + ch = (uptr->CHS) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense CHS b3 unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + /* bytes 4 - mode reg, byte 0 of SNS */ + /* skip the TCMD bit */ + ch = (uptr->SNS >> 24) & 0xfe; /* return the sense data */ + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* bytes 5-7 - status bytes, bytes 1-3 of SNS */ + ch = (uptr->SNS >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_SCK: /* Seek cylinder, track, sector 0x07 */ + /* If we are waiting on seek to finish, check if there yet. */ + if (uptr->CMD & DSK_SEEKING) { + /* see if on cylinder yet */ + if (uptr->STAR == uptr->CHS) { + /* we are on cylinder, seek is done */ + sim_debug(DEBUG_CMD, dptr, "scsi_srv seek on sector unit=%02x %06x %06x\n", + unit, uptr->STAR, uptr->CHS); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* we have already seeked to the required sector */ + /* we do not need to seek again, so move on */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + return SCPE_OK; + break; + } else { + /* we have wasted enough time, we there */ + /* we are on cylinder, seek is done */ + sim_debug(DEBUG_CMD, dptr, "scsi_srv seek over on cylinder unit=%02x %04x %04x\n", + unit, uptr->STAR, uptr->CHS); + uptr->CHS = uptr->STAR; /* we are there */ +#ifdef FAST_FOR_UTX + sim_activate(uptr, 20); /* start things off */ +#else + sim_activate(uptr, 40); +#endif + break; + } + } + + /* not seeking, so start a new seek */ + /* Read in 1-4 character seek code */ + for (i = 0; i < 4; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (i == 0) { + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv seek error unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + /* done reading, see how many we read */ + if (i == 1) { + /* UTX wants to set seek STAR to zero */ + buf[0] = buf[1] = buf[2] = buf[3] = 0; + break; + } + /* just read the next byte */ + } + } + /* else the cyl, trk, and sect are ready to update */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv STAR unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv seek unit=%02x star %02x%02x%02x%02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + /* save STAR (target sector) data in STAR */ + uptr->STAR = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); + + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv SEEK %08x sector %06x (%d) unit=%02x\n", + uptr->CMD, uptr->STAR, uptr->STAR, unit); + + /* Check if seek valid */ + if (uptr->STAR >= CAP(type)) { + sim_debug(DEBUG_CMD, dptr, + "scsi_srv seek ERROR sector %06x unit=%02x\n", + uptr->STAR, unit); + + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; /* set error status */ + + /* we have an error, tell user */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* end command */ + break; + } + + /* calc the new sector address of data */ + /* calculate file position in bytes of requested sector */ + /* file offset in bytes */ + tstart = uptr->STAR * SSB(type); + + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv seek start %04x sector %06x\n", + tstart, uptr->STAR); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* seek r/w sec */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv Error on seek to %08x\n", tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* Check if already on correct cylinder */ + /* if not, do a delay to slow things down */ + if (uptr->STAR != uptr->CHS) { + /* Do a fake seek to kill time */ + uptr->CMD |= DSK_SEEKING; /* show we are seeking */ + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv seeking unit=%02x to sector %06x\n", + unit, uptr->STAR); +#ifdef FAST_FOR_UTX + /* making this value 40 or so create volume mount error on boot */ + sim_activate(uptr, 20); /* start things off */ +#else + sim_activate(uptr, 40); +#endif + } else { + /* we are on cylinder/track/sector, so go on */ + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv calc sect addr seek start %08x sector %06x\n", + tstart, uptr->STAR); + uptr->CHS = uptr->STAR; /* set new sector position */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + } + return SCPE_OK; + + case DSK_XEZ: /* Rezero & Read IPL record */ + + sim_debug(DEBUG_CMD, dptr, "RD REZERO IPL unit=%02x seek 0\n", unit); + /* Do a seek to 0 */ + uptr->STAR = 0; /* set STAR to 0, 0, 0 */ + uptr->CHS = 0; /* set current CHS to 0, 0, 0 */ + uptr->CMD &= LMASK; /* remove old cmd */ + uptr->CMD |= DSK_SCK; /* show as seek command */ + tstart = 0; /* byte offset is 0 */ + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "scsi_srv Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + /* we are on cylinder/track/sector zero, so go on */ + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv done seek trk 0\n"); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); + return SCPE_OK; + break; + + case DSK_LMR: + sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x\n", unit); + /* Read in 1 character of mode data */ + if (chan_read_byte(chsa, &buf[0])) { + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x old %x new %x\n", + unit, (uptr->SNS)&0xff, buf[0]); + uptr->CMD &= LMASK; /* remove old cmd */ + /* leave the TCMD bit */ + uptr->SNS &= (MASK24 | SNS_TCMD); /* clear old mode data */ + /* do not change TCMD bit */ + uptr->SNS |= ((buf[0]&0xfe) << 24); /* save mode value */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + + case DSK_RD: /* 0x02 Read Data */ + if (uptr->SNS & SNS_TCMD) { + /* we need to process a read TCMD data */ + int cnt = scsi_buf[bufnum][unit][4]; /* byte count of status to send */ + uint32 cyl = CYL(type); /* number of cylinders */ + uint32 spt = SPT(type); /* sectors per track */ + uint32 ssb = SSB(type); /* sector size in bytes */ + int bcnt; + + /* cnt has # bytes to return (0xf0) */ + uint8 pagecode = scsi_buf[bufnum][unit][2] & 0x3f; /* get page code */ + uint8 pagecont = (scsi_buf[bufnum][unit][2] & 0xc0) >> 6; /* get page control */ + + ch = scsi_buf[bufnum][unit][0]; /* return TCMD cmd */ + uptr->SNS &= ~SNS_TCMD; /* show not presessing TCMD cmd chain */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv processing TCMD read cmd %02x, chsa %04x tcma %06x cnt %04x\n", + ch, chsa, chp->ccw_addr, chp->ccw_count); + + switch (ch) { + case 0x25: /* read capacity */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv TCMD read call DSK_RCAP cmd %02x, chsa %04x tcma %06x cnt %04x\n", + ch, chsa, chp->ccw_addr, chp->ccw_count); + goto read_cap; /* use IOCL cmd processing */ + break; + + case 0x28: /* read 10 byte cmd */ + /* blk is in bytes 2-5, sects is in 7-8 */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv TCMD call read cmd %02x, chsa %04x tcma %06x cnt %04x\n", + ch, chsa, chp->ccw_addr, chp->ccw_count); + tstart = (scsi_buf[bufnum][unit][2] << 24) | /* get sector address */ + (scsi_buf[bufnum][unit][3] << 16) | + (scsi_buf[bufnum][unit][4] << 8) | + (scsi_buf[bufnum][unit][5]); + bcnt = (scsi_buf[bufnum][unit][8] << 8) | /* get transfer block count */ + (scsi_buf[bufnum][unit][9]); + sim_debug(DEBUG_CMD, dptr, + "scsi_srv TCMD call read DATA cmd %02x, chsa %04x buf addr %08x SA %08x cnt %02x\n", + ch, chsa, chp->ccw_addr, tstart, bcnt); + + /* convert sect address to chs value */ + uptr->CHS = tstart; + /* get byte address for seek */ + tstart = tstart * SSB(type); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "scsi_srv read TCMD Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + /* we are on cylinder/track/sector, get data to write */ + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv TCMD done seek\n"); + tstart = uptr->CHS; /* get sector offset back */ + goto doread; /* use IOCL cmd processing */ + break; + + case 0x1a: /* mode sense */ + for (i=0; i> 6; /* get page control */ + /* pagecont = 0 return current values */ + /* pagecont = 1 return changable values */ + /* pagecont = 2 return default values */ + /* pagecont = 3 return saved values */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv TCMD read call MOD SEN cmd %02x pgcd %02x pgco %1x chsa %04x tcma %06x cnt %04x\n", + ch, pagecode, pagecont, chsa, chp->ccw_addr, chp->ccw_count); + buf[0] = 0xf0; /* page length */ + if (pagecode == 3) { + buf[2] = 0; /* 0x80 if write protected */ + buf[3] = 0; /* block descriptor length */ +// buf[4] = 0x83; /* savable and page type 3 */ + buf[4] = 0x03; /* not savable and page type 3 */ + buf[5] = 22; /* 22 data bytes follow */ + buf[6] = 0; /* tracks per zone ub */ + buf[7] = 1; /* tracks per zone lb */ + buf[8] = 0; /* alt sec per zone ub */ + buf[9] = 1; /* alt sec per zone lb */ + buf[10] = 0; /* alt trks per zone ub */ + buf[11] = 0; /* alt trks per zone lb */ + buf[12] = 0; /* alt trks per unit ub */ + buf[13] = 0; /* alt trks per unit lb */ + buf[14] = (uint8)((spt & 0xff00) >> 8); /* Sect/track */ + buf[15] = (uint8)((spt & 0x00ff)); /* Sect/track */ + buf[16] = (uint8)((ssb & 0xff00) >> 8); /* Sect size */ + buf[17] = (uint8)((ssb & 0x00ff)); /* Sect size */ + buf[18] = 0; /* interleave ub */ + buf[19] = 0; /* interleave lb */ + buf[20] = 0; /* track skew factor ub */ + buf[21] = 0; /* track skew factor lb */ + buf[22] = 0; /* cyl skew factor ub */ + buf[23] = 0; /* cyl skew factor lb */ +// buf[24] |= 0x80; /* soft sectoring */ + buf[24] |= 0x40; /* hard sectoring */ +// buf[24] |= 0x20; /* drive removable */ +// buf[24] |= 0x08; /* inhibit save */ + goto merge; /* go output data and return */ + } + if (pagecode == 4) { + /* num cyl */ + buf[2] = 0; /* 0x80 if write protected */ + buf[3] = 0; /* block descriptor length */ +// buf[4] = 0x84; /* savable and page type 4 */ + buf[4] = 0x04; /* not savable and page type 4 */ + buf[5] = 18; /* 18 data bytes follow */ + buf[6] = (uint8)((cyl & 0xff0000) >> 16); + buf[7] = (uint8)((cyl & 0x00ff00) >> 8); + buf[8] = (uint8)((cyl & 0x0000ff)); + buf[9] = (uint8)HDS(type); /* # of heads */ + goto merge; /* go output data and return */ + } + + case 0x12: /* inquiry */ + /* size is 0x24 = 36 bytes */ + /* ssize has sector size in bytes */ + for (i=0; iCMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + } + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv TCMD inq read data chsa=%02x data %02x%02x%02x%02x %02x%02x%02x%02x\n", + chsa, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv TCMD inq read data chsa=%02x data %02x%02x%02x%02x %02x%02x%02x%02x\n", + chsa, buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]); + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv TCMD inq read data chsa=%02x data %02x%02x%02x%02x %02x%02x%02x%02x\n", + chsa, buf[16], buf[17], buf[18], buf[19], buf[20], buf[21], buf[22], buf[23]); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + break; + + case 0x00: /* test unit ready */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, "scsi_srv test unit ready cmd %02x unit %02x\n", ch, unit); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + break; + + default: /* bad or unsupported scsi command */ + sim_debug(DEBUG_CMD, dptr, "invalid scsi read command %02x unit %02x\n", ch, unit); + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + } + +doread: + /* normal disk read starts here */ + /* tstart has start of sector address in bytes */ + if ((uptr->CMD & DSK_READING) == 0) { /* see if we are reading data */ + uptr->CMD |= DSK_READING; /* read from disk starting */ + sim_debug(DEBUG_CMD, dptr, + "SCSI READ starting unit=%02x CMD %08x count %04x\n", + unit, uptr->CMD, chp->ccw_count); + } + + if (uptr->CMD & DSK_READING) { /* see if we are reading data */ + tstart = uptr->CHS; /* get sector offset */ + + sim_debug(DEBUG_CMD, dptr, + "SCSI READ reading CMD %08x chsa %04x tstart %04x buffer %06x count %04x\n", + uptr->CMD, chsa, tstart, chp->ccw_addr, chp->ccw_count); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart*SSB(type), SEEK_SET)) != 0) { /* seek r/w sec */ + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv READ, Error on seek to %08x\n", tstart*SSB(type)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* read in a sector of data from disk */ + if ((len=sim_fread(buf, 1, ssize, uptr->fileref)) != ssize) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on read %04x of diskfile sector %06x\n", + len, ssize, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_CMD, dptr, "scsi_srv after READ chsa %04x count %04x\n", + chsa, chp->ccw_count); + + /* process the sector of data */ + for (i=0; iccw_count, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + } + + sim_debug(DEBUG_CMD, dptr, + "SCSI READ %04x bytes leaving %4x to be read to %06x from diskfile sector %06x\n", + ssize, chp->ccw_count, chp->ccw_addr+4, tstart); + + /* see if we are done reading data */ + if (test_write_byte_end(chsa)) { + sim_debug(DEBUG_DATA, dptr, + "SCSI Read complete for read from diskfile sector %06x\n", + uptr->CHS); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + break; + } + + /* tstart has file offset in sectors */ + tstart++; /* bump to next sector */ + uptr->CHS = tstart; /* new position */ + /* see if over end of disk */ + if (tstart >= (uint32)CAP(type)) { + /* EOM reached, abort */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Read reached EOM for read from disk @ sector %06x\n", + tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CHS = 0; /* reset cylinder position */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + + sim_debug(DEBUG_DATA, dptr, + "SCSI sector read complete, %x bytes to go from diskfile sector %06x\n", + chp->ccw_count, uptr->CHS); +#ifdef FAST_FOR_UTX +//zz sim_activate(uptr, 10); /* start things off */ + sim_activate(uptr, 15); /* start things off */ +#else + sim_activate(uptr, 10); /* wait to read next sector */ +//BAD4MPX sim_activate(uptr, 40); /* wait to read next sector */ +#endif + break; + } + break; + + case DSK_WD: /* Write Data */ + if (uptr->SNS & SNS_TCMD) { + /* we need to process a write TCMD data */ +//? int cnt = scsi_buf[bufnum][unit][4]; /* byte count of status to read */ + /* cnt has # bytes to read */ + int cnt = chp->ccw_count; /* byte count of status to read */ + + ch = scsi_buf[bufnum][unit][0]; /* return TCMD cmd */ + uptr->SNS &= ~SNS_TCMD; /* show not presessing TCMD cmd chain */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv processing TCMD write cmd %02x, chsa %04x tcma %06x cnt %04x\n", + ch, chsa, chp->ccw_addr, chp->ccw_count); + + switch (ch) { + + case 0x4: /* write 6 byte cmd, format disk */ + if (scsi_buf[bufnum][unit][2] == 10) { + if ((--scsi_buf[bufnum][unit][3]) > 0) { + uptr->SNS |= SNS_TCMD; /* show still presessing TCMD cmd chain */ + sim_activate(uptr, 200000); /* wait a while */ + return SCPE_OK; + break; + } + scsi_buf[bufnum][unit][2] = 0; /* show done */ + } + /* MPX cmd data 04 18 00 00 00 00 */ + /* Format unit */ + len = 0; + for (i=0; iCMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Read %04x bytes from MPX buffer\n", len); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + ch = 0; /* finish out the sector with zero */ + len++; /* show we have no more data to write */ + } + buf2[i] = ch; /* save the char */ + } + sim_debug(DEBUG_CMD, dptr, "SCSI CMD 4 %04x bytes read from MPX buffer\n", cnt); + sim_debug(DEBUG_CMD, dptr, + "SCSI Disk format buf2 %02x%02x%02x%02x\n", buf2[0], buf2[1], buf2[2], buf2[3]); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + break; + + case 0x15: /* write 6 byte cmd, format disk */ + /* MODE select */ + len = 0; + for (i=0; iCMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Read %04x bytes from MPX buffer\n", len); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + ch = 0; /* finish out the sector with zero */ + len++; /* show we have no more data to write */ + } + buf2[i] = ch; /* save the char */ + } + sim_debug(DEBUG_CMD, dptr, "SCSI Format %04x bytes to status buffer\n", cnt); + sim_debug(DEBUG_CMD, dptr, + "SCSI Disk format buf2 %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", + buf2[0], buf2[1], buf2[2], buf2[3], buf2[4], buf2[5], buf2[6], buf2[7], + buf2[8], buf2[9], buf2[10], buf2[11], buf2[12], buf2[13], buf2[14], buf2[15]); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + break; + + case 0x2a: /* write 10 byte cmd */ + tstart = (scsi_buf[bufnum][unit][2] << 24) | /* get sector address */ + (scsi_buf[bufnum][unit][3] << 16) | + (scsi_buf[bufnum][unit][4] << 8) | + (scsi_buf[bufnum][unit][5]); + sim_debug(DEBUG_CMD, dptr, + "scsi_srv TCMD call write DATA cmd %02x, chsa %04x addr %08x data %08x %08x\n", + ch, chsa, chp->ccw_addr, RMW(chp->ccw_addr), RMW(chp->ccw_addr+4)); + + /* convert sect address to chs value */ + uptr->CHS = tstart; /* set seek sector address */ + /* get byte address for seek */ + tstart = tstart * SSB(type); + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */ + sim_debug(DEBUG_EXP, dptr, "scsi_srv TCMD Error on seek to %04x\n", tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + /* we are on cylinder/track/sector, get data to write */ + sim_debug(DEBUG_DETAIL, dptr, "scsi_srv TCMD done seek\n"); + tstart = uptr->CHS; /* get sector offset */ + goto dowrite; + break; + + default: /* bad or unsupported scsi command */ + sim_debug(DEBUG_CMD, dptr, "invalid scsi write command %02x unit %02x\n", ch, unit); + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + break; + } +dowrite: + /* tstart has file offset in sectors */ + if ((uptr->CMD & DSK_WRITING) == 0) { /* see if we are writing data */ + uptr->CMD |= DSK_WRITING; /* write to disk starting */ + sim_debug(DEBUG_CMD, dptr, + "SCSI WRITE starting unit=%02x CMD %02x write %4x from %06x to sector %06x\n", + unit, uptr->CMD, chp->ccw_count, chp->ccw_addr, uptr->CHS); + } + if (uptr->CMD & DSK_WRITING) { /* see if we are writing data */ + tstart = uptr->CHS; /* get sector offset */ + + /* just seek to the location where we will r/w data */ + if ((sim_fseek(uptr->fileref, tstart*SSB(type), SEEK_SET)) != 0) { /* seek r/w sec */ + sim_debug(DEBUG_EXP, dptr, + "scsi_srv WRITE, Error on seek to %08x\n", tstart*SSB(type)); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } + + /* process the next sector of data */ + len = 0; /* used here as a flag for short read */ + for (i=0; iCMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Wrote %04x bytes to diskfile sector %06x\n", + ssize, tstart); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + ch = 0; /* finish out the sector with zero */ + len++; /* show we have no more data to write */ + } + buf2[i] = ch; /* save the char */ + } + + /* write the sector to disk */ + if ((i=sim_fwrite(buf2, 1, ssize, uptr->fileref)) != ssize) { + sim_debug(DEBUG_CMD, dptr, + "Error %08x on write %04x bytes to diskfile sector %06x\n", + i, ssize, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (len != 0) { /* see if done with write command */ + sim_debug(DEBUG_DATA, dptr, + "SCSI WroteB %04x bytes to diskfile sector %06x\n", + ssize, tstart); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ + break; + } + sim_debug(DEBUG_CMD, dptr, + "SCSI WR to sec end %04x bytes end %04x to diskfile sector %06x\n", + len, ssize, tstart); + + /* tstart has file offset in sectors */ + tstart++; /* bump to next sector */ + uptr->CHS = tstart; /* save new sector */ + /* see if over end of disk */ + if (tstart >= (uint32)CAP(type)) { + /* EOM reached, abort */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Write reached EOM for write to disk @ sector %06x\n", + uptr->CHS); + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->CHS = 0; /* reset cylinder position */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } +#ifdef FAST_FOR_UTX +//zz sim_activate(uptr, 10); /* start things off */ + sim_activate(uptr, 20); /* start things off */ +#else + sim_activate(uptr, 10); /* keep writing */ +//BAD4MPX sim_activate(uptr, 40); /* keep writing */ +#endif + break; + } + break; + + case DSK_RCAP: /* Read Capacity 0x53 */ + /* return 8 bytes */ + /* wd 1 disk size in sectors */ + /* wd 2 is sector size in bytes */ + /* cap has disk capacity */ +read_cap: /* merge point from TCMD processing */ +#if 0 + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ +#endif + for (i=0; i<4; i++) { + /* I think they want cap-1, not cap?????????? */ + /* verified that MPX wants cap-1, else J.VFMT aborts */ + ch = ((cap-1) >> ((3-i)*8)) & 0xff; /* use cap-1 */ + if (chan_write_byte(chsa, &ch)) { /* write byte to memory */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + } + /* ssize has sector size in bytes */ + for (i=0; i<4; i++) { + ch = (((uint32)ssize) >> ((3-i)*8)) & 0xff; + if (chan_write_byte(chsa, &ch)) { + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + } + + /* command is completed */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv cmd RCAP chsa %04x capacity %06x secsize %03x completed\n", + chsa, cap, ssize); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + /* Transfer Command Packet (specifies CDB to send) */ + /* address points to CDB */ + case DSK_TCMD: /* Transfer command packet 0xD3 */ + { + uint32 mema; /* memory address */ + int32 i; + + uptr->SNS &= ~SNS_TCMD; /* show not presessing TCMD cmd chain */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv starting TCMD cmd, chsa %04x tcma %06x cnt %04x\n", + chsa, chp->ccw_addr, chp->ccw_count); + +#if 0 + cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */ +#endif + /* mema has IOCD word 1 contents. */ + /* len has the byte count from IOCD wd2 */ + len = chp->ccw_count; /* TCMD command count */ + + for (i=0; i < len; i++) { + if (chan_read_byte(chsa, &buf[i])) { + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + break; + } + } + sim_debug(DEBUG_DETAIL, dptr, + "scsi_srv TCMD data chsa=%02x data %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + chsa, buf[0], buf[1], buf[2], buf[3], buf[4], + buf[5], buf[6], buf[7], buf[8], buf[9]); + + /* save the CMD packet */ + for (i=0; i < len; i++) { + scsi_buf[bufnum][unit][i] = buf[i]; /* save the cmd */ + } + scsi_pcmd[bufnum][unit] = buf[0]; /* save the cmd */ + + /* if this a disk format, do a big wait */ + if ((buf[0] == 4) && (buf[1] == 0x18)) { + scsi_buf[bufnum][unit][2] = 10; /* show Processing Format cmd */ + scsi_buf[bufnum][unit][3] = 10; /* show Processing cmd */ + } + + /* see if just test unit ready */ + if ((buf[0] == 0) && (len == 6)) + uptr->SNS &= ~SNS_TCMD; /* clear TCMD flag */ + else + uptr->SNS |= SNS_TCMD; /* show Processing CMD cmd chain */ + + /* command is completed */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_CMD, dptr, + "scsi_srv cmd TCMD chsa %04x addr %06x count %04x completed\n", + chsa, mema, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + } + return SCPE_OK; + break; + + default: + sim_debug(DEBUG_EXP, dptr, "invalid command %02x unit %02x\n", cmd, unit); + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + return SNS_CHNEND|STATUS_PCHK; + break; + } + sim_debug(DEBUG_CMD, dptr, + "scsi_srv done cmd %02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count); + return SCPE_OK; +} + +/* initialize the disk */ +void scsi_ini(UNIT *uptr, t_bool f) +{ + DEVICE *dptr = get_dev(uptr); + int i = GET_TYPE(uptr->flags); + + /* start out at sector 0 */ + uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */ + uptr->STAR = 0; /* set STAR to cyl/hd/sec = 0 */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS = 0; /* clear any status */ + /* total sectors on disk */ + uptr->capac = CAP(i); /* disk size in sectors */ + sim_cancel(uptr); /* stop any timers */ + + sim_debug(DEBUG_EXP, &sba_dev, "SCSI init device %s on unit SBA%04x cap %x %d\n", + dptr->name, GET_UADDR(uptr->CMD), uptr->capac, uptr->capac); +} + +/* handle rschnlio cmds for scsi */ +t_stat scsi_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & DSK_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, + "scsi_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + scsi_ini(uptr, 0); /* reset the unit */ + return SCPE_OK; +} + +t_stat scsi_reset(DEVICE *dptr) +{ + UNIT *uptr = dptr->units; + uint16 chsa = GET_UADDR(uptr->CMD); + + /* add reset code here */ + sim_debug(DEBUG_EXP, dptr, + "scsi_reset chsa %04x\n", chsa); + return SCPE_OK; +} + +/* create the disk file for the specified device */ +int scsi_format(UNIT *uptr) { + int type = GET_TYPE(uptr->flags); + DEVICE *dptr = get_dev(uptr); + int32 ssize = scsi_type[type].ssiz * 4; /* disk sector size in bytes */ + uint32 tsize = scsi_type[type].spt; /* get track size in sectors */ + uint32 csize = scsi_type[type].nhds * tsize; /* get cylinder size in sectors */ + uint32 cyl = scsi_type[type].cyl; /* get # cyl */ + uint32 cap = scsi_type[type].cyl * csize; /* disk capacity in sectors */ + uint32 cylv = cyl; /* number of cylinders */ + uint8 *buff; + int i; + t_stat oldsw = sim_switches; /* save switches */ + + /* last sector address of disk (cyl * hds * spt) - 1 */ + uint32 laddr = CAP(type) - 1; /* last sector of disk */ + + /* last track address of disk (cyl * hds * spt) - spt */ + uint32 ltaddr = CAP(type)-SPT(type); /* last sector of disk */ + + /* get sector address of vendor defect table VDT */ + /* put data = 0xf0000000 0xf4000000 */ + int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type); + + /* get sector address of utx diag map (DMAP) track 0 pointer */ + /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ + /* 0x9a000000 + (cyl-1), 0xf4000008 */ + int32 daddr = (CYL(type)-4) * SPC(type) + (HDS(type)-2) * SPT(type); + + /* get sector address of utx flaw data (1 track long) */ + /* set trace data to zero */ + int32 faddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); + + /* get sector address of utx flaw map sec 1 pointer */ + /* use this address for sec 1 label pointer */ + int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type); + + /* last user block available */ + int32 luaddr = (CYL(type)-4) * SPC(type); + + /* make up a UMAP with the partiton data for 9346 disk */ + uint32 umap[256] = + { + /* try to makeup a utx dmap */ + 0x4e554d50,(cap-1),(uint32)(luaddr-1),0,0,0,0,0xe10, + 0,0x5320,0,0x4e60,0x46,(uint32)luaddr,0,0xd360, + 0x88,0x186b0,0x13a,0xd100,0x283,0,0,0, + 0,0x22c2813e,0,0x06020000,0xf4,0,0x431b1c,0, + }; + + /* vendor flaw map in vaddr */ + uint32 vmap[2] = {0xf0000004, 0xf4000000}; + + /* defect map */ + uint32 dmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr, + 0x9a000000 | (cap-1), 0xf4000000}; + + /* utx flaw map */ + uint32 fmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr, + 0x9a000000 | ltaddr, 0xf4000000}; + + /* see if -i or -n specified on attach command */ + if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) { + sim_switches = 0; /* simh tests 'N' & 'Y' switches */ + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { + sim_switches = oldsw; + return 1; + } + sim_switches = oldsw; /* restore switches */ + } + +#if 0 + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { + return 1; + } +#endif + + /* VDT 249264 (819/18/0) 0x3cdb0 for 9346 - 823/19/16 vaddr */ + /* MDT 249248 (819/17/0) 0x3cda0 for 9346 - 823/19/16 daddr */ + /* DMAP 249232 (819/16/0) 0x3cd90 for 9346 - 823/19/16 faddr */ + /* UMAP 249216 (819/15/0) 0x3cd80 for 9346 - 823/19/16 uaddr */ + + /* seek to sector 0 */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + } + + /* get buffer for track data */ + if ((buff = (uint8 *)calloc(csize*ssize, sizeof(uint8))) == 0) { + detach_unit(uptr); + return SCPE_ARG; + } + sim_debug(DEBUG_CMD, dptr, + "Creating disk file of trk size %04x bytes, capacity %d\n", + tsize*ssize, cap*ssize); + + /* write zeros to each track of the disk */ + for (cyl = 0; cyl < cylv; cyl++) { + if ((sim_fwrite(buff, 1, csize*ssize, uptr->fileref)) != csize*ssize) { + sim_debug(DEBUG_CMD, dptr, + "Error on write to diskfile cyl %04x\n", cyl); + free(buff); /* free cylinder buffer */ + buff = 0; + return 1; + } + if ((cyl % 100) == 0) + fputc('.', stderr); + } + fputc('\r', stderr); + fputc('\n', stderr); + free(buff); /* free cylinder buffer */ + buff = 0; + + /* byte swap the buffers for dmap and umap */ + for (i=0; i<2; i++) { + vmap[i] = (((vmap[i] & 0xff) << 24) | ((vmap[i] & 0xff00) << 8) | + ((vmap[i] & 0xff0000) >> 8) | ((vmap[i] >> 24) & 0xff)); + } + for (i=0; i<4; i++) { + dmap[i] = (((dmap[i] & 0xff) << 24) | ((dmap[i] & 0xff00) << 8) | + ((dmap[i] & 0xff0000) >> 8) | ((dmap[i] >> 24) & 0xff)); + } + for (i=0; i<4; i++) { + fmap[i] = (((fmap[i] & 0xff) << 24) | ((fmap[i] & 0xff00) << 8) | + ((fmap[i] & 0xff0000) >> 8) | ((fmap[i] >> 24) & 0xff)); + } + for (i=0; i<256; i++) { + umap[i] = (((umap[i] & 0xff) << 24) | ((umap[i] & 0xff00) << 8) | + ((umap[i] & 0xff0000) >> 8) | ((umap[i] >> 24) & 0xff)); + } + + /* now seek to end of disk and write the dmap data */ + /* setup dmap pointed to by track label 0 wd[3] = (cyl-4) * spt + (spt - 1) */ + + /* write dmap data to last sector on disk */ + if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */ + sim_debug(DEBUG_CMD, dptr, + "Error on last sector seek to sect %06x offset %06x\n", + cap-1, (cap-1)*ssize); + return 1; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Error writing DMAP to sect %06x offset %06x\n", + cap-1, (cap-1)*ssize); + return 1; + } + + /* seek to vendor label area VMAP */ + if ((sim_fseek(uptr->fileref, vaddr*ssize, SEEK_SET)) != 0) { /* seek VMAP */ + sim_debug(DEBUG_CMD, dptr, + "Error on vendor map seek to sect %06x offset %06x\n", + vaddr, vaddr*ssize); + return 1; + } + if ((sim_fwrite((char *)&vmap, sizeof(uint32), 2, uptr->fileref)) != 2) { + sim_debug(DEBUG_CMD, dptr, + "Error writing VMAP to sect %06x offset %06x\n", + vaddr, vaddr*ssize); + return 1; + } + + /* write DMAP to daddr that is the address in trk 0 label */ + if ((sim_fseek(uptr->fileref, daddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */ + sim_debug(DEBUG_CMD, dptr, + "Error on diag map seek to sect %06x offset %06x\n", + daddr, daddr*ssize); + return 1; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Error writing DMAP to sect %06x offset %06x\n", + daddr, daddr*ssize); + return 1; + } + + /* write dummy DMAP to faddr */ + if ((sim_fseek(uptr->fileref, faddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */ + sim_debug(DEBUG_CMD, dptr, + "Error on media flaw map seek to sect %06x offset %06x\n", + faddr, faddr*ssize); + return 1; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "Error writing flaw map to sect %06x offset %06x\n", + faddr, faddr*ssize); + return 1; + } + + /* write UTX umap to uaddr */ + if ((sim_fseek(uptr->fileref, uaddr*ssize, SEEK_SET)) != 0) { /* seek UMAP */ + sim_debug(DEBUG_CMD, dptr, + "Error on umap seek to sect %06x offset %06x\n", + uaddr, uaddr*ssize); + return 1; + } + if ((sim_fwrite((char *)&umap, sizeof(uint32), 256, uptr->fileref)) != 256) { + sim_debug(DEBUG_CMD, dptr, + "Error writing UMAP to sect %06x offsewt %06x\n", + uaddr, uaddr*ssize); + return 1; + } + + printf("SCSI Disk %s has %x (%d) cyl, %x (%d) hds, %x (%d) sec\r\n", + scsi_type[type].name, CYL(type), CYL(type), HDS(type), HDS(type), + SPT(type), SPT(type)); + printf("writing to vmap sec %x (%d) bytes %x (%d)\n", + vaddr, vaddr, (vaddr)*ssize, (vaddr)*ssize); + printf("writing to flaw map sec %x (%d) bytes %x (%d)\n", + faddr, faddr, (faddr)*ssize, (faddr)*ssize); + printf("writing dmap to %x %d %x %d dmap to %x %d %x %d\n", + cap-1, cap-1, (cap-1)*ssize, (cap-1)*ssize, + daddr, daddr, daddr*ssize, daddr*ssize); + printf("writing to umap sec %x (%d) bytes %x (%d)\n", + uaddr, uaddr, (uaddr)*ssize, (uaddr)*ssize); + + /* seek home again */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + fprintf (stderr, "Error on seek to 0\r\n"); + return 1; + } + return 0; +} + +/* attach the selected file to the disk */ +t_stat scsi_attach(UNIT *uptr, CONST char *file) { + uint16 chsa = GET_UADDR(uptr->CMD); + int type = GET_TYPE(uptr->flags); + DEVICE *dptr = get_dev(uptr); + DIB *dibp = 0; + t_stat r, s; + uint32 ssize; /* sector size in bytes */ + uint32 info, good,zmap = 0x5a4d4150; /* ZMAP */ + uint8 buff[1024]; + int i, j; + + /* last sector address of disk (cyl * hds * spt) - 1 */ + uint32 laddr = CAP(type) - 1; /* last sector of disk */ + /* defect map */ + uint32 dmap[4] = {0xf0000000 | (CAP(type)-1), 0x8a000000, + 0x9a000000 | (CAP(type)-1), 0xf4000000}; + + for (i=0; i<4; i++) { /* byte swap data for last sector */ + dmap[i] = (((dmap[i] & 0xff) << 24) | ((dmap[i] & 0xff00) << 8) | + ((dmap[i] & 0xff0000) >> 8) | ((dmap[i] >> 24) & 0xff)); + } + + uptr->SNS = 0; /* clear any status */ + + /* see if valid disk entry */ + if (scsi_type[type].name == 0) { /* does the assigned disk have a name */ + detach_unit(uptr); /* no, reject */ + return SCPE_FMT; /* error */ + } + + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, + "ERROR===ERROR\nSCSI Disk device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nSCSI Disk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + /* have simulator attach the file to the unit */ + if ((r = attach_unit(uptr, file)) != SCPE_OK) + return r; + + uptr->capac = CAP(type); /* disk capacity in sectors */ + ssize = SSB(type); /* get sector size in bytes */ + for (i=0; i<(int)ssize; i++) + buff[i] = 0; /* zero the buffer */ + + sim_debug(DEBUG_CMD, dptr, "SCSI Disk %s %04x cyl %d hds %d sec %d ssiz %d capacity %d\n", + scsi_type[type].name, chsa, scsi_type[type].cyl, scsi_type[type].nhds, + scsi_type[type].spt, ssize, uptr->capac); /* disk capacity */ + printf("SCSI Disk %s %04x cyl %d hds %d sec %d ssiz %d capacity %d\r\n", + scsi_type[type].name, chsa, scsi_type[type].cyl, scsi_type[type].nhds, + scsi_type[type].spt, ssize, uptr->capac); /* disk capacity */ + + /* see if -i or -n specified on attach command */ + if ((sim_switches & SWMASK('N')) || (sim_switches & SWMASK('I'))) { + goto fmt; /* user wants new disk */ + } + + /* seek to end of disk */ + if ((sim_fseek(uptr->fileref, 0, SEEK_END)) != 0) { + sim_debug(DEBUG_CMD, dptr, "SCSI Disk attach SEEK end failed\n"); + printf( "SCSI Disk attach SEEK end failed\r\n"); + goto fmt; /* not setup, go format */ + } + + s = ftell(uptr->fileref); /* get current file position */ + if (s == 0) { + sim_debug(DEBUG_CMD, dptr, "SCSI Disk attach ftell failed s=%06d\n", s); + printf("SCSI Disk attach ftell failed s=%06d\r\n", s); + goto fmt; /* not setup, go format */ + } + sim_debug(DEBUG_CMD, dptr, "SCSI Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type)); + printf("SCSI Disk attach ftell value s=%06d b=%06d CAP %06d\r\n", s/ssize, s, CAP(type)); + + if (((int)s/(int)ssize) < ((int)CAP(type))) { /* full sized disk? */ + j = (CAP(type) - (s/ssize)); /* get # sectors to write */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Disk attach for MPX 1.X needs %04d more sectors added to disk\n", j); + printf("SSFI Disk attach for MPX 1.X needs %04d more sectors added to disk\r\n", j); + /* must be MPX 1.X disk, extend to MPX 3.X size */ + /* write sectors of zero to end of disk to fill it out */ + for (i=0; ifileref) != ssize)) { + sim_debug(DEBUG_CMD, dptr, "SCSI Disk attach fread ret = %04d\n", r); + printf("SCSI Disk attach fread ret = %04d\r\n", r); + goto fmt; /* not setup, go format */ + } + } + s = ftell(uptr->fileref); /* get current file position */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\n", s/ssize, s); + printf("SCSI Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\r\n", s/ssize, s); + } + + /* seek last sector of disk */ + if ((sim_fseek(uptr->fileref, (CAP(type)-1)*ssize, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, "SCSI Disk attach SEEK last sector failed\n"); + printf("SCSI Disk attach SEEK last sector failed\r\n"); + goto fmt; + } + + /* see if there is disk size-1 in last sector of disk, if not add it */ + if ((r = sim_fread(buff, sizeof(uint8), ssize, uptr->fileref) != ssize)) { + sim_debug(DEBUG_CMD, dptr, "SCSI Disk format fread error = %04d\n", r); + printf("SCSI Disk format fread error = %04d\r\n", r); +add_size: + if (ssize == 768) { + /* assume we have MPX 1x, and go on */ + /* write dmap data to last sector on disk for mpx 1.x */ + if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Error on last sector seek to sect %06d offset %06d bytes\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + printf("SCSI Error on last sector seek to sect %06d offset %06d bytes\r\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + goto fmt; + } + if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) { + sim_debug(DEBUG_CMD, dptr, + "SCSI Error writing DMAP to sect %06x offset %06d bytes\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + printf("SCSI Error writing DMAP to sect %06x offset %06d bytes\r\n", + (CAP(type)-1), (CAP(type)-1)*ssize); + goto fmt; + } + + /* seek last sector of disk */ + if ((sim_fseek(uptr->fileref, (CAP(type))*ssize, SEEK_SET)) != 0) { + sim_debug(DEBUG_CMD, dptr, "SCSI Disk attach SEEK last sector failed\n"); + printf( "SCSI Disk attach SEEK last sector failed\r\n"); + goto fmt; + } + s = ftell(uptr->fileref); /* get current file position */ + sim_debug(DEBUG_CMD, dptr, + "SCSI Disk attach MPX file extended & sized secs %06d bytes %06d\n", s/ssize, s); + printf("SCSI Disk attach MPX file extended & sized secs %06d bytes %06d\r\n", s/ssize, s); + goto ldone; + } else { + /* error if UTX */ + detach_unit(uptr); /* if error, abort */ + return SCPE_FMT; /* error */ + } + } else { + /* if not disk size, go add it in for MPX, error if UTX */ + if ((buff[0] | buff[1] | buff[2] | buff[3]) == 0) { + sim_debug(DEBUG_CMD, dptr, + "SCSI Disk format0 buf0 %02x buf1 %02x buf2 %02x buf3 %02x\n", + buff[0], buff[1], buff[2], buff[3]); + goto add_size; + } + } + + /* the last sector is used by UTX for a ZMAP, so if there we are good to go */ + info = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3]; + good = 0xf0000000 | (CAP(type)-1); + /* check for 0xf0ssssss where ssssss is disk size-1 in sectors */ + if ((info != good) && (info != zmap)) { + sim_debug(DEBUG_CMD, dptr, + "SCSI Disk format error buf0 %02x buf1 %02x buf2 %02x buf3 %02x\n", + buff[0], buff[1], buff[2], buff[3]); + printf("SCSI Disk format error buf0 %02x buf1 %02x buf2 %02x buf3 %02x\r\n", + buff[0], buff[1], buff[2], buff[3]); +fmt: + /* format the drive */ + if (scsi_format(uptr)) { + detach_unit(uptr); /* if no space, error */ + return SCPE_FMT; /* error */ + } + } +ldone: + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + detach_unit(uptr); /* if no space, error */ + return SCPE_FMT; /* error */ + } + + /* start out at sector 0 */ + uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */ + + sim_debug(DEBUG_CMD, dptr, + "SCSI Attach %s %04x cyl %d hds %d spt %d spc %d cap sec %d cap bytes %d\n", + scsi_type[type].name, chsa, CYL(type), HDS(type), SPT(type), SPC(type), + CAP(type), CAPB(type)); + + printf("SCSI Attach %s %04x cyl %d hds %d spt %d spc %d cap sec %d cap bytes %d\r\n", + scsi_type[type].name, chsa, CYL(type), HDS(type), SPT(type), SPC(type), + CAP(type), CAPB(type)); + + sim_debug(DEBUG_CMD, dptr, "SCSI File %s at chsa %04x attached to %s is ready\n", + file, chsa, scsi_type[type].name); + printf("SCSI File %s at chsa %04x attached to %s is ready\r\n", + file, chsa, scsi_type[type].name); + + /* check for valid configured disk */ + /* must have valid DIB and Channel Program pointer */ + dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */ + if ((dib_unit[chsa] == NULL) || (dibp == NULL) || (dibp->chan_prg == NULL)) { + sim_debug(DEBUG_CMD, dptr, + "ERROR===ERROR\nSCSI device %s not configured on system, aborting\n", + dptr->name); + printf("ERROR===ERROR\nSCSI device %s not configured on system, aborting\n", + dptr->name); + detach_unit(uptr); /* detach if error */ + return SCPE_UNATT; /* error */ + } + set_devattn(chsa, SNS_DEVEND); + return SCPE_OK; +} + +/* detach a disk device */ +t_stat scsi_detach(UNIT *uptr) { + uptr->SNS = 0; /* clear sense data */ + uptr->CMD &= LMASK; /* no cmd and flags */ + return detach_unit(uptr); /* tell simh we are done with disk */ +} + +/* Handle haltio transfers for disk */ +t_stat scsi_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->CMD); + DEVICE *dptr = get_dev(uptr); + int cmd = uptr->CMD & DSK_CMDMSK; + CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + +// sim_debug(DEBUG_EXP, dptr, + sim_debug(DEBUG_DETAIL, dptr, + "scsi_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any input command */ + /* UTX wants SLI bit, but no unit exception */ + /* status must not have an error bit set */ + /* otherwise, UTX will panic with "bad status" */ + if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_EXP, dptr, + "scsi_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", + chsa, cmd, chp->ccw_count); + sim_cancel(uptr); /* clear the input timer */ + } else { + sim_debug(DEBUG_DETAIL, dptr, + "scsi_haltio HIO I/O not busy chsa %04x cmd = %02x\n", chsa, cmd); + } + /* stop any I/O and post status and return error status */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* stop any chaining */ + uptr->CMD &= LMASK; /* no cmd and flags */ + uptr->SNS &= ~MASK24; /* clear all but old mode data */ + sim_debug(DEBUG_EXP, dptr, + "scsi_haltio HIO I/O stop chsa %04x cmd = %02x CHS %08x STAR %08x\n", + chsa, cmd, uptr->CHS, uptr->STAR); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ +// chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force end */ + return SCPE_IOERR; +} + +/* boot from the specified disk unit */ +t_stat scsi_boot(int32 unit_num, DEVICE *dptr) { + UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */ + + sim_debug(DEBUG_CMD, dptr, "SCSI Disk Boot dev/unit %04x\n", GET_UADDR(uptr->CMD)); + + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nSCSI Disk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + + if ((uptr->flags & UNIT_ATT) == 0) { + sim_debug(DEBUG_EXP, dptr, "SCSI Disk Boot attach error dev/unit %04x\n", + GET_UADDR(uptr->CMD)); + printf("SCSI Disk Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + return SCPE_UNATT; /* attached? */ + } + + /* seek to sector 0 */ + if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ + printf("SCSI Disk Boot Error on seek to 0\n"); + } + + SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ + SPAD[0xf8] = 0xF000; /* show as F class device */ + return chan_boot(GET_UADDR(uptr->CMD), dptr); /* boot the ch/sa */ +} + +/* Disk option setting commands */ +t_stat scsi_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int i; + + if (cptr == NULL) /* any disk name input? */ + return SCPE_ARG; /* arg error */ + if (uptr == NULL) /* valid unit? */ + return SCPE_IERR; /* no, error */ + if (uptr->flags & UNIT_ATT) /* is unit attached? */ + return SCPE_ALATT; /* no, error */ + + /* now loop through the units and find named disk */ + for (i = 0; scsi_type[i].name != 0; i++) { + if (strcmp(scsi_type[i].name, cptr) == 0) { + uptr->flags &= ~UNIT_TYPE; /* clear the old UNIT type */ + uptr->flags |= SET_TYPE(i); /* set the new type */ + /* set capacity of disk in sectors */ + uptr->capac = CAP(i); + return SCPE_OK; + } + } + return SCPE_ARG; +} + +t_stat scsi_get_type(FILE * st, UNIT *uptr, int32 v, CONST void *desc) +{ + if (uptr == NULL) + return SCPE_IERR; + fputs("TYPE=", st); + fputs(scsi_type[GET_TYPE(uptr->flags)].name, st); + return SCPE_OK; +} + +/* help information for disk */ +t_stat scsi_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, + const char *cptr) +{ + int i; + fprintf (st, "SEL-32 MFP SCSI Bus Disk Controller\r\n"); + fprintf (st, "Use:\r\n"); + fprintf (st, " sim> SET %sn TYPE=type\r\n", dptr->name); + fprintf (st, "Type can be: "); + for (i = 0; scsi_type[i].name != 0; i++) { + fprintf(st, "%s", scsi_type[i].name); + if (scsi_type[i+1].name != 0) + fprintf(st, ", "); + } + fprintf (st, ".\nEach drive has the following storage capacity:\r\n"); + for (i = 0; scsi_type[i].name != 0; i++) { + int32 size = CAPB(i); /* disk capacity in bytes */ + size /= 1024; /* make KB */ + size = (10 * size) / 1024; /* size in MB * 10 */ + fprintf(st, " %-8s %4d.%1d MB cyl %3d hds %3d sec %3d blk %3d\r\n", + scsi_type[i].name, size/10, size%10, CYL(i), HDS(i), SPT(i), SSB(i)); + } + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + return SCPE_OK; +} + +const char *scsi_description (DEVICE *dptr) +{ + return "SEL-32 MFP SCSI Disk Controller"; +} + +#endif diff --git a/SEL32/sel32_sys.c b/SEL32/sel32_sys.c new file mode 100644 index 00000000..66d9c801 --- /dev/null +++ b/SEL32/sel32_sys.c @@ -0,0 +1,1722 @@ +/* sel32_sys.c: SEL-32 Gould Concept/32 (orignal SEL-32) Simulator system interface. + + Copyright (c) 2018-2022, James C. Bevier + Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers + + 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 + JAMES C. BEVIER 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 "sel32_defs.h" +#include + +extern REG cpu_reg[]; +extern uint32 M[MAXMEMSIZE]; +extern uint32 SPAD[]; +extern uint32 PSD[]; +char *dump_mem(uint32 mp, int cnt); +char *dump_buf(uint8 *mp, int32 off, int cnt); + +/* SCP data structures and interface routines + +The interface between the simulator control package (SCP) and the +simulator consists of the following routines and data structures + +sim_name simulator name string +sim_devices[] array of pointers to simulated devices +sim_PC pointer to saved PC register descriptor +sim_interval simulator interval to next event (in sel32_cpu.c) +sim_stop_messages[] array of pointers to stop messages +sim_instr() instruction execution routine (in sel32_cpu.c) +sim_load() binary loader routine +sim_emax maximum number of words for examine + +In addition, the simulator must supply routines to print and parse +architecture specific formats + +fprint_sym print symbolic output +fparse_sym parse symbolic input +*/ + +char sim_name[] = "SEL-32"; /* our simulator name */ +REG *sim_PC = &cpu_reg[0]; + +int32 sim_emax = 4; /* maximum number of instructions/words to examine */ + +DEVICE *sim_devices[] = { + &cpu_dev, +#ifdef NUM_DEVS_IOP + &iop_dev, /* IOP channel controller */ +#endif +#ifdef NUM_DEVS_MFP + &mfp_dev, /* MFP channel controller */ +#endif +#ifdef NUM_DEVS_RTOM + &rtc_dev, + &itm_dev, +#endif +#ifdef NUM_DEVS_CON + &con_dev, +#endif +#ifdef NUM_DEVS_CDR + &cdr_dev, +#endif +#ifdef NUM_DEVS_CDP + &cdp_dev, +#endif +#ifdef NUM_DEVS_LPR + &lpr_dev, +#endif +#ifdef NUM_DEVS_MT + &mta_dev, +#if NUM_DEVS_MT > 1 + &mtb_dev, +#endif +#endif +#ifdef NUM_DEVS_DISK + &dda_dev, +#if NUM_DEVS_DISK > 1 + &ddb_dev, +#endif +#endif +#ifdef NUM_DEVS_SCFI + &sda_dev, +#if NUM_DEVS_SCFI > 1 + &sdb_dev, +#endif +#endif +#ifdef NUM_DEVS_HSDP + &dpa_dev, +#if NUM_DEVS_HSDP > 1 + &dpb_dev, +#endif +#endif +#ifdef NUM_DEVS_SCSI + &sba_dev, +#if NUM_DEVS_SCSI > 1 + &sbb_dev, +#endif +#endif +#ifdef NUM_DEVS_ETHER + &ec_dev, +#endif +#ifdef NUM_DEVS_COM + &coml_dev, + &com_dev, +#endif + NULL }; + +/* Simulator debug controls */ +DEBTAB dev_debug[] = { + {"CMD", DEBUG_CMD, "Show command execution to devices"}, + {"DATA", DEBUG_DATA, "Show data transfers"}, + {"DETAIL", DEBUG_DETAIL, "Show details about device"}, + {"EXP", DEBUG_EXP, "Show exception information"}, + {"INST", DEBUG_INST, "Show instruction execution"}, + {"XIO", DEBUG_XIO, "Show XIO I/O instructions"}, + {"IRQ", DEBUG_IRQ, "Show interrupt requests"}, + {"TRAP", DEBUG_TRAP, "Show trap requests"}, + {0, 0} +}; + +const char *sim_stop_messages[SCPE_BASE] = { + "Unknown error", + "IO device not ready", + "HALT instruction", + "Breakpoint", + "Unknown Opcode", + "Invalid instruction", + "Invalid I/O operation", + "Nested indirects exceed limit", + "I/O Check opcode", + "Memory management trap during trap", +}; + +#define PRINTABLE(x) ((x < 32) || (x > 126)) ? '.' : x + +static char line[257]; +/* function to dump SEL32 memory up to 16 bytes with side by side ascii values */ +char *dump_mem(uint32 mp, int cnt) +{ + char buff[257]; + uint32 ma = mp; /* save memory address */ + char *cp = &line[0]; /* output buffer */ + int cc=0, ch, bp=0, bl=cnt; + + if (cnt > 16) + bl = 16; /* stop at 16 chars */ + + while (bp < bl) { + if (!bp) { + cc = sprintf(cp, " %06x : ", ma); /* output location address */ + cp += cc; /* next print location */ + } + ch = RMB(ma) & 0xff; /* get a char from memory */ + ma++; /* next loc */ + cc += sprintf(cp, "%02x", ch); /* print out current char */ + cp += 2; /* next print location */ + buff[bp++] = PRINTABLE(ch); /* get printable version of char */ + if (!(bp % 4)) { /* word boundry yet? */ + cc += sprintf(cp, " "); /* space between words */ + cp += 1; /* next print location */ + } + } + + while (bp < 16) { + cc += sprintf(cp, " "); /* print out one space */ + cp += 1; /* next print location */ + buff[bp++] = 0x20; /* blank char buffer */ + if (!(bp % 4)) { + cc += sprintf(cp, " "); /* space between words */ + cp += 1; /* next print location */ + } + } + buff[bp] = 0; /* terminate line */ + cc += sprintf(cp, "|%s|\n", buff); /* print out ascii text */ + return (line); /* return pointer to caller */ +} + +/* function to dump caller buffer upto 16 bytes with side by side ascii values */ +/* off is offset in buffer to start */ +char *dump_buf(uint8 *mp, int32 off, int cnt) +{ + char buff[257]; + uint32 ma = off; /* save memory address */ + char *cp = &line[0]; /* output buffer */ + int cc=0, ch, bp=0, bl=cnt; + + if (cnt > 16) + bl = 16; /* stop at 16 chars */ + + while (bp < bl) { + if (!bp) { + cc = sprintf(cp, " %06x : ", ma); /* output location offset */ + cp += cc; /* next print location */ + } + ch = mp[ma++] & 0xff; /* get a char from memory */ + cc += sprintf(cp, "%02x", ch); /* print out current char */ + cp += 2; /* next print location */ + buff[bp++] = PRINTABLE(ch); /* get printable version of char */ + if (!(bp % 4)) { /* word boundry yet? */ + cc += sprintf(cp, " "); /* space between words */ + cp += 1; /* next print location */ + } + } + + while (bp < 16) { + cc += sprintf(cp, " "); /* print out one space */ + cp += 1; /* next print location */ + buff[bp++] = 0x20; /* blank char buffer */ + if (!(bp % 4)) { + cc += sprintf(cp, " "); /* space between words */ + cp += 1; /* next print location */ + } + } + buff[bp] = 0; /* terminate line */ + cc += sprintf(cp, "|%s|\n", buff); /* print out ascii text */ + return (line); /* return pointer to caller */ +} + + + +/* + * get_word - function to load a 32 bit word from the input file + * return 1 - OK + * return 0 - error or eof + */ +int get_word(FILE *fileref, uint32 *word) +{ + unsigned char cbuf[4]; + + /* read in the 4 chars */ + if (sim_fread(cbuf, 1, 4, fileref) != 4) + return 1; /* read error or eof */ + /* byte swap while reading data */ + *word = ((cbuf[0]) << 24) | ((cbuf[1]) << 16) | + ((cbuf[2]) << 8) | ((cbuf[3])); + return 0; /* all OK */ +} + +#ifdef NO_TAP_FOR_NOW +/* + * get_halfword - function to load a 16 bit halfword from the input file + * return 1 - OK + * return 0 - error or eof + */ +int get_halfword(FILE *fileref, uint16 *word) +{ + unsigned char cbuf[2]; + + /* read in the 2 chars */ + if (sim_fread(cbuf, 1, 2, fileref) != 2) + return 1; /* read error or eof */ + /* byte swap while reading data */ + *word = ((uint16)(cbuf[0]) << 8) | ((uint16)(cbuf[1])); + return 0; /* all OK */ +} +#endif + +/* load a binary file into memory starting at loc 0 */ +/* return SCPE_OK on load complete */ +t_stat load_mem (FILE *fileref) +{ + uint32 data; + uint32 ma = 0; /* start at mem add 0 */ + + /* read the file until the end */ + for ( ;; ) { + if (get_word(fileref, &data)) /* get 32 bits of data */ + return SCPE_OK; /* load is complete, return */ + M[ma++] = data; /* put data in memory */ + } + return SCPE_OK; /* never here */ +} + +#ifdef NO_TAP_FOR_NOW +/* load tap formated tape into memory */ +/* return SCPE_OK on load complete */ +t_stat load_tap (FILE *fileref) +{ + uint32 bdata, edata; + uint16 hdata; + uint32 ma = 0; /* start loading at loc 0 */ + int32 wc; + + for ( ;; ) { /* loop until EOF read */ + /* look for record byte count or zero for EOF */ + if (get_word(fileref, &bdata)) /* read 4 bytes of data */ + return SCPE_FMT; /* must be error, exit */ + wc = (int32)(bdata); /* byte count in tape record */ + wc = (wc + 1)/2; /* change byte count into hw count */ + if (wc == 0) + return SCPE_OK; /* eof found, return */ + /* copy data to memory in 16 bit halfwords */ + while (wc-- != 0) { + if (get_halfword(fileref, &hdata)) /* get 16 bits of data */ + return SCPE_FMT; /* must be error, exit */ + ((uint16*)M)[ma++] = hdata; /* put the hw into memory */ + } + /* look only for record byte count */ + if (get_word(fileref, &edata)) /* read 4 bytes of data */ + return SCPE_FMT; /* must be error, exit */ + /* the before and after byte count must be equal */ + if (bdata != edata) + return SCPE_FMT; /* must be error, exit */ + } + return SCPE_OK; /* never here */ +} +#endif + +/* ICL formats */ +/*********************************************** + * + * *DEVXX=FCILCASA (,N) + * + * *DEV defines a controller definition entry + * XX hex address that will be used by I/O instructions to address controller + * = required delimiter for following 8 hex characters + * F flag used for I/O emulation by CPU, not used but must be zero. + * C defines the class of controller: + * 0 = Line Printer + * 1 = Card Reader + * 2 = Teletype + * 3 = Interval Timer + * 4 = Panel + * 5-D Unassigned + * E = All Others + * F = Extended I/O + * IL Controller interrupt priority level of Service Interrupt (0x14 - 0x23) + * CA Controller address defined by hardware switches on controller + * SA Lowest controller device subaddress. Usually zero when only 1 device configured + * The subaddress field (SA) must reflect the following for TLC controller: + * 00 = Card Reader + * 01 = Teletype + * 02 = Line Printer + * () denotes optional parameter + * ,NN 2 digit hexx number of devices configured on the controller` + * + *********************************************** + * + * *INTXX=RS + * *INT defines interrupt definition entry + * XX Hex interrupt priority level to be defined + * = required delimiter for following 2 hex characters + * R Hex RTOM board number to which the interrupt XX is assigned + * S 1's complement of the hex subaddress of the RTOM board + * assigned to the interrupt XX + * + * RTOM physical controller address 0x79 is RTOM board number 1, RTOM + * address 0x7A is board number 2, etc. + * Real-Time Clock is connected tp subaddress 6 on RTOM board + * Interval Timer is connected to subaddress 4 on RTOM board + * RTOM physical address must be 0x79 or above to be able to + * support up to seven RTOM boards for maximum configuration + * of 112 interrupt levels (7 x 16). + * + *********************************************** + * + * *END + * *END Defines the last record of the Initial Configuration Load file. + * + *********************************************** +*/ + +/* Example device entry + * *DEV04=0E140100,04 + * The controller is "E" class + * CPU command device address will be 0x04 + * The priority of the Service Interrupt is 0x14 + * The first device has suaddress of 00 and there are 4 devices defined + * There will be four devices defined in SPAD. The I/O commands (CD and TD) + * will address the devices as 0x04, 0x05, 0x06, and 0x07. + * The physical address of the controller is 0x10. + * Assigning SI address of 0x14 means: + * The transfer Interrupt location for priority 0x14 is 0x100. + * The Service Interrupt vector location for priority 0x14 is 0x140. + * The emulation IOCD will be stored at loation 0x700. + * The interrupt control instructions (DI, DI, RI, AI, DAI) will control + * the interrupt of the controller by addressing priority 0x14. + * + * Example interrupt entry (RTOM) + * *INT28=16 + * The interrupt control instructions (DI, EI, RI, AI, DAI) will control + * the interrupt on the RTOM by addressing priority 0x28. + * The RTOM board is 1 + * The subaddress on the board is 0x06 (jumpered locic subaddress is 9) + */ + +/* + * Example ICL file + * *DEV04=0E150400,02 Cartridge disc with two platters + * *DEV08=0E160800,04 Moving head disc + * *DEV10=0E181000,04 9-Track magnetic tape + * *DEV20=0E1A2000,10 GPMC with 16 terminals + * *DEV60=0E1E6000,08 ADS + * *DEV78=01207800 Primary card reader + * *DEV7A=00217802 Primary line printer + * *DEV7E=02237801 Primary Teletype + * *INT00=1F Power fail/Auto restart + * *INT01=1E System Overide + * *INT12=1D Memory parity + * *INT13=1C Console Interrupt + * *INT24=1B Nonpresent memory + * *INT25=1A Undefined instruction trap + * *INT26=19 Privlege violation + * *INT27=18 Call Monitor + * *INT28=16 Real-time clock + * *INT29=17 Arithmetic exception + * *INT2A=15 External interrupt + * *INT2B=14 External interrupt + * *INT2C=13 External interrupt + * *INT2D=12 External interrupt + * *END + */ + +/* process two hex input characters into a number + * pt - input char pointer + * val - word oiunter when number will be saved + * return SCPE_OK for OK + * or SCPE_ARG for arg error (bad number) + */ +t_value get_2hex(char *pt, uint32 *val) +{ + int32 hexval; + uint32 c1 = sim_toupper((uint32)pt[0]); /* first hex char */ + uint32 c2 = sim_toupper((uint32)pt[1]); /* next hex char */ + + if (isdigit(c1)) /* digit */ + hexval = c1 - (uint32)'0'; /* get value */ + else + if (isxdigit(c1)) /* hex digit */ + hexval = c1 - (uint32)'A' + 10; /* get hex value */ + else + return SCPE_ARG; /* oops, error */ + hexval <<= 4; /* move to upper nibble */ + if (isdigit(c2)) /* digit */ + hexval += c2 - (uint32)'0'; /* get value */ + else + if (isxdigit(c2)) /* hex digit */ + hexval += c2 - (uint32)'A' + 10; /* get hex value */ + else + return SCPE_ARG; /* oops, error */ + *val = hexval; /* return value to caller */ + return SCPE_OK; /* all OK */ +} + +/* load an ICL file and configure SPAD interupt and device entries */ +/* SPAD keyword will not be set and will be set when MPX or UTX is loaded */ +/* return SCPE_OK on load complete */ +t_stat load_icl(FILE *fileref) +{ + char *cp; /* work pointer in buf[] */ + uint32 sa; /* spad address */ + uint32 dev; /* device entry */ + uint32 intr; /* interrupt entry */ + uint32 data; /* entry data */ + uint32 cls; /* device class */ + uint32 ivl; /* Interrupt Vector Location */ + uint32 i; /* just a tmp */ + char buf[120]; /* input buffer */ + + /* read file input records until the end */ + while (fgets(&buf[0], 120, fileref) != 0) { + /* skip any white spaces */ + for(cp = &buf[0]; *cp == ' ' || *cp == '\t'; cp++); + if (*cp++ != '*') + continue; /* if line does not start with *, ignore */ + if(sim_strncasecmp(cp, "END", 3) == 0) { + return SCPE_OK; /* we are done */ + } + else + if(sim_strncasecmp(cp, "DEV", 3) == 0) { + /* process device entry */ + /* + |----+----+----+----+----+----+----+----| + |Flgs|CLS |0|Int Lev|0|Phy Adr|Sub Addr | + |----+----+----+----+----+----+----+----| + */ + for(cp += 3; *cp == ' ' || *cp == '\t'; cp++); /* skip white spaces */ + if (get_2hex(cp, &dev) != SCPE_OK) /* get the device address */ + return SCPE_ARG; /* unknown input, argument error */ + if (dev > 0x7f) /* devices are 0-7f (0-127) */ + return SCPE_ARG; /* argument error */ + sa = dev + 0x00; /* device entry spad address is dev# + 0x00 */ + cp += 2; /* skip the 2 processed chars */ + if (*cp++ != '=') /* must have = sign */ + return SCPE_ARG; /* unknown input, argument error */ + if (get_2hex(cp, &cls) != SCPE_OK) /* get unused '0" and class */ + return SCPE_ARG; /* unknown input, argument error */ + cp += 2; /* skip the 2 processed chars */ + if (get_2hex(cp, &intr) != SCPE_OK) /* get the interrupt level value */ + return SCPE_ARG; /* unknown input, argument error */ + if (intr > 0x6f) /* ints are 0-6f (0-111) */ + return SCPE_ARG; /* argument error */ + /* put class and 1's intr in place */ + dev = ((~intr & 0x7f) << 16) | ((cls & 0x0f) << 24); + cp += 2; /* skip the 2 processed chars */ + if (get_2hex(cp, &data) != SCPE_OK) /* get the selbus physical address */ + return SCPE_ARG; /* unknown input, argument error */ + if (data > 0x7f) /* address is 0-7f (0-127) */ + return SCPE_ARG; /* argument error */ + dev |= (data & 0x7f) << 8; /* insert the physical address */ + cp += 2; /* skip the 2 processed chars */ + if (get_2hex(cp, &data) != SCPE_OK) /* get the starting sub address 0-ff (255) */ + return SCPE_ARG; /* unknown input, argument error */ + if (data > 0x7f) /* sub address is 0-ff (0-256) */ + return SCPE_ARG; /* argument error */ + if ((cls & 0xf) != 0xf) /* sub addr must be zero for class F */ + dev |= (data & 0xff); /* insert the starting sub address for non f class */ + SPAD[sa] = dev; /* put the first device entry into the spad */ + /* see if there is an optional device count for class 'E' I/O */ + if ((cls & 0xf) == 0xe) { + cp += 2; /* skip the 2 processed chars */ + if (*cp++ == ',') { /* must have comma if optional parameters */ + /* check for optional sub addr cnt */ + if (get_2hex(cp, &data) != SCPE_OK) /* get the count */ + return SCPE_ARG; /* unknown input, argument error */ + if (data > 0x10) /* sub address is max of 16 */ + return SCPE_ARG; /* argument error */ + for (i=0; i 0x6f) /* ints are 0-6f (0-111) */ + return SCPE_ARG; /* argument error */ + sa = intr + 0x80; /* interrupt entry spad address is int# + 0x80 */ +/* TODO call function here to create 32/7x IVL location for interrupt */ +/* if (CPU_MODEL < MODEL_27) get_IVL(intr, &ivl); */ + ivl = (intr << 2) + 0x100; /* default IVL base is 0x100 for Concept machines */ + cp += 2; /* skip the 2 processed chars */ + if (*cp++ != '=') /* must have = sign */ + return SCPE_ARG; /* unknown input, argument error */ + if (get_2hex(cp, &data) != SCPE_OK) + return SCPE_ARG; /* unknown input, argument error */ + /* first digit is 3 ls bits of RTOM addr 0x79 is 001 */ + intr = 0x00800000 | ((data & 0x70) << 16); /* put the RTOM 3 LSBs into entry */ + /* second digit is subaddress on RTOM board for interrupt connection, ~6 = 9 */ + intr |= (data & 0xf) << 16; /* put in 1's comp of RTOM subaddress */ + /* add in the correct IVL for 32/7x or concelt machines */ + intr |= ivl; /* set the IVL location */ + SPAD[sa] = intr; /* put the interrupt entry into the spad */ + } + else + return SCPE_ARG; /* unknown input, argument error */ + } + return SCPE_OK; /* file done */ +} + + +/* Load a file image into memory. */ +/* file.mem files are binary files created with the makecode utility */ +#ifdef NO_TAP_FOR_NOW +/* file.tap files are TAP formatted binary files created from tape images */ +#endif +/* data is raw binary memory data and is loaded starting at loc 0 */ + +#define FMT_NONE 0 +#define FMT_MEM 1 +#ifdef NO_TAP_FOR_NOW +#define FMT_TAP 2 +#endif +#define FMT_ICL 3 +t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) +{ + int32 fmt; + + fmt = FMT_NONE; /* no format */ + /* match the extension to .mem for this file */ + if (match_ext(fnam, "MEM")) + fmt = FMT_MEM; /* we have binary format */ + else +#ifdef NO_TAP_FOR_NOW + if (match_ext(fnam, "TAP")) + fmt = FMT_TAP; /* we have tap tape format */ + else +#endif + /* match the extension to .icl for this file */ + if (match_ext(fnam, "ICL")) + fmt = FMT_ICL; /* we have initial configuration load (ICL) format */ + else + return SCPE_FMT; /* format error */ + + switch (fmt) { + + case FMT_MEM: /* binary memory image */ + return load_mem(fileref); + +#ifdef NO_TAP_FOR_NOW + case FMT_TAP: /* tape file image */ + return load_tap(fileref); +#endif + + case FMT_ICL: /* icl file image */ + return load_icl(fileref); + +#ifdef NO_TAP_FOR_NOW + case FMT_NONE: /* nothing */ +#endif + default: + break; + } + return SCPE_FMT; /* format error */ +} + +/* Symbol tables */ + +/* + * The SEL 32 supports the following instruction formats. + * + * TYPE Format Normal Base Mode + * A ADR d,[*]o,x d,o[(b)],x FC = extra + * B BRA [*]o,x o[(b)],x + * C IMM d,o d,o + * D BIT d,[*]o d,o[(b)] + * E ADR [*]o,x o[(b)],x FC = extra + * HALFWORD + * F REG s,d s,d Half Word + * G RG1 s s + * H HLF + * I SHF d,v d,v + * K RBT d,b d,b + * L EXR s s + * M IOP n,b n,b + * N SVC n,b n,b + */ + +#define TYPE_A 0 +#define TYPE_B 1 +#define TYPE_C 2 +#define TYPE_D 3 +#define TYPE_E 4 +#define TYPE_F 5 +#define TYPE_G 6 +#define TYPE_H 7 +#define TYPE_I 8 +#define TYPE_K 9 +#define TYPE_L 10 +#define TYPE_M 11 +#define TYPE_N 12 +#define H 0x10 /* halfword instruction */ +/* all instruction unless specified as base/nobase only will be either */ +#define B 0x20 /* base register mode only */ +#define N 0x40 /* non base register mode only */ +#define X 0x80 /* 32/55 or 32/75 only */ + +typedef struct _opcode { + uint16 opbase; + uint16 mask; + uint8 type; + const char *name; +} t_opcode; + +t_opcode optab[] = { + { 0x0000, 0xFFFF, H|TYPE_H, "HALT", }, /* Halt # * */ + { 0x0001, 0xFFFF, H|TYPE_H, "WAIT", }, /* Wait # * */ + { 0x0002, 0xFFFF, H|TYPE_H, "NOP", }, /* Nop # */ + { 0x0003, 0xFC0F, H|TYPE_G, "LCS", }, /* Load Control Switches */ + { 0x0004, 0xFC0F, H|TYPE_G, "ES", }, /* Extend Sign # */ + { 0x0005, 0xFC0F, H|TYPE_G, "RND", }, /* Round Register # */ + { 0x0006, 0xFFFF, H|TYPE_H, "BEI", }, /* Block External Interrupts # */ + { 0x0007, 0xFFFF, H|TYPE_H, "UEI", }, /* Unblock External Interrupts # */ + { 0x0008, 0xFFFF, H|TYPE_H, "EAE", }, /* Enable Arithmetic Exception Trap # */ + { 0x0009, 0xFC0F, H|TYPE_G, "RDSTS", }, /* Read CPU Status Word * */ + { 0x000A, 0xFFFF, H|TYPE_H, "SIPU", }, /* Signal IPU # */ + { 0x000B, 0xFC0F, H|TYPE_F, "RWCS", }, /* Read Writable Control Store # */ + { 0x000C, 0xFC0F, H|TYPE_F, "WWCS", }, /* Write Writable Control Store # */ + { 0x000D, 0xFFFF, N|H|TYPE_H, "SEA", }, /* Set Extended Addressing # NBR Only */ + { 0x000E, 0xFFFF, H|TYPE_H, "DAE", }, /* Disable Arithmetic Exception Trap # */ + { 0x000F, 0xFFFF, N|H|TYPE_H, "CEA", }, /* Clear Extended Addressing # NBR Only */ + { 0x0400, 0xFC0F, H|TYPE_F, "ANR", }, /* And Register # */ + { 0x0407, 0xFC0F, H|TYPE_G, "SMC", }, /* Shared Memory Control # */ + { 0x040A, 0xFC0F, H|TYPE_G, "CMC", }, /* Cache Memory Control # */ + { 0x040B, 0xFC0F, H|TYPE_G, "RPSWT", }, /* Read Processor Status Word Two # */ + { 0x0800, 0xFC0F, H|TYPE_F, "ORR", }, /* Or Register # */ + { 0x0808, 0xFC0F, H|TYPE_F, "ORRM", }, /* Or Register Masked # */ + { 0x0C00, 0xFC0F, H|TYPE_F, "EOR", }, /* Exclusive Or Register # */ + { 0x0C08, 0xFC0F, H|TYPE_F, "EORM", }, /* Exclusive Or Register Masked # */ + { 0x1000, 0xFC0F, H|TYPE_F, "CAR", }, /* Compare Arithmetic Register # */ + { 0x1008, 0xFC0F, B|H|TYPE_F, "SACZ", }, /* Shift and Count Zeros # BR */ + { 0x1400, 0xFC0F, H|TYPE_F, "CMR", }, /* Compare masked with register */ + { 0x1800, 0xFC0C, H|TYPE_K, "SBR", }, /* Set Bit in Register # */ + { 0x1804, 0xFC0C, B|H|TYPE_K, "ZBR", }, /* Zero Bit In register # BR */ + { 0x1808, 0xFC0C, B|H|TYPE_K, "ABR", }, /* Add Bit In Register # BR */ + { 0x180C, 0xFC0C, B|H|TYPE_K, "TBR", }, /* Test Bit in Register # BR */ + { 0x1C00, 0xFC0C, N|H|TYPE_K, "ZBR", }, /* Zero Bit in Register # NBR */ /* CON SRABR */ + { 0x1C00, 0xFC60, B|H|TYPE_I, "SRABR", }, /* Shift Right Arithmetic # BR */ /* CON ZBM */ + { 0x1C20, 0xFC60, B|H|TYPE_I, "SRLBR", }, /* Shift Right Logical # BR */ + { 0x1C40, 0xFC60, B|H|TYPE_I, "SLABR", }, /* Shift Left Arithmetic # BR */ + { 0x1C60, 0xFC60, B|H|TYPE_I, "SLLBR", }, /* Shift Left Logical # BR */ + { 0x2000, 0xFC0C, N|H|TYPE_K, "ABR", }, /* Add Bit in Register # NBR */ /* CON SRADBR */ + { 0x2000, 0xFC60, B|H|TYPE_I, "SRADBR", }, /* Shift Right Arithmetic Double # BR */ /* CON ABR */ + { 0x2020, 0xFC60, B|H|TYPE_I, "SRLDBR", }, /* Shift Left Logical Double # BR */ + { 0x2040, 0xFC60, B|H|TYPE_I, "SLADBR", }, /* Shift Right Arithmetic Double # BR */ + { 0x2060, 0xFC60, B|H|TYPE_I, "SLLDBR", }, /* Shift Left Logical Double # BR */ + { 0x2400, 0xFC0C, N|H|TYPE_K, "TBR", }, /* Test Bit in Register # NBR */ /* CON SRCBR */ + { 0x2400, 0xFC60, B|H|TYPE_I, "SRCBR", }, /* Shift Right Circular # BR */ /* CON TBR */ + { 0x2440, 0xFC60, B|H|TYPE_F, "SLCBR", }, /* Shift Left Circular # BR */ + { 0x2800, 0xFC0F, H|TYPE_G, "TRSW", }, /* Transfer GPR to PSD */ + { 0x2802, 0xFC0F, B|H|TYPE_F, "XCBR", }, /* Exchange Base Registers # BR Only */ + { 0x2804, 0xFC0F, B|H|TYPE_G, "TCCR", }, /* Transfer CC to GPR # BR Only */ + { 0x2805, 0xFC0F, B|H|TYPE_G, "TRCC", }, /* Transfer GPR to CC # BR */ + { 0x2808, 0xFF8F, B|H|TYPE_F, "BSUB", }, /* Branch Subroutine # BR Only */ + { 0x2808, 0xFC0F, B|H|TYPE_F, "CALL", }, /* Procedure Call # BR Only */ + { 0x280C, 0xFC0F, B|H|TYPE_G, "TPCBR", }, /* Transfer Program Counter to Base # BR Only */ + { 0x280E, 0xFC7F, B|H|TYPE_G, "RETURN", }, /* Procedure Return # BR Only */ + { 0x2C00, 0xFC0F, H|TYPE_F, "TRR", }, /* Transfer Register to Register # */ + { 0x2C01, 0xFC0F, B|H|TYPE_F, "TRBR", }, /* Transfer GPR to BR # */ + { 0x2C02, 0xFC0F, B|H|TYPE_F, "TBRR", }, /* Transfer BR to GPR # BR Only */ + { 0x2C03, 0xFC0F, H|TYPE_F, "TRC", }, /* Transfer Register Complement # */ + { 0x2C04, 0xFC0F, H|TYPE_F, "TRN", }, /* Transfer Register Negative # */ + { 0x2C05, 0xFC0F, H|TYPE_F, "XCR", }, /* Exchange Registers # */ + { 0x2C07, 0xFC0F, H|TYPE_G, "LMAP", }, /* Load MAP * */ + { 0x2C08, 0xFC0F, H|TYPE_F, "TRRM", }, /* Transfer Register to Register Masked # */ + { 0x2C09, 0xFC0F, H|TYPE_G, "SETCPU", }, /* Set CPU Mode # * */ + { 0x2C0A, 0xFC0F, H|TYPE_F, "TMAPR", }, /* Transfer MAP to Register # * */ + { 0x2C0B, 0xFC0F, H|TYPE_F, "TRCM", }, /* Transfer Register Complement Masked # */ + { 0x2C0C, 0xFC0F, H|TYPE_F, "TRNM", }, /* Transfer Register Negative Masked # */ + { 0x2C0D, 0xFC0F, H|TYPE_F, "XCRM", }, /* Exchange Registers Masked # */ + { 0x2C0E, 0xFC0F, H|TYPE_F, "TRSC", }, /* Transfer Register to Scratchpad # * */ + { 0x2C0F, 0xFC0F, H|TYPE_F, "TSCR", }, /* Transfer Scratchpad to Register # * */ + { 0x3000, 0xFC0F, X|H|TYPE_F, "CALM", }, /* Call Monitor 32/55 # */ + { 0x3400, 0xFC00, N|TYPE_D, "LA", }, /* Load Address NBR Note! FW instruction */ + { 0x3800, 0xFC0F, H|TYPE_F, "ADR", }, /* Add Register to Register # */ + { 0x3801, 0xFC0F, H|TYPE_F, "ADRFW", }, /* Add Floating Point to Register # */ + { 0x3802, 0xFC0F, B|H|TYPE_F, "MPR", }, /* Multiply Register BR # */ + { 0x3803, 0xFC0F, H|TYPE_F, "SURFW", }, /* Subtract Floating Point Register # */ + { 0x3804, 0xFC0F, H|TYPE_F, "DVRFW", }, /* Divide Floating Point Register # */ + { 0x3805, 0xFC0F, H|TYPE_F, "FIXW", }, /* Fix Floating Point Register # */ + { 0x3806, 0xFC0F, H|TYPE_F, "MPRFW", }, /* Multiply Floating Point Register # */ + { 0x3807, 0xFC0F, H|TYPE_F, "FLTW", }, /* Float Floating Point Register # */ + { 0x3808, 0xFC0F, H|TYPE_F, "ADRM", }, /* Add Register to Register Masked # */ + { 0x3809, 0xFC0F, H|TYPE_F, "ADRFD", }, /* Add Floating Point Register to Register # */ + { 0x380A, 0xFC0F, B|H|TYPE_F, "DVR", }, /* Divide Register by Registier BR # */ + { 0x380B, 0xFC0F, H|TYPE_F, "SURFD", }, /* Subtract Floating Point Double # */ + { 0x380C, 0xFC0F, H|TYPE_F, "DVRFD", }, /* Divide Floating Point Double # */ + { 0x380D, 0xFC0F, H|TYPE_F, "FIXD", }, /* Fix Double Register # */ + { 0x380E, 0xFC0F, H|TYPE_F, "MPRFD", }, /* Multiply Double Register # */ + { 0x380F, 0xFC0F, H|TYPE_F, "FLTD", }, /* Float Double # */ + { 0x3C00, 0xFC0F, H|TYPE_F, "SUR", }, /* Subtract Register to Register # */ + { 0x3C08, 0xFC0F, H|TYPE_F, "SURM", }, /* Subtract Register to Register Masked # */ + { 0x4000, 0xFC0F, N|H|TYPE_F, "MPR", }, /* Multiply Register to Register # NBR */ + { 0x4400, 0xFC0F, N|H|TYPE_F, "DVR", }, /* Divide Register to Register # NBR */ + { 0x5000, 0xFC08, B|TYPE_D, "LABRM", }, /* Load Address BR Mode */ + { 0x5400, 0xFC08, B|TYPE_A, "STWBR", }, /* Store Base Register BR Only */ + { 0x5800, 0xFC08, B|TYPE_A, "SUABR", }, /* Subtract Base Register BR Only */ + { 0x5808, 0xFC08, B|TYPE_D, "LABR", }, /* Load Address Base Register BR Only */ + { 0x5C00, 0xFC08, B|TYPE_A, "LWBR", }, /* Load Base Register BR Only */ + { 0x5C08, 0xFF88, B|TYPE_B, "BSUBM", }, /* Branch Subroutine Memory BR Only */ + { 0x5C08, 0xFC08, B|TYPE_B, "CALLM", }, /* Call Memory BR Only */ + { 0x6000, 0xFC0F, N|H|TYPE_F, "NOR", }, /* Normalize # NBR Only */ + { 0x6400, 0xFC0F, N|H|TYPE_F, "NORD", }, /* Normalize Double # NBR Only */ + { 0x6800, 0xFC0F, N|H|TYPE_F, "SCZ", }, /* Shift and Count Zeros # */ + { 0x6C00, 0xFC40, N|H|TYPE_I, "SRA", }, /* Shift Right Arithmetic # NBR */ + { 0x6C40, 0xFC40, N|H|TYPE_I, "SLA", }, /* Shift Left Arithmetic # NBR */ + { 0x7000, 0xFC40, N|H|TYPE_I, "SRL", }, /* Shift Right Logical # NBR */ + { 0x7040, 0xFC40, N|H|TYPE_I, "SLL", }, /* Shift Left Logical # NBR */ + { 0x7400, 0xFC40, N|H|TYPE_I, "SRC", }, /* Shift Right Circular # NBR */ + { 0x7440, 0xFC40, N|H|TYPE_I, "SLC", }, /* Shift Left Circular # NBR */ + { 0x7800, 0xFC40, N|H|TYPE_I, "SRAD", }, /* Shift Right Arithmetic Double # NBR */ + { 0x7840, 0xFC40, N|H|TYPE_I, "SLAD", }, /* Shift Left Arithmetic Double # NBR */ + { 0x7C00, 0xFC40, N|H|TYPE_I, "SRLD", }, /* Shift Right Logical Double # NBR */ + { 0x7C40, 0xFC40, N|H|TYPE_I, "SLLD", }, /* Shift Left Logical Double # NBR */ + { 0x8000, 0xFC08, TYPE_A, "LEAR", }, /* Load Effective Address Real * */ + { 0x8400, 0xFC00, TYPE_A, "ANM", }, /* And Memory B,H,W,D */ + { 0x8800, 0xFC00, TYPE_A, "ORM", }, /* Or Memory B,H,W,D */ + { 0x8C00, 0xFC00, TYPE_A, "EOM", }, /* Exclusive Or Memory */ + { 0x9000, 0xFC00, TYPE_A, "CAM", }, /* Compare Arithmetic with Memory */ + { 0x9400, 0xFC00, TYPE_A, "CMM", }, /* Compare Masked with Memory */ + { 0x9800, 0xFC00, TYPE_D, "SBM", }, /* Set Bit in Memory */ + { 0x9C00, 0xFC00, TYPE_D, "ZBM", }, /* Zero Bit in Memory */ + { 0xA000, 0xFC00, TYPE_D, "ABM", }, /* Add Bit in Memory */ + { 0xA400, 0xFC00, TYPE_D, "TBM", }, /* Test Bit in Memory */ + { 0xA800, 0xFC00, TYPE_B, "EXM", }, /* Execute Memory */ + { 0xAC00, 0xFC00, TYPE_A, "L", }, /* Load B,H,W,D */ + { 0xB000, 0xFC00, TYPE_A, "LM", }, /* Load Masked B,H,W,D */ + { 0xB400, 0xFC00, TYPE_A, "LN", }, /* Load Negative B,H,W,D */ + { 0xB800, 0xFC00, TYPE_A, "ADM", }, /* Add Memory B,H,W,D */ + { 0xBC00, 0xFC00, TYPE_A, "SUM", }, /* Subtract Memory B,H,W,D */ + { 0xC000, 0xFC00, TYPE_A, "MPM", }, /* Multiply Memory B,H,W,D */ + { 0xC400, 0xFC00, TYPE_A, "DVM", }, /* Divide Memory B,H,W,D */ + { 0xC800, 0xFC0F, TYPE_C, "LI", }, /* Load Immediate */ + { 0xC801, 0xFC0F, TYPE_C, "ADI", }, /* Add Immediate */ + { 0xC802, 0xFC0F, TYPE_C, "SUI", }, /* Subtract Immediate */ + { 0xC803, 0xFC0F, TYPE_C, "MPI", }, /* Multiply Immediate */ + { 0xC804, 0xFC0F, TYPE_C, "DVI", }, /* Divide Immediate */ + { 0xC805, 0xFC0F, TYPE_C, "CI", }, /* Compare Immediate */ + { 0xC806, 0xFC0F, TYPE_N, "SVC", }, /* Supervisor Call */ + { 0xC807, 0xFC0F, TYPE_G, "EXR", }, /* Execute Register/ Right */ + { 0xC808, 0xFC0F, X|TYPE_A, "SEM", }, /* Store External Map 32/7X * */ + { 0xC809, 0xFC0F, X|TYPE_A, "LEM", }, /* Load External Map 32/7X * */ + { 0xC80A, 0xFC0F, X|TYPE_A, "CEMA", }, /* Convert External Map 32/7X * */ + { 0xCC00, 0xFC08, TYPE_A, "LF", }, /* Load File */ + { 0xCC08, 0xFC08, TYPE_A, "LFBR", }, /* Load Base File */ + { 0xD000, 0xFC00, N|TYPE_A, "LEA", }, /* Load Effective Address # NBR */ + { 0xD400, 0xFC00, TYPE_A, "ST", }, /* Store B,H,W,D */ + { 0xD800, 0xFC00, TYPE_A, "STM", }, /* Store Masked B,H,W,D */ + { 0xDC00, 0xFC08, TYPE_A, "STF", }, /* Store File */ + { 0xDC08, 0xFC08, TYPE_A, "STFBR", }, /* Store Base File */ + { 0xE000, 0xFC08, TYPE_A, "SUF", }, /* Subtract Floating Memory D,W */ + { 0xE008, 0xFC08, TYPE_A, "ADF", }, /* Add Floating Memory D,W */ + { 0xE400, 0xFC08, TYPE_A, "DVF", }, /* Divide Floating Memory D,W */ + { 0xE408, 0xFC08, TYPE_A, "MPF", }, /* Multiply Floating Memory D,W */ + { 0xE800, 0xFC00, TYPE_A, "ARM", }, /* Add Register to Memory B,H,W,D */ + { 0xEC00, 0xFF80, TYPE_B, "BU", }, /* Branch Unconditional */ + { 0xEC00, 0xFF80, TYPE_A, "BCT", }, /* Branch Condition True */ + { 0xEC80, 0xFF80, TYPE_B, "BS", }, /* Branch Condition True CC1 = 1 */ + { 0xED00, 0xFF80, TYPE_B, "BGT", }, /* Branch Condition True CC2 = 1 */ + { 0xED80, 0xFF80, TYPE_B, "BLT", }, /* Branch Condition True CC3 = 1 */ + { 0xEE00, 0xFF80, TYPE_B, "BEQ", }, /* Branch Condition True CC4 = 1 */ + { 0xEE80, 0xFF80, TYPE_B, "BGE", }, /* Branch Condition True CC2|CC4 = 1 */ + { 0xEF00, 0xFF80, TYPE_B, "BLE", }, /* Branch Condition True CC3|CC4 = 1 */ + { 0xEF80, 0xFF80, TYPE_B, "BANY", }, /* Branch Condition True CC1|CC2|CC3|CC4 */ + { 0xF000, 0XFF80, TYPE_B, "BFT", }, /* Branch Function True */ + { 0xF000, 0xFF80, TYPE_A, "BCF", }, /* Branch Condition False */ + { 0xF080, 0xFF80, TYPE_B, "BNS", }, /* Branch Condition False CC1 = 0 */ + { 0xF100, 0xFF80, TYPE_B, "BNP", }, /* Branch Condition False CC2 = 0 */ + { 0xF180, 0xFF80, TYPE_B, "BNN", }, /* Branch Condition False CC3 = 0 */ + { 0xF200, 0xFF80, TYPE_B, "BNE", }, /* Branch Condition False CC4 = 0 */ + { 0xF280, 0xFF80, TYPE_B, "BCF 5,", }, /* Branch Condition False CC2|CC4 = 0 */ + { 0xF300, 0xFF80, TYPE_B, "BCF 6,", }, /* Branch Condition False CC3|CC4 = 0 */ + { 0xF380, 0xFF80, TYPE_B, "BAZ", }, /* Branch Condition False CC1|CC2|CC3|CC4=0*/ + { 0xF400, 0xFC70, TYPE_D, "BIB", }, /* Branch after Incrementing Byte */ + { 0xF420, 0xFC70, TYPE_D, "BIH", }, /* Branch after Incrementing Half */ + { 0xF440, 0xFC70, TYPE_D, "BIW", }, /* Branch after Incrementing Word */ + { 0xF460, 0xFC70, TYPE_D, "BID", }, /* Branch after Incrementing Double */ + { 0xF800, 0xFF80, TYPE_E, "ZM", }, /* Zero Memory B,H,W,D */ + { 0xF880, 0xFF80, TYPE_B, "BL", }, /* Branch and Link */ + { 0xF900, 0xFCC0, X|TYPE_B, "BRI", }, /* Branch and Reset Interrupt 32/55 * */ + { 0xF980, 0xFF80, TYPE_B, "LPSD", }, /* Load Program Status Double * */ + { 0xFA08, 0xFC00, TYPE_B, "JWCS", }, /* Jump to Writable Control Store * */ + { 0xFA80, 0xFF80, TYPE_B, "LPSDCM", }, /* LPSD and Change Map * */ + { 0xFB00, 0xFCC0, X|TYPE_A, "TRP", }, /* Transfer Register to Protect Register 32/7X */ + { 0xFB80, 0xFCC0, X|TYPE_A, "TPR", }, /* Transfer Protect Register to Register 32/7X */ + { 0xFC00, 0xFC07, TYPE_L, "EI", }, /* Enable Interrupt */ + { 0xFC01, 0xFC07, TYPE_L, "DI", }, /* Disable Interrupt */ + { 0xFC02, 0xFC07, TYPE_L, "RI", }, /* Request Interrupt */ + { 0xFC03, 0xFC07, TYPE_L, "AI", }, /* Activate Interrupt */ + { 0xFC04, 0xFC07, TYPE_L, "DAI", }, /* Deactivate Interrupt */ + { 0xFC05, 0xFC07, TYPE_M, "TD", }, /* Test Device */ + { 0xFC06, 0xFC07, TYPE_M, "CD", }, /* Command Device */ + { 0xFC17, 0xFC7F, TYPE_C, "SIO", }, /* Start I/O */ + { 0xFC1F, 0xFC7F, TYPE_C, "TIO", }, /* Test I/O */ + { 0xFC27, 0xFC7F, TYPE_C, "STPIO", }, /* Stop I/O */ + { 0xFC2F, 0xFC7F, TYPE_C, "RSCHNL", }, /* Reset Channel */ + { 0xFC37, 0xFC7F, TYPE_C, "HIO", }, /* Halt I/O */ + { 0xFC3F, 0xFC7F, TYPE_C, "GRIO", }, /* Grab Controller */ + { 0xFC47, 0xFC7F, TYPE_C, "RSCTL", }, /* Reset Controller */ + { 0xFC4F, 0xFC7F, TYPE_C, "ECWCS", }, /* Enable Channel WCS Load */ + { 0xFC5F, 0xFC7F, TYPE_C, "WCWCS", }, /* Write Channel WCS */ + { 0xFC67, 0xFC7F, TYPE_C, "ECI", }, /* Enable Channel Interrupt */ + { 0xFC6F, 0xFC7F, TYPE_C, "DCI", }, /* Disable Channel Interrupt */ + { 0xFC77, 0xFC7F, TYPE_C, "ACI", }, /* Activate Channel Interrupt */ + { 0xFC7F, 0xFC7F, TYPE_C, "DACI", }, /* Deactivate Channel Interrupt */ +}; + +/* Instruction decode printing routine + Inputs: + *of = output stream + val = 16/32 bit instruction to print left justified + sw = mode switches, 'M'=base mode, 'N'=nonbase mode +*/ +const char *fc_type = "WHDHBBBB"; /* F & C bit values */ + +int fprint_inst(FILE *of, uint32 val, int32 sw) +{ + uint16 inst = (val >> 16) & 0xFFFF; + int i; + int mode = 0; /* assume non base mode instructions */ + t_opcode *tab; + + if ((PSD[0] & 0x02000000) || (sw & SWMASK('M'))) /* bit 6 is base mode */ + mode = 1; + /* loop through the instruction table for an opcode match and get the type */ + for (tab = optab; tab->name != NULL; tab++) { + if (tab->opbase == (inst & tab->mask)) { + if (mode && (tab->type & (X | N))) + continue; /* non basemode instruction in base mode, skip */ + if (!mode && (tab->type & B)) + continue; /* basemode instruction in nonbase mode, skip */ + + /* TODO? Maybe want to make sure MODEL is 32/7X for X type instructions */ + + /* match found */ + fputs(tab->name, of); /* output the base opcode */ + + /* process the other fields of the instruction */ + switch(tab->type & 0xF) { + /* memory reference instruction */ + case TYPE_A: /* r,[*]o[,x] or r,o[(b)][,x] */ + /* zero memory instruction */ + case TYPE_E: /* [*]o[,x] or o[(b)][,x] */ + /* append B, H, W, D to base instruction using F & C bits */ + i = (val & 3) | ((inst >> 1) & 04); + if (((inst&0xfc00) == 0xe000) || + ((inst&0xfc00) == 0xe400)) + i &= ~4; /* remove f bit from fpt instr */ + if (((inst&0xfc00) != 0xdc00) && + ((inst&0xfc00) != 0xd000) && + ((inst&0xfc00) != 0x5400) && + ((inst&0xfc00) != 0x5800) && + ((inst&0xfc00) != 0x5c00) && + ((inst&0xfc00) != 0xcc00) && + ((inst&0xfc00) != 0x8000)) + fputc(fc_type[i], of); + /* Fall through */ + + /* BIx instructions or bit in memory reference instructions */ + case TYPE_D: /* r,[*]o[,x] or r,o[(b)],[,x] */ + if ((tab->type & 0xF) != TYPE_E) { + fputc(' ', of); +// fputc('R', of); + /* output the reg or bit number */ + fputc('0'+((inst>>7) & 07), of); + fputc(',', of); + } + /* Fall through */ + + /* branch instruction */ + case TYPE_B: /* [*]o[,x] or o[(b)],[,x] */ + if (((tab->type & 0xf) != TYPE_A) && ((tab->type & 0xf) != TYPE_D)) + fputc(' ', of); + if (mode) { + /* base reg mode */ + fprint_val(of, val&0xffff, 16, 16, PV_LEFT); /* output 16 bit offset */ + if (inst & 07) { + fputc('(', of); +// fputc('B', of); + fputc(('0'+(inst & 07)), of); /* output the base reg number */ + fputc(')', of); + } + if (inst & 0x70) { + fputc(',', of); +// fputc('R', of); + fputc(('0'+((inst >> 4) & 07)), of); /* output the index reg number */ + } + } else { + /* nonbase reg mode */ + if (inst & 0x10) + fputc('*', of); /* show indirection */ + fprint_val(of, val&0x7ffff, 16, 19, PV_LEFT); /* 19 bit offset */ + if (inst & 0x60) { + fputc(',', of); /* register coming */ +// fputc('R', of); + if (tab->type != TYPE_D) + fputc('0'+((inst & 0x60) >> 5), of); /* output the index reg number */ + else { + if ((inst & 0xfc00) != 0xf400) + fputc('0'+((inst & 0x60) >> 5), of); /* output the index reg number */ + } + } + } + break; + + /* immediate or XIO instructions */ + case TYPE_C: /* r,v */ + fputc(' ', of); +// fputc('R', of); + fputc('0'+((inst>>7) & 07), of); /* index reg number */ + fputc(',', of); + fprint_val(of, val&0xffff, 16, 16, PV_LEFT); /* 16 bit imm val or chan/suba */ + break; + + /* reg - reg instructions */ + case TYPE_F: /* rs,rd */ + fputc(' ', of); +// fputc('R', of); + fputc('0'+((inst>>4) & 07), of); /* src reg */ + fputc(',', of); +// fputc('R', of); + fputc('0'+((inst>>7) & 07), of); /* dest reg */ + break; + + /* single reg instructions */ + case TYPE_G: /* op r */ + fputc(' ', of); +// fputc('R', of); + fputc('0'+((inst>>7) & 07), of); /* output src/dest reg num */ + break; + + /* just output the instruction */ + case TYPE_H: /* empty */ + break; + + /* reg and bit shift cnt */ + case TYPE_I: /* r,b */ + fputc(' ', of); +// fputc('R', of); + fputc('0'+((inst>>7) & 07), of); /* reg number */ + fputc(',', of); + fprint_val(of, inst&0x1f, 10, 5, PV_LEFT); /* 5 bit shift count */ + break; + + /* register bit operations */ + case TYPE_K: /* r,rb */ + fputc(' ', of); +// fputc('R', of); + fputc('0'+((inst>>4) & 07), of); /* register number */ + fputc(',', of); + i = ((inst & 3) << 3) | ((inst >> 7) & 07); + fprint_val(of, i, 10, 5, PV_LEFT); /* reg bit number to operate on */ + break; + + /* interrupt control instructions */ + case TYPE_L: /* i */ + fputc(' ', of); + fprint_val(of, (inst>>3)&0x7f, 16, 7, PV_RZRO); /* output 7 bit priority level value */ + break; + + /* CD/TD Class E I/O instructions */ + case TYPE_M: /* i,v */ + fputc(' ', of); + fprint_val(of, (inst>>3)&0x7f, 16, 7, PV_RZRO); /* output 7 bit device address */ + fputc(',', of); + fprint_val(of, (val&0xffff), 16, 16, PV_RZRO); /* output 16 bit command code */ + break; + + /* SVC instructions */ + case TYPE_N: /* i,v */ + fputc(' ', of); + fprint_val(of, (val>>12)&0xf, 16, 4, PV_RZRO); /* output 4 bit svc number */ + fputc(',', of); + fprint_val(of, (val & 0xFFF), 16, 12, PV_LEFT); /* output 12 bit command code */ + break; + + default: + /* FIXME - return error code here? */ +// /* fputs(" unknown type", of); /* output error message */ +// return SCPE_ARG; /* unknown type */ + break; + } + /* return the size of the instruction */ + return (tab->type & H) ? 2 : 4; + } + } + /* FIXME - should we just return error here? or dump as hex data? */ + /* we get here if opcode not found, print data value */ + if (mode) + fputs(" Binvld ", of); /* output basemode error message */ + else + fputs(" Ninvld ", of); /* output non-basmode error message */ + fprint_val(of, val, 16, 32, PV_RZRO); /* output unknown 32 bit instruction code */ + return 4; /* show as full word size */ +} + +/* Symbolic decode + + Inputs: + *of = output stream + addr = current PC + *val = pointer to values + *uptr = pointer to unit + sw = switches + Outputs: + return = status code +*/ +t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) +{ + int i; + int l = 4; /* default to full words */ + int rdx = 16; /* default radex is hex */ + uint32 num; +// uint32 tmp=*val; /* for debug */ + + if (sw & SIM_SW_STOP) { /* special processing for step */ + if (PSD[0] & 0x02000000) { /* bit 6 is base mode */ + sw |= SWMASK('M'); /* display basemode */ + sw &= ~SWMASK('N'); /* no non-based display */ + } else { + sw |= SWMASK('N'); /* display non-basemode */ + sw &= ~SWMASK('M'); /* no basemode display */ + } + } + if (addr & 0x02) + l = 2; + /* determine base for number output */ + if (sw & SWMASK ('D')) + rdx = 10; /* decimal */ + else + if (sw & SWMASK ('O')) + rdx = 8; /* octal */ + else + if (sw & SWMASK ('H')) + rdx = 16; /* hex */ + + if (sw & SWMASK ('M')) { /* machine base mode? */ + sw &= ~ SWMASK('B'); /* Can't do B and M at same time */ + sw &= ~ SWMASK('C'); /* Can't do C and M at same time */ + if (addr & 0x02) + l = 2; + else + l = 4; + } else + if (sw & SWMASK('F')) { + l = 4; /* words are 4 bytes */ + } else + if (sw & SWMASK('W')) { + l = 2; /* halfwords are 2 bytes */ + } else + if (sw & SWMASK('B')) { + l = 1; /* bytes */ + } + + if (sw & SWMASK ('C')) { + fputc('\'', of); /* opening apostorphe */ + for(i = 0; i < l; i++) { + int ch = val[i] & 0xff; /* get the char */ + if (ch >= 0x20 && ch <= 0x7f) /* see if printable */ + fprintf(of, "%c", ch); /* output the ascii char */ + else + fputc('_', of); /* use underscore for unprintable char */ + } + fputc('\'', of); /* closing apostorphe */ + } else + /* go print the symbolic instruction for base or nonbase mode */ + if (sw & (SWMASK('M') | SWMASK('N'))) { + num = 0; + for (i = 0; i < l && i < 4; i++) { + num |= (uint32)val[i] << ((l-i-1) * 8); /* collect 8-32 bit data value to print */ + } + if (addr & 0x02) + num <<= 16; /* use rt hw */ + l = fprint_inst(of, num, sw); /* go print the instruction */ + if (((addr & 2) == 0) && (l == 2)) { /* did we execute a left halfword instruction */ + fprintf(of, "; "); + l = fprint_inst(of, num<<16, sw); /* go print right halfword instruction */ + l = 4; /* next word address */ + } + } else { + /* print the numeric value of the memory data */ + num = 0; + for (i = 0; i < l && i < 4; i++) + num |= (uint32)val[i] << ((l-i-1) * 8); /* collect 8-32 bit data value to print */ + fprint_val(of, num, rdx, l*8, PV_RZRO); /* print it in requested radix */ + } + return -(l-1); /* will be negative if we did anything */ +} + +/* + * Collect offset in radix. + */ +t_stat get_off (CONST char *cptr, CONST char **tptr, uint32 radix, t_value *val, char *m) +{ + t_stat r = SCPE_OK; /* assume OK return */ + + *m = 0; /* left parend found flag if set */ + *val = (uint32)strtotv(cptr, tptr, radix); /* convert to value */ + if (cptr == *tptr) + r = SCPE_ARG; /* no argument found error */ + else { + cptr = *tptr; /* where to start looking */ + while (sim_isspace(*cptr)) + cptr++; /* skip any spaces */ + if (*cptr++ == '(') { + *m = 1; /* show we found a left parend */ + while (sim_isspace(*cptr)) + cptr++; /* skip any spaces */ + } + *tptr = cptr; /* return next char pointer */ + } + return r; /* return status */ +} + +/* + * Collect immediate in radix. + */ +t_stat get_imm (CONST char *cptr, CONST char **tptr, uint32 radix, t_value *val) +{ + t_stat r; + + r = SCPE_OK; + *val = (uint32)strtotv (cptr, tptr, radix); + if ((cptr == *tptr) || (*val > 0xffff)) + r = SCPE_ARG; + else { + cptr = *tptr; + while (sim_isspace (*cptr)) cptr++; + *tptr = cptr; + } + return r; +} + +/* Symbolic input + Inputs: + *cptr = pointer to input string + addr = current PC + uptr = pointer to unit + *val = pointer to output values + sw = switches + Outputs: + status = error status +*/ + +t_stat parse_sym (CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) +{ + int i; + int x; + int l = 4; /* default to full words */ + int rdx = 16; /* default radex is hex */ + char mod = 0; + t_opcode *tab; + t_stat r; + uint32 num; + uint32 max[5] = {0, 0xff, 0xffff, 0, 0xffffffff}; + CONST char *tptr; + char gbuf[CBUFSIZE]; + + /* determine base for numbers */ + if (sw & SWMASK ('D')) + rdx = 10; /* decimal */ + else + if (sw & SWMASK ('O')) + rdx = 8; /* octal */ + else + if (sw & SWMASK ('H')) + rdx = 16; /* hex */ + + /* set instruction size */ + if (sw & SWMASK('F')) { + l = 4; + } else + if (sw & SWMASK('W')) { + l = 2; + } + + /* process a character string */ + if (sw & SWMASK ('C')) { + cptr = get_glyph_quoted(cptr, gbuf, 0); /* Get string */ + for(i = 0; gbuf[i] != 0; i++) { + val[i] = gbuf[i]; /* copy in the string */ + } + return -(i - 1); + } + + /* see if we are processing a nonbase instruction */ + if (sw & SWMASK ('N')) { + /* process nonbased instruction */ + cptr = get_glyph(cptr, gbuf, 0); /* Get uppercase opcode */ + l = strlen(gbuf); /* opcode length */ + /* try to find the opcode in the table */ + for (tab = optab; tab->name != NULL; tab++) { + i = tab->type & 0xf; /* get the instruction type */ + /* check for memory reference instruction */ + if (i == TYPE_A || i == TYPE_E) { + /* test for base opcode name without B, H, W, D applied */ + if (sim_strncasecmp(tab->name, gbuf, l - 1) == 0) + break; /* found */ + } else + /* test the full opcode name */ + if (sim_strcasecmp(tab->name, gbuf) == 0) + break; /* found */ + } + if (tab->name == NULL) /* see if anything found */ + return SCPE_ARG; /* no, return invalid argument error */ + num = tab->opbase<<16; /* get the base opcode value */ + + /* process each instruction type */ + switch(i) { + /* mem ref instruction */ + case TYPE_A: /* c r,[*]o[,x] */ + /* zero memory instruction */ + case TYPE_E: /* c [*]o[,x] */ + switch(gbuf[l]) { + case 'B': num |= 0x80000; break; /* byte, set F bit */ + case 'H': num |= 0x00001; break; /* halfword */ + case 'W': num |= 0x00000; break; /* word */ + case 'D': num |= 0x00002; break; /* doubleword */ + default: + return SCPE_ARG; /* base op suffix error */ + } + /* Fall through */ + + /* BIx instructions or memory reference */ + case TYPE_D: /* r,[*]o[,x] */ + while (sim_isspace(*cptr)) + cptr++; /* skip leading blanks */ + if (i != TYPE_E) { + /* get reg number except for zero memory instruction */ + if (*cptr >= '0' || *cptr <= '7') { /* reg# is 0-7 */ + x = *cptr++ - '0'; /* get the reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if (*cptr++ != ',') /* check for required comma */ + return SCPE_ARG; /* anything else is an argument error */ + num |= x << 23; /* position reg number in instruction */ + } else + return SCPE_ARG; /* invalid reg number is an argument error */ + } + /* Fall through */ + + /* branch instruction */ + case TYPE_B: /* [*]o[,x] */ + if (*cptr == '*') { /* test for indirection */ + num |= 0x100000; /* set indirect flag */ + cptr++; /* skip past the '*' */ + while (sim_isspace(*cptr)) + cptr++; /* skip blanks */ + } + if ((r = get_off(cptr, &tptr, 16, val, &mod))) /* get operand address */ + return r; /* argument error if a problem */ + cptr = tptr; /* set pointer to returned next char pointer */ + if (*val > 0x7FFFF) /* 19 bit address max */ + return SCPE_ARG; /* argument error */ + num |= *val; /* or our address into instruction */ + if (mod) { + return SCPE_ARG; /* if a '(' found, that is an arg error */ + } + if (*cptr++ == ',') { /* test for optional index reg number */ + if (*cptr >= '0' || *cptr <= '7') { /* reg# is 0-7 */ + x = *cptr++ - '0'; /* get reg number */ + num |= x << 20; /* position and put into instruction */ + } else + return SCPE_ARG; /* reg# not 0-7, so arg error */ + } + break; + + /* immediate or XIO instruction */ + case TYPE_C: /* r,v */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* get reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr++ != ',') /* next char need to be a comma */ + return SCPE_ARG; /* it's not, so arg error */ + num |= x << 23; /* position and put into instruction */ + } else + return SCPE_ARG; /* invalid reg#, so arg error */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, rdx, val))) /* get 16 bit immediate value */ + return r; /* return error from conversion */ + num |= *val; /* or in the 16 bit value */ + break; + + /* reg-reg instructions */ + case TYPE_F: /* r,r */ + while (sim_isspace(*cptr)) + cptr++; /* skip blanks */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr++ != ',') /* test for required ',' */ + return SCPE_ARG; /* it's not there, so error */ + num |= x << 23; /* insert first reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + while (sim_isspace(*cptr)) + cptr++; /* skip more spaces */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip any spaces */ + num |= x << 20; /* insert 2nd reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + break; + + /* single reg instructions */ + case TYPE_G: /* r */ + while (sim_isspace(*cptr)) + cptr++; /* skip blanks */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + num |= x << 23; /* insert first reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + break; + + /* opcode only instructions */ + case TYPE_H: /* empty */ + break; + + /* reg and bit shift instructions */ + case TYPE_I: /* r,b */ + while (sim_isspace (*cptr)) + cptr++; /* skip blanks */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr++ != ',') /* test for required ',' */ + return SCPE_ARG; /* it's not there, so error */ + num |= (x << 23); /* insert first reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, 10, val))) /* get 5 bit shift value */ + return r; /* return error from conversion */ + if (*val > 0x1f) /* 5 bit max count */ + return SCPE_ARG; /* invalid shift count */ + num |= (*val << 16); /* or in the 5 bit value */ + break; + + /* register bit operations */ + case TYPE_K: /* r,rb */ + while (sim_isspace(*cptr)) + cptr++; /* skip blanks */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr++ != ',') /* test for required ',' */ + return SCPE_ARG; /* it's not there, so error */ + num |= (x << 20); /* insert reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, 10, val))) /* get 5 bit bit number */ + return r; /* return error from conversion */ + if (*val > 0x1f) /* 5 bit max count */ + return SCPE_ARG; /* invalid bit count */ + x = *val / 8; /* get 2 bit byte number */ + num |= (x & 3) << 16; /* insert 2 bit byte code into instruction */ + x = *val % 8; /* get bit in byte value */ + num |= (x & 7) << 23; /* or in the bit value */ + break; + + /* interrupt control instructions */ + case TYPE_L: /* i */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, rdx, val))) /* get 7 bit bit number */ + return r; /* return error from conversion */ + if (*val > 0x7f) /* 7 bit max count */ + return SCPE_ARG; /* invalid value */ + num |= (*val & 0x7f) << 19; /* or in the interrupt level */ + break; + + /* CD/TD Class E I/O instructions */ + case TYPE_M: /* d,v */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, rdx, val))) /* get 7 bit bit number */ + return r; /* return error from conversion */ + if (*val > 0x7f) /* 7 bit max count */ + return SCPE_ARG; /* invalid value */ + num |= (*val & 0x7f) << 19; /* or in the device address */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, rdx, val))) /* get 16 bit command code */ + return r; /* return error from conversion */ + num |= *val; /* or in the 16 bit value */ + break; + } + return (tab->type & H) ? 2 : 4; /* done with nonbased instructions */ + } + + /* see if we are processing a base mode instruction */ + if (sw & SWMASK ('M')) { /* base mode? */ + /* process base mode instruction */ + cptr = get_glyph(cptr, gbuf, 0); /* Get uppercase opcode */ + l = strlen(gbuf); /* save the num of char in opcode */ + /* loop through the instruction table for an opcode match and get the type */ + for (tab = optab; tab->name != NULL; tab++) { + i = tab->type & 0xf; /* get the type */ + /* check for memory reference instruction */ + if (i == TYPE_A || i == TYPE_E) { + /* test for base opcode name without B, H, W, D applied */ + if (sim_strncasecmp(tab->name, gbuf, l - 1) == 0) + break; /* found */ + } else + /* test the full opcode name */ + if (sim_strcasecmp(tab->name, gbuf) == 0) + break; /* found */ + } + if (tab->name == NULL) /* see if anything found */ + return SCPE_ARG; /* no, return invalid argument error */ + num = tab->opbase<<16; /* get the base opcode value */ + + /* process each instruction type */ + switch(i) { + /* mem ref instruction */ + case TYPE_A: /* c r,o[(b)][,x] */ + /* zero memory instruction */ + case TYPE_E: /* c o[(b)][,x] */ + switch(gbuf[l]) { + case 'B': num |= 0x80000; break; /* byte, set F bit */ + case 'H': num |= 0x00001; break; /* halfword */ + case 'W': num |= 0x00000; break; /* word */ + case 'D': num |= 0x00002; break; /* doubleword */ + default: + return SCPE_ARG; /* base op suffix error */ + } + /* Fall through */ + + /* BIx instructions or memory reference */ + case TYPE_D: /* r,o[(b)],[,x] */ + while (sim_isspace(*cptr)) + cptr++; /* skip leading blanks */ + if (i != TYPE_E) { + /* get reg number except for zero memory instruction */ + if (*cptr >= '0' || *cptr <= '7') { /* reg# is 0-7 */ + x = *cptr++ - '0'; /* get the reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if (*cptr++ != ',') /* check for required comma */ + return SCPE_ARG; /* anything else is an argument error */ + num |= x << 23; /* position reg number in instruction */ + } else + return SCPE_ARG; /* invalid reg number is an argument error */ + } + /* Fall through */ + + /* branch instruction */ + case TYPE_B: /* o[(b)],[,x] */ + if ((r = get_off(cptr, &tptr, 16, val, &mod))) /* get offset */ + return r; /* argument error if a problem */ + cptr = tptr; /* set pointer to returned next char pointer */ + if (*val > 0xFFFF) /* 16 bit offset max */ + return SCPE_ARG; /* argument error */ + num |= *val; /* or offset into instruction */ + if (mod) { /* see if '(' found in input */ + if (*cptr >= '0' || *cptr <= '7') { /* base reg# 0-7 */ + x = *cptr++ - '0'; /* get reg number */ + while (sim_isspace(*cptr)) + cptr++; /* skip any spaces */ + if (*cptr++ != ')') /* test for closing right parend */ + return SCPE_ARG; /* arg error if not found */ + num |= x << 16; /* put base reg number into instruction */ + } else + return SCPE_ARG; /* no '(' found, so arg error */ + } + if (*cptr++ == ',') { /* test for optional index reg number */ + if (*cptr >= '0' || *cptr <= '7') { /* reg# is 0-7 */ + x = *cptr++ - '0'; /* get reg number */ + num |= x << 20; /* position and put into instruction */ + } else + return SCPE_ARG; /* reg# not 0-7, so arg error */ + } + break; + + /* immediate or XIO instruction */ + case TYPE_C: /* r,v */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* get reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr++ != ',') /* next char need to be a comma */ + return SCPE_ARG; /* it's not, so arg error */ + num |= x << 23; /* position and put into instruction */ + } else + return SCPE_ARG; /* invalid reg#, so arg error */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, rdx, val))) /* get 16 bit immediate value */ + return r; /* return error from conversion */ + num |= *val; /* or in the 16 bit value */ + break; + + /* reg-reg instructions */ + case TYPE_F: /* r,r */ + while (sim_isspace(*cptr)) + cptr++; /* skip blanks */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr++ != ',') /* test for required ',' */ + return SCPE_ARG; /* it's not there, so error */ + num |= x << 23; /* insert first reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + while (sim_isspace(*cptr)) + cptr++; /* skip more spaces */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip any spaces */ + num |= x << 20; /* insert 2nd reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + break; + + /* single reg instructions */ + case TYPE_G: /* r */ + while (sim_isspace(*cptr)) + cptr++; /* skip blanks */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + num |= x << 23; /* insert first reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + break; + + /* opcode only instructions */ + case TYPE_H: /* empty */ + break; + + /* reg and bit shift instructions */ + case TYPE_I: /* r,b */ + while (sim_isspace(*cptr)) + cptr++; /* skip blanks */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr++ != ',') /* test for required ',' */ + return SCPE_ARG; /* it's not there, so error */ + num |= (x << 23); /* insert first reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, 10, val))) /* get 5 bit shift value */ + return r; /* return error from conversion */ + if (*val > 0x1f) /* 5 bit max count */ + return SCPE_ARG; /* invalid shift count */ + num |= (*val << 16); /* or in the 5 bit value */ + break; + + /* register bit operations */ + case TYPE_K: /* r,rb */ + while (sim_isspace(*cptr)) + cptr++; /* skip blanks */ + if (*cptr >= '0' || *cptr <= '7') { /* test for valid reg# */ + x = *cptr++ - '0'; /* calc reg# */ + while (sim_isspace(*cptr)) + cptr++; /* skip spaces */ + if (*cptr++ != ',') /* test for required ',' */ + return SCPE_ARG; /* it's not there, so error */ + num |= (x << 20); /* insert reg# into instruction */ + } else + return SCPE_ARG; /* reg# invalid, so arg error */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, 10, val))) /* get 5 bit bit number */ + return r; /* return error from conversion */ + if (*val > 0x1f) /* 5 bit max count */ + return SCPE_ARG; /* invalid bit count */ + x = *val / 8; /* get 2 bit byte number */ + num |= (x & 3) << 16; /* insert 2 bit byte code into instruction */ + x = *val % 8; /* get bit in byte value */ + num |= (x & 7) << 23; /* or in the bit value */ + break; + + /* interrupt control instructions */ + case TYPE_L: /* i */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, rdx, val))) /* get 7 bit bit number */ + return r; /* return error from conversion */ + if (*val > 0x7f) /* 7 bit max count */ + return SCPE_ARG; /* invalid value */ + num |= (*val & 0x7f) << 19; /* or in the interrupt level */ + break; + + /* CD/TD Class E I/O instructions */ + case TYPE_M: /* d,v */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, rdx, val))) /* get 7 bit bit number */ + return r; /* return error from conversion */ + if (*val > 0x7f) /* 7 bit max count */ + return SCPE_ARG; /* invalid value */ + num |= (*val & 0x7f) << 19; /* or in the device address */ + while (sim_isspace(*cptr)) + cptr++; /* skip any blanks */ + if ((r = get_imm(cptr, &tptr, rdx, val))) /* get 16 bit command code */ + return r; /* return error from conversion */ + num |= *val; /* or in the 16 bit value */ + break; + } + return (tab->type & H) ? 2 : 4; /* done with base mode insrructions */ + } + + /* get here for any other switch value */ + /* this code will get a value based on length specified in switches */ + num = get_uint(cptr, rdx, max[l], &r); /* get the unsigned value */ + for (i = 0; i < l && i < 4; i++) + val[i] = (num >> ((l - (1 + i)) * 8)) & 0xff; /* get 1-4 bytes of data */ + return -(l-1); +} + diff --git a/SEL32/tests/SetupNet b/SEL32/tests/SetupNet new file mode 100755 index 00000000..ef4c3084 --- /dev/null +++ b/SEL32/tests/SetupNet @@ -0,0 +1,635 @@ +#!/bin/sh + +# Copyright (c) 2020, Geert Rolf +# +# 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 +# GEERT ROLF 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. +# + +# Test platforms: +# +# Debian 10 (Buster) +# Raspbian Buster +# FreeBSD 12.1 +# OpenBSD 6.7 +# NetBSD 9.1 + +# CHANGE HISTORY +# 2021/4/8 avoid setting PATH in scripts for root +# 2021/5/31 whereis used without -b in OpenBSD and NetBSD +# Corrected: bridge create and fwdelay done twice for NetBSD +# FreeBSD: tapX opened by userland program not by ifconfig +# 2021/11/17 check for existance of br0 done too lousy. Done better. +# + +# uncomment next line if you need more than one tap = run multiple SIMHs... +#OPSMODE="expert" +# ... by editting the saved params file followed by rerun of this script + +OS=`uname -s` +case $OS in + "FreeBSD" | "OpenBSD" | "NetBSD") + # List of Utils + LOU="ifconfig brconfig sysctl chown netstat" + + # set $util to path of util for all in $LOU + for U in $LOU + do + # whereis -b in only FreeBSD as in Linux + if test $OS = "FreeBSD" + then + eval ${U}="`whereis -b $U | + awk '{ if($2 != "") + print $2; + else + print "void"; + }'`" + else + eval ${U}="`whereis $U | + awk '{ if($1 != "") + print $1; + else + print "void"; + }'`" + fi + done + + # make list of all interfaces ignoring lo + AVL_IF=`$ifconfig -a | + grep -v '^[ ]' | + awk -F: '{ print $1 }' | + grep -v 'lo' | + sed '1,$s/^ //'` + + ## echo $AVL_IF + + # found bridge0 in active interfaces? + L=`echo $AVL_IF | grep bridge0 | wc -l` + if test $L -ne 0 + then + echo "$0: bridge0 already configured." + echo "-- if you configured bridge0 statically don't use this script" + echo "-- otherwise if you do not want permanent settings" + echo "-- and want bridge0 configured differently reboot first" + exit 1 + fi + + ;; + "Linux") + # List of Utils + LOU="ip brctl tunctl netstat" + + # set $util to path of util for all in $LOU + for U in $LOU + do + eval ${U}="`whereis -b $U | + awk '{ if($2 != "") + print $2; + else + print "void"; + }'`" + done + + ERR=0 + # check brctl to exist + if test $brctl = "void" + then + echo 'No brctl program -- please install package bridge-utils' + ERR=1 + fi + + # check tunctl to exist + if test $tunctl = "void" + then + echo 'No tunctl program -- please install package uml-utilities' + ERR=1 + fi + + # quit when either not installed + if test $ERR -eq 1 + then + exit 1 + fi + + # make list of all interfaces ignoring lo + AVL_IF=`$ip link show | + grep '^[0-9]' | + awk -F: '{ print $2 }' | + grep -v 'lo' | + sed '1,$s/^ //'` + + # found br0 in active interfaces? + L=`echo $AVL_IF | tr ' ' '\012' | grep '^br0$' | wc -l` + if test $L -ne 0 + then + echo "$0: br0 already configured." + echo "-- if you configured br0 statically don't use this script" + echo "-- otherwise if you do not want permanent settings" + echo "-- and want br0 configured differently reboot first" + exit 1 + fi + + ;; +esac + +# let user chose the interface he/she wants to use +echo " Available networkinterfaces" +N=0 +for I in $AVL_IF +do + N=`expr $N + 1` + case $OS in + "FreeBSD" | "OpenBSD" | "NetBSD") + IPCMD="$ifconfig $I " + ;; + "Linux") + IPCMD="$ip addr show $I " + ;; + esac + + L=`$IPCMD | + grep 'inet' | + grep -v 'inet6' | + wc -l` + if test $L -eq 0 + then + M="not configured" + else + M=`$IPCMD | + grep 'inet' | + grep -v 'inet6' | + awk '{ print $2 }' ` + fi + + # did we see wlan? alas... + L=`echo $I | grep wlan | wc -l` + if test $L -gt 0 + then + M="$M (wlan not supported)" + echo "-: $I $M" + N=`expr $N - 1` + else + if test -r SnetSaved.$I + then + echo "$N: $I $M (saved params available)" + else + echo "$N: $I $M" + fi + fi +done +# take wlan out +AVL_IF=`echo $AVL_IF | sed 's/wlan.//'` + +if test $N -gt 1 +then + ANSWER=0 + while test $ANSWER -lt 1 -o $ANSWER -gt $N + do + echo -n "Which interface do you want to use? " + read ANSWER + done +else + ANSWER=1 +fi + +N=0 +for I in $AVL_IF +do + N=`expr $N + 1` + if test $N -eq $ANSWER + then + ACT_IF=$I + fi +done + +# see if there are saved params for this interface +if test -r SnetSaved.$ACT_IF +then + . ./SnetSaved.$ACT_IF + echo "Saved params loaded from SnetSaved.$ACT_IF" +fi + +echo "" +echo "Interface to use for SIMH......... " $ACT_IF + +if test "x$IPNR" = "x" +then + case $OS in + "FreeBSD" | "OpenBSD" | "NetBSD") + IPCMD="$ifconfig $ACT_IF " + ;; + "Linux") + IPCMD="$ip addr show dev $ACT_IF " + ;; + esac + + L=`$IPCMD | + grep inet | + grep -v inet6 | + wc -l` + if test $L -eq 0 + then + IPNR="not configured" + else + IPNR=`$IPCMD | + grep inet | + grep -v inet6 | + awk '{ print $2 }' ` + fi +fi +echo "IPnumber on this interface........ " $IPNR + +if test "x$IPBRO" = "x" +then + case $OS in + "FreeBSD" | "OpenBSD" | "NetBSD") + IPCMD="$ifconfig $ACT_IF " + SEDBRO='1s/^.*broadcast //' + ;; + "Linux") + IPCMD="$ip addr show dev $ACT_IF " + SEDBRO='1s/^.*brd //' + ;; + esac + + IPBRO=`$IPCMD | + grep inet | + grep -v inet6 | + sed "$SEDBRO" | + sed '1s/[ ].*$//'` +fi +echo "IP Broadcast on this interface.... " $IPBRO + +if test "x$DEFRT" = "x" +then + case $OS in + "FreeBSD" | "OpenBSD" | "NetBSD") + DEFRT=`$netstat -rn | + grep $ACT_IF | + grep 'default' | + awk '{ print $2 }'` + ;; + "Linux") + DEFRT=`$netstat -rn | + grep $ACT_IF | + grep '^0\.' | + uniq | + awk '{ print $2 }'` + ;; + esac +fi +if test "x$DEFRT" = "x" +then + echo "Default Route set to Gateway...... " none +else + echo "Default Route set to Gateway...... " $DEFRT +fi + +if test "x$OS" = "xLinux" +then + if test "x$IPFWD" = "x" + then + IPFWD=`cat /proc/sys/net/ipv4/ip_forward` + fi + if test $IPFWD -eq 1 + then + echo "IP forwarding is active........... " YES + else + echo "IP forwarding is active........... " NO + fi +fi + +# nr of taps the user wants or 1 for default +if test "x${NrTaps}" = "x" +then + NrTaps=1 +fi +echo "Number of taps to create.......... " $NrTaps + + +# the user who needs access to the tap +if test "x$SimhUser" = "x" +then + case $OS in + "FreeBSD" | "OpenBSD" | "NetBSD") + SimhUser="root" + ;; + "Linux") + if test "x${SUDO_USER}" != "x" + then + SimhUser=${SUDO_USER} + else + SimhUser=${USER} + fi + ;; + esac +fi +echo "User who runs SIMH on the taps.... " $SimhUser + +# only save params when in expert OPSMODE +if test "X$OPSMODE" = "Xexpert" +then + if test ! -r SnetSaved.$ACT_IF + then + cat - > SnetSaved.$ACT_IF < $JOBFILE <<\EOF +#!/bin/sh + +# This script should be run under root permission + +EOF + +cat - > $TMPFILE <<\EOF +echo ${CMD} +${CMD} +if test $? -ne 0 +then + echo '*** FAIL:' ${CMD} + exit 1 +fi + +EOF + +case $OS in + "Linux") + echo "CMD=\"$brctl addbr br0\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"$tunctl -t tap${N} -u ${SimhUser}\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + + echo "CMD=\"$brctl addif br0 ${ACT_IF}\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$brctl setfd br0 0\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ip link set ${ACT_IF} down\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + if ! test "$IPNR" = "not configured" + then + echo "CMD=\"$ip addr add ${IPNR} dev br0\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + fi + + if ! test "$IPNR" = "not configured" + then + ## if test ! "x$DEFRT" = "x" + ## then + ## echo "CMD=\"$ip route del default via ${DEFRT} dev ${ACT_IF}\"" >> $JOBFILE + ## cat $TMPFILE >> $JOBFILE + ## fi + echo "CMD=\"$ip addr del ${IPNR} dev ${ACT_IF}\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + fi + + echo "CMD=\"$ip link set ${ACT_IF} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ip link set br0 up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + + if test ! "x$DEFRT" = "x" + then + echo "CMD=\"$ip route add default via ${DEFRT} dev br0\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + fi + + ipfwd=`cat /proc/sys/net/ipv4/ip_forward` + if test $IPFWD -ne $ipfwd + then + echo "CMD=\"echo ${IPFWD} > /proc/sys/net/ipv4/ip_forward\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + fi + + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"$brctl addif br0 tap${N}\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ip link set tap${N} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + BRIDGE="br0" + EXAMPLE="tap:tap0" + + ;; + "FreeBSD") + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"$ifconfig tap${N} create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + + echo "CMD=\"$sysctl net.link.tap.up_on_open=1\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ifconfig bridge0 create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + case $NrTaps in + 1 ) + echo "CMD=\"$ifconfig bridge0 addm ${ACT_IF} addm tap0\"" >> $JOBFILE + ;; + 2 ) + echo "CMD=\"$ifconfig bridge0 addm ${ACT_IF} addm tap0 addm tap1\"" >> $JOBFILE + ;; + 3 ) + echo "CMD=\"$ifconfig bridge0 addm ${ACT_IF} addm tap0 addm tap1 addm tap2\"" >> $JOBFILE + ;; + 4 ) + echo "CMD=\"$ifconfig bridge0 addm ${ACT_IF} addm tap0 addm tap1 addm tap2 addm tap3\"" >> $JOBFILE + ;; + * ) + echo "Sorry too many taps..." + exit + esac + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ifconfig bridge0 up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + BRIDGE="bridge0" + EXAMPLE="tap:tap0" + ;; + "OpenBSD") + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"$ifconfig tap${N} create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ifconfig tap${N} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + + echo "CMD=\"$ifconfig bridge0 create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ifconfig bridge0 fwddelay 4\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + case $NrTaps in + 1 ) + echo "CMD=\"$ifconfig bridge0 add ${ACT_IF} add tap0\"" >> $JOBFILE + ;; + 2 ) + echo "CMD=\"$ifconfig bridge0 add ${ACT_IF} add tap0 add tap1\"" >> $JOBFILE + ;; + 3 ) + echo "CMD=\"$ifconfig bridge0 add ${ACT_IF} add tap0 add tap1 add tap2\"" >> $JOBFILE + ;; + 4 ) + echo "CMD=\"$ifconfig bridge0 add ${ACT_IF} add tap0 add tap1 add tap2 add tap3\"" >> $JOBFILE + ;; + * ) + echo "Sorry too many taps..." + exit + esac + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ifconfig bridge0 up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + BRIDGE="bridge0" + EXAMPLE="tap:tap0" + ;; + "NetBSD") + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"$ifconfig tap${N} create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$ifconfig tap${N} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + + echo "CMD=\"$ifconfig bridge0 create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$brconfig bridge0 fwddelay 1\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + case $NrTaps in + 1 ) + echo "CMD=\"$brconfig bridge0 add ${ACT_IF} add tap0\"" >> $JOBFILE + ;; + 2 ) + echo "CMD=\"$brconfig bridge0 add ${ACT_IF} add tap0 add tap1\"" >> $JOBFILE + ;; + 3 ) + echo "CMD=\"$brconfig bridge0 add ${ACT_IF} add tap0 add tap1 add tap2\"" >> $JOBFILE + ;; + 4 ) + echo "CMD=\"$brconfig bridge0 add ${ACT_IF} add tap0 add tap1 add tap2 add tap3\"" >> $JOBFILE + ;; + * ) + echo "Sorry too many taps..." + exit + esac + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"$brconfig bridge0 up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + BRIDGE="bridge0" + EXAMPLE="tap:tap0" + ;; +esac + + cat - >> $JOBFILE < detached +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications (N/U) +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- diag.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; +; Set run limit of 2 minutes +set runlimit 2 minutes +set on +on error ignore +on runtime echof "\r\n*** FAILED - SEL32 Test Runtime Limit %SIM_RUNLIMIT% %SIM_RUNLIMIT_UNITS% Exceeded ***\n"; exit 1 +; +if not exist "diag.tap" echo "\n*** FAILURE diag.tap file missing ***\n"; exit 1 +; +; Set debug output +;set debug -n sel.log +;set debug stderr +; +; CPU type and memory +;set CPU 32/27 2M +;set CPU 32/27 4M +;set CPU 32/87 4M +set CPU 32/67 4M +;set CPU 32/97 4M +;set CPU V6 4M +;set CPU V6 8M +;set CPU V9 4M +;set CPU V9 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;;set cpu history=10000 +; useful options +;set cpu debug=exp +;set cpu debug=cmd;exp;irq;trap;xio +;set cpu debug=cmd;irq;trap;exp +;set cpu debug=irq;trap;exp;xio +;set cpu debug=irq;xio +;set cpu debug=irq;exp;trap +; +; RTC realtime clock +set RTC 50 +;set RTC 60 +set RTC enable +; RTC debug options +;set RTC debug=cmd +; +; ITM interval timer +;set ITM debug=cmd +; +; IOP at channel 7e00 +; useful options +;set iop debug=cmd;exp +;set iop debug=cmd +; make iop online +set iop enable +; set iop channel address +set iop0 dev=7e00 +; +; MFP at channel 7e00 +; useful options +;set mfp debug=cmd;exp +; make mfp online +;set mfp enable +; set mfp channel address +;set mfp0 dev=7e00 +;set mfp0 dev=7600 +; +; COM 8-Line +;set com debug=cmd; +;set coml0 enable +;set coml1 enable +;set coml2 enable +;set coml3 enable +;set coml4 enable +;set coml5 enable +;set coml6 enable +;set coml7 enable +; +; Enable telnet sessions on port 4747 +;set comc enable +;at comc 4747 +; +; LPR +;set lpr debug=cmd;detail +;set lpr enable +; LPR output file +;at lpr lprout +; +; CON Console +;set con debug=cmd;exp;detail +; useful options +; enable console +set con enable +; set console address +; set con0 enable +set con0 dev=7efc +; set con1 enable +set con1 dev=7efd +;set con debug=cmd;exp +; +; MTA Buffered tape processor +;set mta debug=cmd;exp;detail;data +; useful options +; +; enable MTA to change channel +set mta enable +; set mta channel +set mta0 dev=1000 +; +; Attach in/out tape files +set mta0 locked +at mta0 diag.tap +;at mta1 temptape.tap +;at mta2 output.tap +; +; DMA disk processor II/UDP +; enable DMA to change channel +;set dma enable +; set disk chan to 0800 +;set dma0 dev=800 +; set disk type to MPX MH300 +;set dma0 type=MH300 +; set disk type to UTX 9346 +;set dma0 type=9346 +;set dma0 type=8155 +;set dma0 type=8887 +;set dma0 type=8148 +; +; Attach diskfile +;at dma0 utx0disk +;at dma0 utx1disk +;at dma0 sim32disk +;at dma debug=cmd;exp;detail;data +;at dma0 diagdisk +; useful options +;set dma debug=cmd;exp +;set dma debug=exp;cmd;detail +; +; SDA SCFI disk processor +;set sda debug=cmd;exp;data;detail +; Attach diskfiles +;at sda0 diskfile4 +;at sda1 diskfile5 +; +; DPA high speed disk processor +; enable the HSDP to change channel +;set dpa enable +; set channel addr +;set dpa dev=800 +; set disk type to UTX 8887 +;set dpa0 type=8887 +; +; Attach diskfiles +;at utxdsk.dsk +;at dpa0 utx0hsdp +;at dpa1 utx1hsdp +; +;set dpa debug=cmd;detail;exp +; useful options +;set dpa debug=cmd;exp +; +; set console switches +deposit CSW 0 +; +;UTX boot tape options +;set GPR 7 to 0x00 to boot in multi-user mode +;set GPR 7 to 0x01 to prompt for unix filename +;set GPR 7 to 0x02 to boot in single user mode +;set GPR 7 to 0x10 to disable swapping and paging +;set GPR 7 to 0x20 to boot from device specified in GPR6 +;set GPR 7 to 0x40 to allow progress messages on boot +;deposit BOOTR[7] 40 +;deposit BOOTR[7] 52 +;deposit BOOTR[7] 42 +;deposit BOOTR[7] 2 +;deposit BOOTR[6] 800 +;deposit BOOTR[0] ffffffff +; +; Set register content at boot for SEL diagnostics +; uncomment next line to get diag loader prompt +;deposit bootr[0] ffffffff +deposit bootr[1] 0 +deposit bootr[2] 0 +; +; allow cpu idle +set cpu idle +; Set expect script for auto time entry on MPX at OPCOM prompt +;expect haltafter=20000 +; wait for expected output from simulator, then enter this text +;expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r"; GO +; +; Boot from disk +;bo dpa0 +;bo dma0 +; +; Go to simh on completion of script +expect "DOL>" echof "\r\n*** PASSED - SEL32 Autobatch Diagnostic Successfully Completed\n"; exit 0 +; Boot from mag tape +bo mta0 +;det all +;rm temptape.tap +;rm output.tap +expect "[][]" echof "\r\n*** FAILED - SEL32 Autobatch Diagnostic Failed to Complete\n"; exit 1 +echof "\r\n*** FAILED - SEL32 Autobatch Diagnostic Failed to Complete\n" +exit 1 +;quit diff --git a/SEL32/tests/diag.tap b/SEL32/tests/diag.tap new file mode 100644 index 0000000000000000000000000000000000000000..1986f76cd3341610c180f4ffe671c81d481386b1 GIT binary patch literal 4144792 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%0DT4@b%WJkVF8YnqIb!EPSP+06XHj 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࿴oXvH*g($+f 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

-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

;!Xd32gECrRy|Vtcco1Se_k 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%0A6XQ9LyBKfQ^E_i*3LKv#j!#l|r@(PW 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

opf^HD*K&?zSu8qNuR`xn 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%0AeY0^hv^de}MGDFc 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 wXiPu{ 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Π#p3Mn@F58QCWaOc(7IPa>e7U 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�Cu$8#V&Cx)1A%p(^a2XsQp% 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�&5 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­(+2o7En($zi5VOj zOeVUMFKXY+spwWx5Iu4g zn4woJgE6BcPMghqJBT6`v^)rcIUkp>}>+2Gp7+72uZf$oiq#uh{cW1&G7!Dh4&A;UH-ZUp9w zG0E<-rjWFJU*$Clo6jbSVjrA8UQMDOqW<5H=!zg z;7X*dh!V7s!Q2a#!;e+6LJLWWL0lrTR(tm@u*W^LNS4rDu%r_okMXevkGp7IEm_LP zTYO-ku$IubaF@jg7eDTr$VW9Ftl%!H+Ph#Kc(6xJQc=D-z{lr!+)WU7_uykN9}zyT z=VJjL=n*_5-~D{Ij}Q7V?k4QJ3Hxq-y{8Kwefa3lM;?a#bN&c6xnrFVyRKlcnv9Qk zH{)a9C*`C2Q(U;AbB;Q=%$7=ZNng%I-q))*1hNtbL0Ev8Kv~A;NYtvzZH4jdyc!Dq z!326kSudFiCjeH^81aRIJ75roGl{#d8#!1_aXw8fiAYh#*h8huVwpkM#qcv9!|T&A zOu;MvC<}k!x0ZFG6<*`dke_a!)FZB<*#FcssnN121G_aK3>Y28xzQDJNut>><<)m? zYV`w>e-iUgtR=_I00YWryTB=fb;Gx*m=AkYa=B372}!89X31S+xubLkNssvo=F%ZI z#*diLny}o;4Ai?~KGedXZnxdFxog!o$qL^LJ{difOapFc=~?UCVFDjOzucQO@1edh;td9Z7S z4Ob;>_oCn%f7VIklYn`>d#~5VyT_)tQONGPSg?qJS|0Q>&kQmXbY^mpw@YCFAg{JZ zKA&PgX$Q^6+q|=Wd{lkEGuc;AWVJMlT^?}{p1Wtf+b1}c`ld?E&79L^bWuaW%12cD%NVBP#w~D*PNEhLU`hH7QIl*$an^Y%l zlcb-#2s`N~%^&=H9pjuD@IwrH7=Ep!qiYd!hLP}|3NtDbmZW+m?rp{3h~Qwui^Hd= z3eL-C)4>;lmb-5z#^8G#KHT8)W;lM`0kpXlc^1s?dPr}XjntOJJ%vtlV`!&-79VJ8 zcISxwrJ14}N-P`6pRF)rU`yOfx_)9U^VhO#hHEty$`#)b12$W4xJD3IR?VXzIInpi z0_*OcVps>rg4z;vCZYoq_b(x%(d@l{o!%gwnz%2=nw|3n6JidCgP$b%*hHZA)#waHMKZ0HSc#oP4;18mvLd`Ga$UiMKrpjQyA;0>a5 z)?2U(RblI52+q7#kb!`375cJcuvhUof)w6lBnJ({52`qtf8Tbn(z4?!bUMca*waVV zbx|g{0UcqH%iebmUUAPX%&?Zua`#ccJ?Gw8*c6Y?Z?g~A^H@U=X)hOo*n;~e!sNTh zQA2Fj0}xlS4-JKdE_MAMQs6ss!RjWV`h7Fq30DFggK41!mb-VYVL5We^)Fy%d0(AA zG#j5n*8SJ;q4^l&rS99tR0$u2-s3(V6ypAL`=oy0VpScyO;3H6xNjFZw?(fY7T6<< zAm5kSj^&Mg7%p(%7tR>#zN1Nr$J{(2e^OE(s3dyJS!P z{qTP2^kwyWjh6ysWaI}I_K@GI8DxZsFe%vI7IF*Nl~P2&f@A294NlR#|K;|MSrYdi zNU-mU)H%1(4^g=Y|K;$L&QK1{`I?%^nLCI;ymNXb9w-C{JP>x;gpgUQeM3ErxhRUj z<*2M>1``CuonzwVun#P^eH+zH|hJ8(43V1C>kO6e9@m^xy=Bu{{ zu;mxiIB1&(S|E?eOjSw8wgr+d$5s~7(4_EAujIp>?mh64S*?;{QsPiz`B0;q`j1wZ zdHI(2AZBZ!-@&jzK8z5|kbS1!6NZ~YRPVCc&@@L94}8!L3Rn0jAeD~7@>qa^$BQ-D z*Qr^i1;A&4k3~I5v%J4vvq`#f`5Ssown_co<9Qr|xt{0!pt;R__k}4T6j_O4dJW+V zMf?F$eiF2_yZ)4CK|pQeBWUs;_y)UD_&3HR5k!r)hs zGO%mITK${zBWqQX3nR!QDRADZuroHXYL+=|U~|(7+j*z|3Y-R22n61>R!vfM`>0ml z?Z2`ov@kwnOZK0grJ-{^#3-;jg4D5AIB<|^Zdz3cJTn>(>IS{0zU3@f)b+3Gf*q{? zP-68=GiGyPR@J|(#%&Xlsa!BW)(f$%P6l3YL|k>;*>{XDU%*x(P_C?wQWc^mlo9c#rI1TC-|`hTpbj#q7f z5?=l#Qmgy3nYm0^bUgwR-@!0bKJr-FA`$3q#9=xuOhV&p)m=gkfn$I7?W4xXK>76_ z8k`e)B~k*r?(_xf+j{ji21LR%fv$zsMkA#0#=qvLM{|9v`p&M9sE&sPYuQw1q%BzagefEu+VZlBNC(qv=wp^3&AJxGeY12*!cV{MLps5oSUYaiV$ zS_-L$mdKdt)1?M$7vF_$diV|f5W%k61ZB2rKiI=lX5(a3#m@&`b}=i)*Q1H`V_7?8 zVtrSm{!Ge!*N1x97NOEx=~mxjt+_`ppACO4|BS6#uC9i3tu5up75ZTyKosBL&-?W9 z*3g;etGAtYuIrL`*IIKaZ9q6(5-7Zy-mpVxf*HvuNnAl7YU`r(xw|P^z#iJCDV7c_9qzj;kRbP}>|$04~~1gpeXXd9Z8pZ&Tls*B$|pLE7VU9Yd<fccWL+lpvvau)<4^4!Yf;@R09)r~?zWlW@=OLm6a5!j7;g~TtRAE-OrciIeyv5&# zoy<6@XDc%uw$|Rt)5;gReKLHMn(KW^ti4s3N))gUcPUqkeg$X`9d;fy%=ge?GisO- z-8%XpO$AJukwtF>`_gukg=8MDag>n;W~E&=IflJHsT;URT?-kO^IeX@-RtJksm0}V zVOgjTrGEIWDUr4wWKNQ&M#*JAQdWr7Y+!{sE)^hUux8jZss=P~b3CNiY&O<3`zM_+ zDxnHt6izx>8SR5L-(%_wroNprOltsIB>tKFa}Ux4vvp5l zieu*+roacS1|2h6;V0J{QKw;;{LdIdBSlF^h4L#Ho7&s^nsh#>NAqDD z)b-w>qK_O)IW_c=X1&pz8v4j~@6=F}!bt~>7+L&NLn%HI{o=>Woa7)-pXPPvc2_sF zN6&+$#2wr`n?mHaEcrlC$OILdtoGYvLrH0#A!OdMi%se$UP@mgsZ8Zy=nVCJ%y#wp z&g#ygZ+Mm1e?}qF z%7^2BGqCaVE#^Cu2DyCwC4Zi0P-Zdy%=P=EChvN66YAW#jx~L*SIUSBa&vi{t=+(N zNpZ;7`x!jOMV$3wwBTGCsAE_K8}iI720y>;|2)G81`RXT!hnf24U#W_J?uL51HS(O z-=D$Me5QIbwTP*6^+WqZV(PeZh9;A~8?I;bPD90@K2##&B0^s_a@%Xjxpz_4SBS+L zrn*T=f-9U8S8TY|hh0DD9(6NxEz7r}6#TJQdYfNcLub2-B1ib$Jp%$HVRm(1BNQCD zLWZLTrerw!0aHCWR?KJWT&5Q36>L9D^i~;ST)j8w-_$J}Z5~Ge!Zky2O1d% z(GMpXZPVH@)5X5r;54rXAtWj-8X&B4!4 z_;WS#>32}fY`Ew)8+$Iyk$fX|aV&iI!=4)qN^EH`8}!@VfTf4V;C))ES7PH@aL~rt zVvwLk&C<=db>RxcA|13g&N2h7SOyXifdl^~o=7_8l51W9pf_xi>B;5|dP6qU zkF-1Y36(&lc=zZgAbTkB7}lslp|61}H)6@p+Q?OmjU{}*wy`$iG#hIpc79qLXXuBE zr9^WSaS?x55d)k5}U5o@B@bQLk5Az`|C&d3o4K2P_t?W zfi-if@)&Ks>3-*r37~w)+Qj99%;ccHf1UcF^DN7;y{^`NB^>&y$}eQE9I?sQ23~5w9 zVv(*;xYF|GF0ges-f4JTKbkFVeXNJGG_i3Os~GPdg9jEfM4a^0RQViq&7>5k^H)wB}Oro6x)z{z4|fVkM{Fk#MD&2W5lW{ zKZPm5jC-x0z-(qgh<7S%?!pwe!94K=Q$Inn#6qL`IUOn@PjJ{tJEEQ|E0Vq z-~$;iMe+6ViP+{uIq0%+3g2-h;PD9MV6xO_ zB#~B{gQFr#d^xB^Z1X~Akp($8ND~fYa7g-Fuacf7eK8JlCfr<#v2mlrntF3ZuAgf7 z1!L>bt8fs6IT@h+hdjkhoyT`)GS%H+FUz=p0$XG%2Mq)Mpqlg+7&!X1PS748AFdZ@ z4M7*1lOkZpn8A`Omt8%r`}jxRu=)5$)CMuV(G}3&J8P&HKqGjTI-yaN6tA)maZ`x| zMo6F34Xag)xT=`tRr^GLZdat#Jb`P5*eB9Y05FBxM`}cLUrLQwrRzp1MLpfTdeD!u z?U6at>H%RW2X(`~s}@V0KHWP&GGvOd$CJf+mP%`yk zumtFFb|SE|7pprBSZFzPyY&Q|9fp3JaSuRinu2@cJqOx{OWSA-RMrgs6x}_;)myLW z(D_Mvi@pf>si48AMs58d9xm*fVZGH7eA*l{5RWF1`V1WjD=Fr3Om`?xDmM#+ss9KOzOjMe}-&W36cLJ>&v4FVc z0HzsREaMzry$P_6Cbq(7nP^VELgAR%l!6Z+tmil2<|m_j4yya;xNx`2U}~Ebe0}U4 z;^Ge9KG8s7kk45C;=%@nxkSF@G3H(iwE$v~1nk?L{BVGFET*m2mhrt3TU#=f1Du_3 zKl)@VIK|qE7{DaX*xDXvaKzn)6L4uqd}3|8oG9YlHmt6J3AS$X$+wl{+jgzY;iwxl zi_k#WHrSJcx)Jl$1N?@GF$em#)vX67ZQV)q$TC|Yocy`P+PVz~OKsf*&9ya!5s;BR zyR|VL4fNvHUrH}}eKN3@TCUw5-G%_j#MVrD^yIy`)ic6;n&9|mGN?-#7k16S-f9J3 zFHNLS2}Ix`0f^R4`Sn65Lytq&wz0j)X{4k)K%(s-3=`XNu;tsV`dDK78gARl4`V8v z)tea&FJAD9S_!q2)m!x}V8&0Z?Hg6zHaGbO?hVX32R(M=ENnHuQyIaE{ zYx^2!?|dBG7L;u-|2skcTiv9)?(k$MXQOeiqbATK4A>cs2lY8S)hZ+A>nY}k5>MuU z$F`s8dP}Th3-~izui)3siS2_(ne#AAJvos(5m>}}k_Re(`5Cbv@e;afyTd7DNH5!u zCLgh${BQTz#7CO87a`_od!gGWLq@38&OJD=4upU5zo|dO*~v|9$9~SAg`C@h`ra2V z2^@P?zVIrkz^^Ms%vu3;(HJPz?Y-5-EyNE=hYxY~4gz7Qn`#E%pw`eEcp9sGNviaG z&riOGpDC(pH_vaBZexWftS4ja^{^oYm}U)#u>JmCi5+1Oe+LLN+c`L?8JWpJUB6js9SyRi3a17YcIlPaxz@PM(Bz$sG}y)@JKK0cq?;Wl-}9uo zr`}QC+0sCe7LsHL4$a?r+@s5Yr`1nV&z9cR&pTWCskcmBunlm;J}$@Xc@!e`)ObkX zF0@!CFHoD>1ul`=X0`5P`v*e%4l{OAK%8I*(CAqUkX=+39!F;`t2O6-by zE>j?ZRhwU8=-+jdInLeLW9?k+0d*S$;=>-g(v2cHl0dt^Qphe@96EjoHSb!YaG%;& zD$MVDLnlCE1H1mbe8m&?cP*hWx4Sw+)XAdI@ejqG0oo}<-3+vM?ebcb@`){as;{do zps&Z6xO^NW4ay^G+dC`uRroy&?1p}e)du&ROjP>?+?dC=={;*h1E5RsL+1e-y1D ziI#hXf>zyeM%TZB2Tov6V&{-$TD(p?yuEjRCX5!B~Rn; z3GVL~xva5=r%nVF6_H{2@?va8c=|l?VZ4d)@9Fa}2t9pHIwI-Sd+o08_n3P8AA@yH z0P7skrHmaC)P9dUNyJ?(9>AFNd%v^d!OiA zg3yKN4Ay*jIe|tFv7)Bf4b5nj<249!FyhHONiwvHYR(<2nu+p9UN!JNu}QrRXlMql z`tLx+YyeC_PZ4)dLyh>I$%lsokqok9p%XJ{DMNM;Uaaf&x!S@RHg6UtT?hd)&!=12 z)vY1|P>!Sk6^z@scde)Y!j8!6mDt^}7hc4qy@w0C{@m$mYw(@?bbg2;(CsJ&zTLBR z^C<_uJ#$XMO3!vlWu<5Pn|9ato2<5ZT(zew8iT5Q!b0vv$I1xTtI&w>vpGJAcK^3X zDhSi+jkJ8h@wW4cLFh`<=<3rwUEN!zmqFhf*bV1RP}`vs@QIp3Y7w>y#_MO7CZqjH zfE+xbM%}Sb43oIH9<0Um-8Sfy*P#GbVQ=cc977 z+z*aU9#7jMos8+@#Pl&xbk8RA^qy_#y`L_T{!m#I8#z5FNS@{#?6PM|2!Ap!3U^gc zW2em?x(4=aPO9LL_0#_7`8|#3d63VH!_=s(e<}I`U*5I$JV?aR7e8%D>wyk`613^> z{)LLfmf>V%rZwi@@SbMpd6{SQcxQ6uM#NGv&*+q2&f2?++rF*AJXF)%F z=vzMSg&ce7;oiFdcVcA?#{jhVas$sOFc?ameY*&^-9c}Qi^wPnv#^g_=Qz-z;On3P zDD2XucF4=>*Z10 z)a~WYGHdz=FsJsefwFt92eT_@S(oX*3Ep9`4j1*guHT^dX z7lVP^0t^r!5yDn4xmMx1u8bE5xjaG#rEW$>RbQ;?aX7?U3h=$Sl@GN&SIW6I_ETHW z6=<9x?r5AL?zp@-@I3WX9jS_72X$mpiH?S2ahypmiJFJ3=avc$(P{&`E+?+!bP1C6 zxyBT-K401)S)W^i`kyaNA*=r`iHP1i;0CrJf=Hd|!mi2Lp`PPg;JzPJ6}~uPJul(; zoq_vvzk~zSrXG*!JW@fWK^JbmVz|=IZ}S6XAy$%KnsB^`~=9E$w9-Q z`_%J>q^QB*j(+ZyKp-|NK>`O=ThD*nS-%iboktVTuQbk-;4JFVZ~^fMn|j5E)_$I9XIM@ny98{*)Ocie0Q4;5=! z3zFd7aU7Zb{Ly4*j_LE)0V)ZqxWC}#!nQ;3qIP!~ajDY$i7&fn)P5iAzZ*4{2C%d;kxt>1@`GLq1 zcKrnv>V?!yZYZEvzd2OtlYawmw7f+~r^Mh<%Kgzq3r1cBdmgb`_HwNzmzJmr05z~1 zE@)IQGBiYTzm*bH)_EKQ@YsnhyyU4M9Bj7gJQxE4;;uFrCTPhK3Zdiov13|tTw0O7 zDi{7IOwYp7XZ!kK<*EDc%vdyZgL=vNEEK{*PAK#yeDpZ22@i0;RXxFZClq=CDIA0H zj#d4(%I#yiv{z!^Y%tS4EF2o{c>$X|?jZ<}bP)9GzNK7G%H^eb=gOU0ycOdJ&*LvF zBtqfL*3r&aFN56sK2PbGBVR~0&X`8*ZynpY54YZ6%7BCY-X{3L8WtzlnD)KQJDmqC zb3Tpi+vSXDGT^c93vO_hHTD@#JddMw`-w0xkuLc=1O`)Q-oJauW_pKMW0QJHU@XZT{iLJ-1kn~sj8WrGQP$bRt+MV~P+D~^a zMVcbw5yqp%vA-MYAF^IJ?)AQ@v76Jp4pBz$uytT_?g79D2mu4{y(~+ag&&;N2E7-@ z`t7bCV5tLXq&@a0=I$dEy7tu15YPql>jgi2{Kf03=%}k+q+loa%*VVy2F26f@&N2t z`lx{~!a_APuf=&)ud!u*l30VCPX2Z~yX_9>IXSw1UQ(OW~4)SofTmr zuJOyi;)whA2dF_Zhd7#e>3S4;KUY7~0;zmE@sb?d2R* zfig3?6uu|ilAAz}eR{Dzf4gs2EEdv_cwmgf;)-tUG4mN-zy*S zX9z!6b>~m|a9?SW?60y7uZ9hZ&1-?((;Uj-_#NlYdWpB|-TCy2SA!KUIPqOM7}80- zZ7N&K%6LP{tJ~0(zIyRQc)y&&=Lt5#<4>c_h__g_4DpyV9%%RKd$Nj&fkO_m+TYZ{ zP-J9q=w<31T!nYqbw&itXgvQkvC|6q;YP3C{eAdT25f8r;Ss+s!2Nmrd6fO7Mb!xx zN_}d?k3edkEzkvAus^18WG}-i1a{rPGZjKAcp@EEn9w7Cw)W?lN)ILWUzKK=KMYCUGG%F{mrPvZsqpd3pl+B ztGukAVYWH3+f=4{GATM6+82B^b|m;3|F|t_D@OpRpFu7{UgCO`$WuMh9m3 z_$6JgbD&-|>{AU9H7}wDQrjFjJLr?&srP{U{#KqmcBXLUfwhhteD}U}ppn)2b`A{F zUHo*^S%^=VE*)r8gBlGYukG_8Y z`du>JCz;w~U{Y?g~M!iMsiS>^^E$Z#u0uia0oRs&{2{+MrbhKaBZ7ASCU_|+m&5W&2h;!m7>DJP4yMa%vJ-vtoUQZ54dV+=tdejqb^jL|aXq*6Jp zpif$m$Rlk`SAk7&jN&B_Ldsx6_j2|7w1R0rJp@J?1VDjURai%7psy=%^0X>T#X{OW zL(iBogHi`s!QBwxD<@iM*}i-U?E3D%RsSQvJP`RaW{|6^a9AY7G02{p2})(gjBp&S zs4B;SSfU!ohp+_qunN7SEz7!CS@jC%idnxHc6S@9KFm;gvO*99TB-<_Yk1Y1y6`BLGleUoI^u+@ zG8+%-yI-t6(y`JQbSv-6oE(oC|p`@L&2P+3a=dXscAQwP#l{?j*rgJ6*#aIN9j(g#v_)j zCcUw!`vvMxX+0aXE?R=osV_@bs4JEQ>#I{DvaA{n56x5h1jK3*wqv9D6Y0GLLcbL%JNFXN*>L-El@|& zDhYmi`V#{bdlVXHYIRIklw#EPby$$Qy_Ba_AeyLw2w|Aaa6D+pdQ*LTiXl~CdT6>7 z3~P*EQQU1?mRTpTX&lLcV%UkrO`mi>T^$9_PsU}prMRCq9IdRhVfJLe{ip`?LUY4J zf@V?-ng}=ZM2gfUCuJ+oKIr}xb0Ue$)Ff`Vx&zlZWgN#RW5${2V&TvD!~Q==~ItQXb)Cb4K* z9l_6_HrEt{#KPz~we4rBm>|6)%mPt!VRwI4{aH_oV3>5mrBPj44t)}iI5_h-8jok9 zeMLeluy*Jvyo5f_idyXu`Dc`Xbm2JHK4?;(LF$Vz9zgWD(hLI% zS5@1XWn`uVK;nEoCfvSB+#X4-uuJnE*Qw7jyKp%wf0U~>{~=W zGL(D$0!mNNp_@aykT80$>u=Rxbm(JiWP2EP_)dtAX$YH)|ICRmHD)*-)MdS`{+f=0 zncoUr4BVLhaPCwb1sj4P?Re3tJImPRX8wYywl~|AmIyP_Mz7DBrT&&NFQy^sime$H zh$@&Oqba=UlX|rKi?k}`rwFr8^)Pf5Mj9P1E5~>RV+;4dm7U6POsm#YFc>&o*xj?# z-@UQ1I-*O$6<{YABBxM^9n|Za#9`b~r>o=+`0~n93{ByfirZi#DQIBVbp3<+GOePH ze@=kVy9^i}HcSs27M`SMa>N6qD#&l#?zpVa0u%!y2i-omLqP#gx%d+*uhOuth*o-o zyN`cR@DwSdKc&`i85CbQqxIzOVcXKBlOV*H9^hh%Xv9e(-YG!(ZPlLg#zZkyOMwQH zbf}3Fx&GF*+S;w)Q1f{4*S5m(%h;5r{-1q;w!dR<*7i|7I%B8-d_M*1T7i!%9*t_) z1j$otw@~l-4K@m{{iR0~`5|0ZRkm_xI23(>!1@A#5MmsQ(i%9{{@u05X$< zx^AuZ>FrQ?^uGod`aIh<)~CxnyED6V%)bU0byr(p1TZ!UfF}oKc9*p7%HXF@Wbqd| zm1bIUasxG}*5k#lL+mqxx9z1|6LSpOqoYxHOkh8Wk0{w2*k@97tPcqu`|j)rY#_ZiAT*O7MD_S)0oJ5S-l78&FF$|mXR_{>x2xS&RlAI^Ni&I;ZJsU#3^ zeP(Fy1jRc{v5#EXHQmm(yKy-nKVJ;pq&a^GD>b7+SL@KG(AynWmGof(=0g5Y$Hb9h zY86X&tOBw(4(_nK`z3<1VX+iA9rC$7a1EhG8`GjwF{udZ1h~8WD#Gz*>Ez^>_L z**!4B`e&A649XKYKk^tgt}lsIoTA_TcGvcL#O~=<;(OImQ>stCAYKK>D<+msMSiKC zR*?^zJbPe)E*M!bT93*bU!X6V5+0>5Dviw4KZaNIyoNi9_EU0&s0v1aGAo)%u^~TjXA0!2e=J~Tef@(oc*{c3XTLgtLOu{G$Ou$ zu%-3z@Wq#Dv}vHu{l?|rP+_fxhxNsm6;&F&*n5Y4md>qi`&s9T3!o&LtDS1Npa!D2 z{f#goqQ)X!nOjz_b7z8{UcI1C6vGkl=VD-_tW0BF&-W*I!Y~omy^(|3p3CjCeKs}> z4cVc5q3a?VUB}ck5Ic&osCp7sT~KROmt@DmZKx=%Fn?-Y5U-x3gLTErhFy+YFtY+7 zF9T$E4DQ|AK1W|pUW--5FfWQ-8sRNkWgM-kh`>1Tkzz*baB;G%x^xo8L9Y#fGf|@* zn5GaU{>_8bO`<}XMltjv7XdKJK@c*MgW4WHwELnnfkq{6uG6F#=R-+=+K|aZuv|~Z z>=}y{U`&G+$&`wvAro5Zi3cV_K3#geX`jo99V87iBaLN~2wi-vZDKeL3xSYIFnCKQ zn+YM<*9jLzbVZ~H9>a^}kJ~&ju^PE*F|P8YUJ2K|mGL zL_FINq%wlr*Ct^CiNy+tVP#;P2|?I*EbO(rw&%0)( zkI<-1Do7=WOt)!CmC!^0gZV%vda&zyop1MZ*$Lh3X8?7;PNh&GU{Jt?(>?-zjfc6i z;BanI5&>71psPD#kpge_Eb;@b9;>Rxqr8j_r(dMDXBYc?ugll~mpVyU5FZdES{Bih zN}$^!CDcr1aH>b$MKyTVcu&2{A<5k$Z2>_F0+EVW0dz)kP}lQ1%ur<hVoEheYz&YtFZNk&5A>GiVKG79 zyXZsTb94(=*+AT)X256%SZHiCj8St&3`0*5Ivv=ico={==U~(Ez=|U(;1COq24tmz zp&rfadjG&4qzi_!IhEzr_LSnVHB?83ir3hT$rZYU7d8UyDA+r(sLn6Q9i?;g^K+CP zED)e^r5ei_pgDB1hLcB%c)q=17#h*^m`2ml;Tg$6eeZF&?ZgRVaH3HI^9SRh#wZtz zvcpt<;Jg~0L(YfYq{Bn2(G}?Ez=9{e(-6#0jS`r~(a>@Ep{C~`dk9ujAipJOknvi@ z!N)oZK6bg-<-f2VH*)ki9nJ%Hj4Qx^8RimrEDwV~Wfhj4oGH<^CB}`rh$Tkr(HF7A z2}#dO^G3E_-aVXoXB`Xk3M zH+&JJrXY6_8mgmgXo`wRw`piHIF&BVYx^v)hZ)ZTSQYX$84?6mbs*bN9Ld&LpihS- zanNWeAucbI@4llvh{9|mFTBWS`I8qJKU$BukVuYp zrNoE*s+~`XfxwrRW5j_8(7p&>4b=nFGs3aHNU!toc4E%5uK(jJw0@o`X$(0PWZFdszk zo}BU9Rn~r=TxpN)Kyi;8?dr)uuBrLj_8{7X{urmnLZN2Rg8*&#p~rB03~3I38#FA& z{wbLhM~RVM3Fu@OATVoBhM=BMH-b+_PZ4JJVAu7z+a4=|5pZ^z$>F-Z+MVyD7<|S= zn_LdV3-iPoFiVmH99Bc)VA?6hlJe-%d!&s< z`jb=EmfENAg+);*CtJCoI)_8}QFIAxOcD@dDZMIKj;*x092?kjP&+~HkuaQH>Id`W zJ|*^e*Q}E&y)|7l$FrEjBZK9xQ7|U3lFa$jPz{F-8WN+?&q+WjCYL%AMzJ{7o#FAA z6jfNd^TMWp89KR))}U*X^}fNLK??*B&-A`+#|ROT`YR| zU+6*)101Ih$-|6m7xlTqz8KU<2LpFogzM&$u<$6sb|vL7IR$lesF^dES#+Az_*U{v z3{W)v%W1lBh(phEx{iKu+g;cDm-g3ab3@N#4(-n5X;~w>44qsyB{!88w7G|ZqNo-D zj@4LBWSbymzSqSqoZm508OuRmdt#dgV498|FGIi!rc5Rpm}t7p$7nVU?I;~9IaI4VMRx!IlTd_jqxxk zW(`j2vMI*h<1;iY>Il4hKuSawb9T5sbp@Ra?)tn;ci9thNMf1zVc{ah#ED~cUGJCd zZ(wp7NhcvX8}VOyCPP&*_eW27fnaIVU!x7O|w142m};ZYl$Z(VCRGG#WQWm%-tTIbYbfi+X=yN9+;h zVaxMvAU47$D(qs^iMciWHPDT&oQwa0f{b28gbn&!%>I}ShqhJj2F}JtfK}n-KvzRQ z#o@Wr(R@}74}{z9+OyBFCn4SpE;Yn_pxfXUM`ul~h8V-UJ;4kV=(ZUZUx&#E;}|-{ zsnCc@pJC_EVB1ld*F=#BAc;H>5X8vBl!{K^tj$5V@z>o|2!PJWE~@YOqK(;I1;8L8 zV+PdzaJu}bV7_14*3nDdUrJ`HLa=bJ#1TS8SCnBINm@D@>RBv6NsZLN0*g{@ABGoe zPJ6_bO*!r6X|LQV-W61#^%I5-gAOfMYfZpUnpo;fOt zm;-+t^Dxp?O>=+C%S<0?82lMUy0pw8VDXW)dAP9adtPf#*4YCG4%GM`Xb;Q@Te%qX zib`}C{i&;?6NX83BroS|d_Wq(8(0A2&*|{yfGx2z0`prWb$FCSaWM%toXiL~8AZW| zd3kvn|Cktwjo$6s_7s@F?n`_@75r=-er_A@E%#;cIVFXZkHB=7Xt$1 zA?ee+d)zLTZ#JCkmLYml-k=oem(+G403Y<)VP9B2_iI2nW~An!!Y+#&LG;K4j>$+4 zYP)T+W2x08Q{TtH4Im=y8DYqB01-a!vNln#L6asVQHZMx`19ye-+O`mO}+`kR|QBO z8h+qqGHbw1Ra#LsQ+O3SpTO;=8%n@BI?9N7o&cmuv?>5Em@PZh302kjVxl^;<8}@r zAcY?qdd{;ifr5$7sDP|s$k5p%@iD+VoDEY5Pz=gy80=OoZb0{Ne96|x9P}d!k4i2K zBnvPIn(bK#%%ejVUS&k=3hessSKB2Te#!}K4L3`K<8;+$kJPBuuNF{HtN#-Y;^YEL%2FdkH!eUYulxL~m)nA8vl25Q8O z^3B%39@Zw<4GKOUH_BY56j1BsSc#=(j+IFZy*0f0?)Tbd9*NQ2F0tA1#vN`{kw<}W zIhG$}WMf94rmX@xmDo!#y`eV390t()K%bNp4nm)&QZhq1=>Di(&Wh8B?ujF)3PJCEQ^Z5Uf}gLh!wHH&kRaGaLeju)S%dqkot%(O&1^^~%;oh7 z_{?i}ulMaZNhzOFc+pc>0l6{K!$8%Q)fHgKID*2VRA8IHEVkjTuMwdke{ z2CXpEsi7asc|%@ia!}v>O1m1RHClxME=Rc6Jd!neo<~tJI>4Ng#U3^xd3ehU3MbPN z#whr(v=l2Vj*KKlo{ipPkv)xUD1yvKQ7LvYleR@gc*t-twZeQAlY^9J)IJ7eT~so) zLdMAs%Xzco6xw+FkhRU89vBU21f{ufGWz=bsq$bAWux6W0f9({Br%4O=F!W8-D|Er zLl1+=5PY&B`bm~TS{+z1tCvsg7!%EqRG0u<*tI>*vM+B7+Xv%TG|VFd z1_bh0O7zO)l8Bxjmpv8U1Kq@KlWK$vNTDeA7%&vxZ8u_k{tftIEw z2L_`@h7{N)1O?jJL|P@G;%Ryo_Q_DeLD=~4|89RvR~B(O3cxXql~|UvihMC1YzSh= zki;GBaZE?=WKt)vdtPYI25U&2Zh&i&L|2q!s%fG@+#?wLV3lMtpsUf1Zr2$xP1adn zpSthR>~JRg59+$!YhNJ*mzkN*IwBH47~+U`B9v|yd(?0xQ#eq}GbxhM!|Rit3+->G zQV&XmWGX8UBSZ^vEf72`slYqNZ6&gQHiC7h7#L8(PvFus&ODD>QbakmYJ)dGyE2$< zf2X|+87rFh3a7pE+0bxP*lTyUuh>`m;#rF63k<$+4D%1LE?AR+a$%SgSTkqJ9T0`k z=Hb?xsy93a@OdQQ79;+q-CbAMS9O>*9bq3yA23?vW7?en=%WHR* zw!a%>NJ*t*ol(6>H9$Se*&#H?;rsCPV=h2vCI@HEw68{eWs=Op^5J)0=a)m%Y?I%DBKQwedZqG^k z*51#Qirqm0v2VW98*2mZ6e6(q5s{AVae+t{6c{W}mx0}TvHd*-olEM{u_!}LivQm% z9ASqt3?R?{%vz;t>`fG*_G`_cE;!H(?4DiifA``My$ajM_2jj>YXfl)C9f_Ixl{}d z?5sEKxk0UMJEy%4=8J(DtI${30M31>1MH1s@TU+Wo}@iaoGwk2pmdqx7I>*U-6 z$D8$Om<+7YA7nlA#pj3a|6$jhyw>WttNC3sI8zKyMq|?_-EXvOJEU>&A%)ruiiJf1 zwsk|uJQj^Zjh95GBkDDYS@UHUnhymv*ymUSyZ2PPE@<~jYNe+XFcH)4_e^`WW>iIR&mkttX>qK&lQ?et&1ZW;dLqR-qy6NJQsjT8;p^(g-*5cK|)5XWHcP z3?~eQnaM#`jXf`Eoa`7XCWM{_6R3f{YcGXKHjM;-9+w@bC&S|hbDmAZnLF(3(rWec zblCh3Ke%)OP=Va>!|+4Tf48qsGh^EO=~;`xP~}ZLy~$?jWL=eqs4>UHsWSS{Sa5B| zqJSS>w{MVk2c}D!q3cgiQzq<5o$GfQ<^W#LcxtPIsikRm)^7XzXlRmhYL8OE%);wO zV;i@fu(B@cRu{Ufu-fhKo@d)PvfZcdqYSdJ-NUh(ZPs3=Bb=BUr?D{vOThFW!)7+_ z#f;>jw$DfQO*G1}d4xM>%z}8EgF_G;$R#Eojsjmb_l0(1(K-;9|r4>iGAEAWK7OX$WG zi<#>sK)oVjW1$nR#hy5GNDZ6>!RjUaV6r6%jyCwWbC}VyQ^gyCEi8z%z>Y!KPEmwD zxb3bz`vLnFxO4msJfIpV#syiN{iLIL*mY19&PGAPsx)gMXghqEl^Q-wYz49lu>B8l zc9>i^<=pll@f?V^pbp}J5L1h_ zXUtQJfJ@+gFwVE=3F2V0q8IkfUg8&ASN-93a+o39SbTRR%zXo>$SV?tP=Y+ zGLCHW0bUU-JYelQs(3IPSAA#=o7E|j-|Tn@yD>6u^h#2H(;E&K1VU37Fzy8`!Q&kP zfn0AqU}q!;b!Ro(w}Tf!VMvig2Tg)x0jpTN0M5q-EX9ImX*3T3@+h5+nJ;9e(!_PU{7`@PB)btU;8qLxsL}V6D^+=^ zf=duwiMEX>XP1LRz!AU=wQ+?8eoE9PR+tbp#mhapvfL`Q>BlawfSjNP$X+$}Q_ZMg zhy~0=R|e1NY$pPYQn0|O6h+b4G&#DGB7hAj2-jfb3^&=x)PRv*kfG^1ubS&{(Xu!e z*wt{%9E^G*gVElR89p-OijVT?zOU-6kL~$jXskhq>yrn#=mNkolYa;+=LIG<%e582 zYnY%`aD`FiGKm9&SO)0_oVN$YXN*x*Igr44Ux*PY4c2VVzRmt&z{M(_jy3ID6PqD| zSMDppbrh3(ld*(?h3&~+f1mY+{UbfCyu=GFYQG|~ z1B2@2C@3HS)lO2x%HhO*3-riQ>67@9MagWBGE?FC@F*rlKz z!a;`neo1gP+@U34iiiWZK$`k;{n=s{PsuYY{5XLJ%UiT;1bbQ9#xJ33*j+M?l~-|( zkQooU&#`|@I|q@$BpxCM;EJ7zWy0{J3M}6toLs7t$Re=`0`D{&&*?^mxEx$}8P`+b zbj8!PCH&kj?Al&;+IIwtEy$VVeDf9_=)Eb4pm~T|5YcuQF--Fii3UB0V9Uxpr^v#F zQ{*nqD~V%yn5jv572K{vDT!X9^QtPR`0eg0>KegN?$JE!=XR54TYAJvX?(j> zv-0frO|^D&%c_cuh{o~a(LBqs7a5DkSDVoPfgS6P=-}yL=)AysI%#g^!w|-5!pV!f z#{2^4%*KPP5%ywM)h=9X7#xzmJ(py7w3}Njbg>m(zmv42oknG8IGCt&|ynm?_a zhohO@Pmp2^j}&TXLk{h-r^rmZL~mfd6`(~18_wEeFA-Y?qUZYDDD34D;VJ_Fowlh5 zWwp_eV)I~CxG0Lz3|xxMnXr{m9nL{6;nHMKHBP@pP>2irPxf6Hvyyj%`KRNi>7*25*8+RPT{K9T2Y&wKZgAoTx(%-kGq9qC&2qp~` zQw1j43|M9!&FjxzXx{_72y`k%Fr%D~IUKu^WqE}myRgjMs6BwwMF3~)Jokji;j(%f zo{Av{QCQ(}#K%@nE-AOMDHawfEOE0eh_xDKbli-Y$w9+e74}kC!co>%v#YV){W~|!)w$PPb%oBIchz@P zPOic_f|K^8u6CZzoqJV{zAX2q5xVB`9ER~u!eY^7*#mRz%ducPiCtoN@!Y7rOi#_8 zcb#sSQ**V>$;D>FqN$f<>v`8T%+WPh=Uh(sMOF4BltV~<3|?s`62DBNNP|WZQzL`* zb8T#@nbh`6Q4z}&MU%b=?3#0)weJ&rFc3<;0NkeDqAHelir5IpDM2HAT+tM;Q#-iC zq|D^fHnj!q{^|t#em$)!wV{YC@yPkzIdk<@HCJ4#uL4P6E5`_ba%ojM{Nh-7IuxvM zmsF&`j6p42mM!hBKQC%OkV;>eKSjmqxbS5ff|zswL6AVBcWN|xCl>}rNoi#|S|t@F zX&7WC2X$Y)#9of0BBqw2)zF5imDmWYomQEOXINFHW(r#{-YVK;0&}P1jUy=qZ+^QX@mMQClfjy=7z1nv+i6S#?_%+j>Inwrl*zziG_!vP)~#>w;N z2UV%l&E+`bm^Tr8O>Te|nmE+b(js)Q6S!NP?~?eyI~DAE$^GyceN!CtH@Ly|Rv+ zb_<|3id!fTC_Eqr9+Ju@geLeH3Pkztgf;j%R0i;y9JjP^H-8RBik#a+MENJ%q5+lW zV@#UPM+P5xLeuZ46WJi~b5x4zJ>VBr!*?w$n%Jo68o@MiC*R5Gq8a2~UI`ooG>bba zN=3<3*f1~mLFQY8yOaa$4=+!@*Q^sgmBjcC5QuLCzbXlwv!v|fiC8YyeIegz$1}=7 zKK6*+GFb~0iYVPsbzu$wRJLfORuFjT$3Ivn@sIyE zlSBEi$d>BvPiXq=ipkj(rG?oA7+6rTvOJFRu$o~Nco=-xlpr6R`O7YFxco#q415ab zF|9-THGM2F{}>3;9>qhN;lxCEiuUA74Br=h7fbar7RCNNjF{Fy&6s=Gc+8x_?v;yW>-K!jC*^`@ClD zEHR|~+MfxRVtR$G%~URY6cxupIN0Cvod>(iw`B4ylXXK8pF6!^aQ#SnOig^e@r6^3`K}JkQ4)7%DrTJHV_Shsu~N zuc#=PVxrYUUq_zG!&Exv(y>s3=}mRrqME1WDvKJS3e1yY$nA-PVI1ai@eu^(yLLbU zYjeyu@xo|sdgHJe$E$dh!;a|*t}HSE0ts-O3lrG9XUrW}Vq|Qu0@$V*wy`C(@ww|0%0-A<^ckXIC&8pmdWs;XJ>wj<2`qMigW!~C6MN#$bq?g*D}mp0_5J*b6VQokMlj---$sh+55eLBMB+oZK^vFf;bt*_8-LBHCy zS{U1L8!=Yq8A<%%=kXh(p&h1(BlFERxL=3awTpoVyMMcqb~v&Jdq9WTwTl6-^ljU-U2ja26h1+>~qoY+Mmjy82jO{bA+@m`Qu(1H^mowCf47)Kt^;bsuE1|!c$$MCVSd))x#RA!fm>_Y4-l(D@JisE$H zP^M+*kD+T2Dmxd&Hto!lr6@6nhyD3Mb^q_+JF(a%RD$n3@wN_h(iG2_bp&=W%76yR z%g%)<*jfW_e8{vjx&Dd^Go`3pSI6}Q;D|%IW#U}i<0{U?0du=ds=NP9QyN6qwi1i8 zxb+47F|5$X$^v#MPG<)RyH)5)#g>L1N)30zKtRV!aMsjpm!#0QusbLm7s*ikpY~9t zU!)C_^G$p!M4A&WQeA48OZ9T8B$o=?RI&oaFB|G`6yGasvZ(@)$Dq!ODX@%144@7{!B~aSR#zVCBIc z?IXc4jN-u_a|{{#U`1@-elXSt!($l5qnFHM$k+!f4|bN11jjIn2Rr*1GWNmBgFVhi zf@2uPgB?EyeGGBhVnuAsV_5ZhhtPmCja>YmAo&$n+sC``O;t{-5PDzJJ{Zq5m)Z*q2k`JNIWc5&jd zefvR4;$?IF;G6)l&kYcJYJk|&0>my&JhpE?kh?_#su#-=uNT(`&kGQ{JV5M<0I@3* zkL}wJW+YxV*A~wY5c`4vv1bN|Ju5)$3lop++Ye?ZUN+YcE(#EPPJq}K2Z()1fY@^r zkL}wJ<|SS>*AFfY5c{$Ku`dr0dwzh}S0oN(a9!eMbN!$yK>X0(jPRZb%rc1oB{i zFF@??2Z()R;<0`E!A*&m&GmyH1c?2^0I`1*Aok4xV*fbt*uMSXmc+~E`aw8A>_~vv zw+4v)lK`=AOFXu3Ke#>dvblb6M}XLO28g{VKu8W#AEyRg9j5Yo9hQl1H^tP zK}83^_U#AD6EB7>v40mJ_6q@GzZf9)?-P&h+YkPbc-dS(cqu^a zmjlH9V}RIy3J`l;;<0`E!7GWE&Gm!-4iNj#0b;)zAognkV*e%a*uMSXuZfq<^@H^R zVs8i#`}F{^-v|(UW8$%W`@yEf%jWvQ-vY#bGeGRO0>pkhKC0;hy5B@hm?0*M{y)!`UT>)bMC-K<6{owx+FPrNJ zO#xzm5+L@c0b+j^AolLWWBc}lJ&Bji^@F_uVt*bW_PzkI_Xmi5Ao19~{osql%jWt) zbAZ?f1H}F^Kd}n{otDbv0H+}*0lh!^#HMr#AEyQ1Kmu#Y>pr3 zB0%ge0b(B)AolSAVkadY+qWNdO}uQbA9M>4`-A|olLN%=9w2s)#AEyRgPw_(&Gmzn z0I_=oh}}Ct?9>3U`y?LQw;%LPylk!?^a~KXe}LEn0>mB|AoifdWBc}l6B93+>j#4a z#2ykL_Rs*aPYMt_lz434elRTYvblaRJV5NU0I|~p#2yhK_Q=Fz`}TuTiI>gwgNy*N zM+b;KCP3`50b*w+9^1DcWF=lU*AKD-#2yzQc20oUxdCF2Pdv77KR7w@vblbc7a;b8 z0I^RA5c|{su_q=T+qWN_mU!7*KbRCC_UQp)pAjJTnE_&dC-K<6{ot&`%jWt)et_5o z0b)-M5W6ryY%B5DzWtym@v^yoaCU&$Qv$>;4iLK}K}f?DG?k?b{D7NW5&WAIuC8dscwh z7Y2wuJ3#D<5|8cM59TCZHrEd>4iNj20I}x=h&?Yr>`N1m?b{D7OT28ZA6yr*HKi&4-+q&>jysy5c}o; zv40#O_ALQohZB$O+Ycg%m(BHqTLZ-YNr2e51&DonfY^5=9^1Dc+?jaUTt8S8Aok(_ zv40vM_FVyD-<^1D-+pjU;$?IF;Aa71|2#nKdjrH?5+L?{iO2Ts2lpplHrEe+5g_&h z0b>7GfY=WPh`luN*uMSXp~TDP`oY5iVm}ff_Obx6mj{UbXyUPb`@v(0mreP>3D4?v zhsCxu?Sv2?b$BF`N+#8vRCiK6NcAAqlT=SqDWp+<@qHi0=tHV6slKH8k?KdPKdJtt29O#+Y9OhBqy~{1MCwFRCz2XWYA~rGq=t|h z8iUR5qz`q{flTA(cZamsBpP@ubF+ zI+@hTr1E00Q@iRb_=@i*FvbK@r;s{@)TyLSB{h-ML{g`bI*rsMQj`0XOKFB z)S0BtB=sFq-ywCD#P;V0sbA?UnS|-`$swOq0jUB~lSxe`RY7=HUDkD`! z>O4~Ckt!!uPO5@b1*u9>m853GVE6q{f0D2G{(QzbpVS4UE+93N)J#&dNX;U3A*l;V z%_cRQ)J3E&A~lE998wpPx|q}@q%I*fHwL@k+xjZL;`@1wF^|-xq%I|O8L7)iT~6w9 zQu9g8Cv^p>D@a{Q>Pk{qk-Cc1)ugT_wSd$DQrE;__y4p06kqZEwTy8ssq08xN2-cc z6{&@!7LuwaRZXgfR1K+GQnjS6Cv`ok?~?j1sT)Y$Kpkc zKUN+Yc{um(k zp8~{Q7a;a40b>7m;<0`E!JiW^o9hR!28jJyfY^Tt5c{tIVy{m;wr@Y!ka*c#KX^Sr z>^B0$-WVYErU0@3mUwL6e(+}EWpn-DtpKs#4iNkA0b>6nK~{mi-WDMCdx^*P?Fa8CUN+Ycwg-s4BS7pA0>u6>Kj(b~ z5c_`u#Qr!y?0*G_{lAIF_U#A%PP}ZcAM6Yedsk4{eY)uX`F7YPOjd3^an+``tS5Hj zahvueA5XuE$7;dHwU(w=-e)ynr;m6&tR-1_k@6w#T6XoYhxGpw>yOLNcLHad-k%fX zPpdv+trA{b0q(3t3Iq*)*X=rdDc%O3np4y__J9Tqme8p$(UZK zC+SHLq5K(Zf?mFvZ|4G?YxvbC?a`auXvumqqx}ny*)y$A!mH+6Yr2AJSUh`{c;j|$ zmbF(~HQ$Y{xK?y?U#RpIU%Kfx8$IV5nqfT;E@DHMmT#<2wN)#zW$Q+nd+)=uMrWL#fNl)Fl1&$jjh00QM_T6-YBc>Q+m7V8tl zv9>G{-&k8U@s+i;Yh|i&eG-#^?Cpw={7@q5r8ey&{ZnM4vce5jnVb2Rleu3Pxq6{& zPxW$RD!t6yPuVu3m|9xI2CYT6wiF*%2>G5G$nu*ABYz@-Zc8z|RFP~-abGQ*2!Ul=84TlYs6oS`B$ho2q>_+J-^4Z5a_^$|_C z@NTxXTQW1i?33`X&lC--G>s*jW#_v(<3W8lSsWBw*CVKn)Yh6s5WaqAm&sPcRb2|L zW<11(TLG{c0Y>jeN(PN@Hd4z-eyTn7iFlm?Y}pB`-9YMBWYK^Jv0EJMk<;}(G9@H` z>NW9tD=9M}8Fb-FW;KML+-UTwmWbh}YK*Kpkc6hu3ahBQ}I#$!oOxLPpQsRCaSd)U|b; zmTCUOCg+8r~Ep(+pL)(hrR8Ygu5M*B=MFp*8H+o*oUpT8l*s zLW$Ve=|lDX*4D+9*BjR_VhWJ8QL=``DfsfcMuuh#4!g#j1KWQ3Ppaw>cV%drsvk(g z6;##m^q*J?nv6-R1%~(ZpIq$P5qq`-Ym2O9Y*bd| zKl!rN6ke@cOZjvEx~KP8k1X2rw6(0O7z5W{{hGCGF{wyqM5@|)jG?>3t4plq3;>mj z(80SPQkiCH+Ul9sQlynX-Fz<`dXe7Dz&VmJ1FI!FQr~4jvM4T@o~fU1mRD4Y%n~b8 zSa|5Cr-sqYEnNg7jgg2yr9`1~CtD8iM@fiVr?^UBzwN<*FZ6@aWQV1!?Hbs-7Hh3w z_M5^DMbd1o31O7lZ&~*=?9^bo>rq84rO(6rXHZ6A^vI{Vv1z4za<5y)8vRSroS}8$ zL-3)qa-66v_&|8|zpOQp;bqp!B<(u@TazW8yb9(8*we&gq*hQD{AnvB6bf0*+Uj*G zSwmQ~h?dVFMa#btd39uXrCTOd8CU3EA+Gk8SQFCvhz3gR3JWi2)T}SUYieMMtN#of zJb-hMOv=P#8Q=-u60nhPPLqr!7weJ5BFj2eJNPc-={pN0o1}p{F^e6C92a}xNwf4r zct7@LDW|w~t~S8v@fOwdQ?1)Mil4-QXvtzrzGjFujarh}JXcGxHtWNS6&jh6bEfr3 zSCI{dsRg2>w6NHE3_ryR_%D@q9VBgZv8&QQ*S|(pQr|Tywpg$G&yFc%r!8qx-chDO%nb=qK-O_Er$PRl`MTVKKybz(Cj13&FNrOaikPysbZ#_y7u zjA9Qf*1w_h5D3x56YEhblu&8)5ok3kl&wqMn8_+hC-(79KBa1pZ;Hz&z@TZCvdpnq z1|VXG{Pc^eMjq5#AWZ#hRL=9LBpSM^%=lBpCs9R2b11W~Bzj_%Hdy7A7A+pRN@_*< zLG9371D>KxuA#3=;Hn8dTz0SY%lpEQQ14BhuB*1_^5b0lFM=U%e8pOpga&juon<4u z)yTjO*M_-=b!q8?)gw+Y^tdRf_GydTwT8K_pRcr@SPVmh53Cd`icwIz!ws)cOKZdm z7Nh*RbP?dZo@BifZnzxcG|YuK0huG*E=(}Cnl|Rw6FM{WK z0+M9_9yuB4He7ieshBq4!fncxSSv6{P))EJ3CE;Sh-`^nHT(uc4G7u*%Vi4L^h>aQ z=n|=pfesn3IN%Ar;(h!CD9e-WkZQ-peW*|1QfnWV6&h@6?RB!mneUoj8HQj3k_~;X zecTvF*Y^l{$(0_AOD?rmhtbR09D?huKQ2X~L7~W^jV$4h`0(im+DxNMoIP~%PggJ4 z>uMa=$zXBpJ=n*`1$OdJ4|Y-~gT=A;V0VoR?Bt&w>~5V57RR30{@MfB;t6qyJNc(a zFUg$@7RTO$-90X_lYe@!dvr2b9D5IT&$z%&{^`L^>141t_Qdw>2fgAFck)kL@UgMCt5 zU?>0dV23&xERMYgdstjxC;#+d5AS5KIQGQ$?FVUbi97kHM=$A}3>L@UgFPZHu#SR8u~_NchPPX6h^&gf*YIQGQ$?FXad5_j@Xk6y-fGFTjY5BAu&z)t?@!OrYt zusHS}?5w!JPX6h^&hBKeIQGQ$?FZxH5_j@Xk6v;*87z*y2Rk<|u#$zXBpJ=mwl1$OdJ5B9`P28(0w!9Fc6 zu#L?p*uMQ>N?hVj{^`+6aVLYtvG-uh&HTRisl;(=|4$G0Iqgs1krW>6b34MR{b@be zQ`?`uBPodO+YhF71gZULJ$fl^fBKH3@L*5x2&eX^^J3TjD z$FmVr%B(vh3o3C!W9@Tz>}g`g<(|)+ZpH=9Uil{mTlJdOB)N;#IObtBht|G;#|vxm zcxg2r>sIj)ND`>$p2OqS6?m+#bq!DDrqm88A3&Pqyp z^JYGN&c`Y~)+1ocMR>fs6pw9nc)Y(F+4koL!_G8jA;tDE9y?Z$-@ACc)rF5V^kP5Q zslYYuZz-VuHj`y>zr2TsU1! zn^sUNtWaUGC@3i{5v5Z?m7)lTIIt1_`~oqx#0rV&Wr$}LRfGUgQHjmg(iZ!@ZOk@{ z3#N+7P{}v|NEAsyl2BRsbTOs8s6teXb{OK-6j5F>bp$Iw+O)C=9rkBsMbzalI zk1a@w2pOs;g=Io(e^|VuVCS$++nhHzbr|z|9zK zm)Hd*0+}llWrZawi?$E;8){sv3$wgvnwVZ$? zQJGl*u`(x%^D<}(nH8ld5WK@-ok;@8G68XBj>yc-ED`5hNIZUA;h7>w#>+e>S7eUQ zoaE0Bs{0)>E>SFVGmA^abS57+!GW0!0Vo~}u<*1@Q3?_zRG23+L5fU}B6qyZ!RSm; z!Lvk@c$P@dG?CJco+}_cc}sxO>28^n7<0`sW*HWhsXN)tC@T|%C141Q3{eJcB0crc zI=~p6DV?Qt$YGPHGN~T;FJs=fNPW~KPBGyO1`cn9Lb(N`3gqDmJKt4lUmBOHqcja# zw@VS8yiGKRa2DoNZS##d){4VHIGE5y9Yt|Y^x)7B&zbxuti1)wd&-ALdK|pTq!eBh zgDxojziQN_#$|{RgLqpEqQf{A>@glLvICCa3F^eGn4>XL9(n%ANh^;YEk-;& zPmIf{l0pQw5)toWg!;u%gz|v3lE)R9*#6ps5nmYdQBA81#z;?jt)t7kB1T@1HV&`J zs9r{-8CL+JoqDBYIDm6BO`<>G8kD0o5yc+0!?;pnE6Z{<=jy^Xxi&HtZv_tbcmtrI zXGaB%Vy90qu8P_yV#FB0#u-hDtf7;N4M7 z^W$$RSrj|{eq#ajn-pssZR96Lzp>iK0kmjM5F3zm0EvLzXCDK*%caN}&*A(h}RBAEaJm)Sw$!G97ud3KTlnBde$;yy$i)yFZQy zjzoxi#K=+Ag`#JKYldw#YN?lya1m*S5rOXnsqO^z&vW1JR;yE+YjBpBC%`j!o_F9| z#-Q_zL2rvK>u_$CS5{bC^t3!u2k8kqj&^pt)EK}c|KOXvjlb_x{ey*LuQ09`ck%o$ z4$|{1 z4BEp%C$2FVtZ;Eae7pY>7Q@B#ItkZaITb@&WnPo`_U{MsU+V0 zRwaR)jldl$u4z#5wq9z7l^Zu&b|GxN&Z%>@TqMdWIQl887%Or!D=Ll5(~YtUF&4C0 znTg8_-d#k`Ekw0K@2kMjk`#-ME|haBDHI~DSf0dpXIpTbxgjFUq$>SC#!Wa~ylt^J z^M)~?+9^cw2Ck4W2D`t(HqH^=-Gg_r1-IKc@vsF)bCB58qfRk?5brmKD@Lz)v}yQr zD?zr=`(gxX?IkvL6;4b4kXKs7dkoUIDkq%7-nPV<-Ff$Ur>Ne2$SEq!%qXSjOoYCn zbjM5H|AkUN9VD9X%x2?9ZIuYh;k}!^8KrBtnbG|SKt^fipiuvy?ifIKfz!xb$5afo zI-l)9^+?O$7>iv4j~jW#I-LIBD^X%mBLB6NQzm1U8b3z*R{D2Tzior6Ol?=$_BbNb z)N>}<^;K+D_1-gXA^b902ytqUmdV%#;}+=_D1`TK^5%9hmFm`L@y7pN+eOhKLDhHYcl4zDvJ>beMf_VPVk%EId0R`PqY#%CXBTiwy> zqxVJn>($2+V-y2 zU6BQsvl}3Asla7_gfZaa1G-Dd&wUjO2maak334;$6rU{8`e_POI`_Hl4ok=AV{ zI}XX1UP1*l27Q6-1 z+_8-v%Mk8r+Odlg2)3dj^ayvn24nhQvvGQvas70e@2ZTK40bVh)VWxbNxAOx!S-l( zCeD#$MP=QEv`6Z)d~hcC#kLm6wZDE*&B)EhV#(SVWH&6#Z?w}HRk&)ozeS_*!2?RV zXrp1$Cmj3aIdfAF#6jg5~x50K|70KoI3VZ08yvr$> zm&v8TUOt?`GEsgovfj9x?|I+ahx6Q2yjttSJq!pj0j36S*DiIbBu0K7k@MZVSmykb zKl9ai^KGXCx17~iJ?Vi=RzJ!G-i;n?^Q z?)f_OIW?4vRl!4h9PIR=#?M?FR@-wH9S-O6HgPWT;`|HxkIo`v%G177tTCpS=+h6X zN8}qnZ(SoTWvkY9FA@X6WwPh(u}IO7kAg>4P$%xs*YZ$ijmyOw#&P*#D+6R3TusOtXh;~{Q_;< zM@c@KwGKzIv3Xz3eH~`jE(XlD%r~*`Z&%U|NA_Uy} zUjD1Y?Apb^gZ*H;l6E+<2YYFU*|m#-2m7IRCGBuz5B9?yX4ftT#P;n6kF<+*ha-FR zvaG}G+Qq`A{b+~TwTpoV`>}Q6h!Vi5Jz& z@k@+V$A)KHT&x0ZuVziw_Aa$7ZQr$4k#=xq6uVb1<0-3HJJ@KIXkRv3)3mR4Tcz5e z=d5z=&_1g|`{o6!QrBO#F3>T@$z&aVM6uBq{dI@gwTpoV`{{Ni?Qmod_UaC^YZn7z z`}Tu1?PA^G$R54acbHwf7ZbiO$r`NvGY8av=7RdqB9VmHZj=_6ioQE6 z)#k}(7kgpfcZ~lgJ8>AE@}htHwtpD~YgNLs-qE!6T*=PlS+5+cDI(@$!$Bdwjiifd zM)q4=NB>mY%l!Z;Pce9c^@)y0leV{r;Bx(N)PIaWM^|mRblBn?9osui9#m7yiQI{W zy?1-(Im^@tZPLXs`}-W)-Y{T1J7(p=w%m%qcs%P?*)akd7yrw&f9I)_TEiw ze||8gxAB_w&|>OU`#kH&T&;(t{*N9H>v}oXqm2A8DYw{=;k}Doy;NskZTyA%Dsrs6 z@UFQ=R+*8#o9l>WSl~WAQ*2$uuP*VcO(b=Gn*&mYKcA14UVQxnAF05`#jv)H6wYmg zwO6?mr&*e|YcAhm4c`vETZTeCQZuxNni2OJf5oXps81e9tgriN29&$+JpRPjVCuAF zqnB-2c=`IR*ahSME)fk^!HQ8JNi2|0xNrjNvCsKd8;3_Pxy%CFD{d4c~S6ecb39=kWW!j`MN9ez0(4qw$7QA?)wcxy_BclJ+#a z*ax_GBd&B0oaSI3IIT7Ifsz<(S&i=wADDsqCF_r1m9+u8()M8gf$f9C?=s%B^`;#t zuvQ=pVjieL72@u}K=X6Oo9+wuD|hNsJAChcc1Ie7SN^Bkkbi^H`PjFNw@{mnuP5S* zZk{&qdpcfy9@rNB#*VYUrMbvS`-R?mE6K&PAei$VKlj^77h{)y$j^Fm&5*B*x2-4O zir5bFMUiM&hmT=_q1?m5Z;s9xsrVycu#wGenBL%%+k&4n5Vr9}MAfYgbzoT^!Vv+N zuU#ggn~c8`f?vGL&o{=cYsLNiHo2dH;?vHiz{`zs`A7uS=ll;_+!PdHNd_ND)-oy_ zan`UQ$pY0}ATz4UWavZ2KTsTBd`%(oeY8669cz`ni^FXRaPjqy0L=w)0)&7)6(_g# zsePb=<^q?y0C(FKYeE+q@5E>I;;Y+4y2uw2EnOM+{_ugf9pi51)+N`tmCkEMFEBPk zyer;RKDcs`R%Gptpugj>=4S3ejP=G?PE6j@vEt^ZT3d1Ri*Z(Lm-op>*J-_hU~ zefdGvu%8%P;~4Q)`TeP3&ni4z6t7W*kI`s2d#+%F4^dPQS<4=Ja*j{;nUOvF(4J^%l_pMnGFZKDyzHko~N<-GRrZmFVQt+<=CWs zd8VBm_J8ea{>yvBLvr77S2*^v#XMgT8L>?)$2;**1|Cp7js%3ioTGHKl96|ZzkG_& z(*J8SDvbA?{b*m_fb{l`TeKgNopX+8xja1t4LFU*ml$YJ7qWES&m>>G7VaAijcE@}#r?B?UXh@;0=FV0TQ_9O+#mN-UgeVW#mdxjnz4wPYG;pBpFbMFslR zeERx6>;9cdhX_9b--7$904*~+LT{s;^YKE}%Xm8U1)<{Ac>2ACF{j&HglFBhzFgwGR7mAL-w@!%46iw|*7FkMn5%-1xSgn_|9?{(HEFcIT4IbvE8KF*RO za0bPW8<>061BW)q+`FZEXot#o`kBT*VHL6Mj4~2j$e;|4`KjYW?Z<2F3|~+1sJ(J3 z;Jz6M;9^O!Dypc&yRSz}5twaXeo&o0-uNE~!>#A|Qze1Et#q~rP)WcAoSBHPxt-O? z1Wd^8$IC6o@@t~?ji{2a8$B7j(Z4>(E#vCgfIvW!QTvvWT_zeDwPXNse6TR{N#kSV z`g@IT)z*C)F51ED#&X1=Zl7GV=O3uazW$fdZMSR*!!2KM?E5b7<++hNl5v(Y{Ppu{ zH#%**tHoujDJ~w&=5}@INKNg`bGN-j`*Co zMpKy)d!$oZ;udTo#+QY$r&#`!ZWQ+sSq8Wo`-YW)qcP6iNbH)79~%E_bYDwx<%egP z28FMw`6t)cVT^1V&|vZ^qi^Q4ZtlLRahf}XHfi6iv{ubMw2O8WGPLpds$`NXRdp~+ z>U`)K#=p6f_($T|5CHK}SdBl!;@N!uW^dCFOQ&0~lT@Mz*?k z4Jmp-%MeiIlA0!sR>L2$tJ0GV__~_r(rB$Mn-H}Gjj672Hlbn~se3>bO6nm{MX+yO zTM3FTrt8x{mCLlUt)3R6E!PlfdDS#Jlh7eQ+7CDJM=o6<|#Z;k)Nv_*6}#6W|DBhVqXA2`v3 z_Ja=&z}*1*T?S_yGMoT3VVH5qPy)+y3A@8B+pKr=%rmTd9I>_bz_MNJ+O)@v|D(?i zqW8_2hDa62cU{+23xPb@*Hb_MC*#Lr(c${c@=dRHI`i(CaWxuAm1yxhi|@`Ht= z78;+mp$L6myn>q}`qffd$OaTai;D5Zn3^l1-xFVRK~SEW%#m}vElkS#p?b(XWA_oN zCE2kDH>5m#WmHlK)f@9Xt);AC^j(zJ?J(*Fdf6};8@p;mp|K~%2b*-m{($qE5QfdM z*)fL1XQwG*iz7sbBq|>56oII+sglk4m9?*nqA{n37oZ3Il<7C z)iGQj2eCsIdh2MR*=&%B(0UEa^;F61K`W!GYezg|d@gGj z*9VOkV~W~eGhZf82gWz^hi}@qO6-LresAo9(VEka)W}Cnv?pOS_pyzhHah{Xo5?|(`z|4bEFVz{pH4X^3HKSTJ*|=CgjV!oVY^g(u-ZjqG=g;s4+r7D*^yr$s|d#nHBhg+sH9FNocTN$bRK zhz-~>2}Z^%6l36gWUa;umg)@Kb_g!2CctRoGum84yrJdfy3}}=I@zW2kVxjcYFM6u z$x1tsY%OH+Q`~o_y3|CMI?cLEUw|254tKCja;*#a6e$TPDG4a4Jf>JJQxIBW*P4@z zgED<;M68R;P3Qeo`NsajFFOyTEzZn#$d4cJ9L`s5ap=5vl+D%4q0Yl;i?av&>$YNa z-a8NWH=T#m7H1E3yOze4zqiHH@4HxRv*Yai!peBW_Ui|x-Y(W1j_lEk(P4J&V&K6x z+m*D#kv-Ul+fre-GaUwtW8lH=5*OIXKRwvTbuw5Sdt&?cgX7~8ck)kFT5uUxKN~d&F|iuv7u(?tORWbh=+HvBkp>K-6UnUPct|V5$1(^2KGI1{_Vg=-RBsmRZCLu-c`*IuEA29l5LIL z{iXMqzztd0zQxT}4Z3*G+WL6XcI!z_EbfkUe;iA8DJ#TQM%g+{G>S(dn@>Ne9kSI- z6|3_xS(?=aLRl+0#Q>(bj0Stl#1iI9?jTbFGZ*&8uzVTPql>dKOi9?Ii_EFDr0!?w zm=VLzPa-|KleuPyht{*y^d8;S_+a4o%sx&CM7CtcH*;qPN=AtK46M!V)q9NKDxGeO zlxo@?>5*%s{h8dhFnlAd0Yli-NRKm=X}PmmTx7sTw@8n9m=N8wTmE$Ip*DSi*;fYA zD0FP_Gsab8NZI2I>rQ>aT4cG$?YM6PY8iJqOJ}PLi7a@|82&kb%e4_{KXN@BQhjaJ z!(faP@);}#=nYJ>6`v5GQpZ54Jzkdit{FYk>?hVokYk35^|xvoJ`%um{CoiT;4=da z_{@O)GP<^cyMSaQgl|Q-!?)*X#cc}{%77*v?=W+btR%S~pFvQzSeyQ)*hlKHO99BB@K8hU<& zEUtYaR#ht&r>tOzoRTSUm4S~j)bnEu^>r_;j#mbB^}<@ti$EjGy7nB;E3%zEp}9%_ayF;5g&{nM=jddhrcKIH+%-WM0!jS_*!rG%8A z>T&^Wo8yNom>q5_cmYclDa+tWDZk(hc>S=Ro7l+B2ppMx4CWe=)GaBb2Nc}oPWAL=T9ro1N3#w4pKEX1RNltoHj zl0S{JuShYI4{T)Adu@;EJnbfvGrhfD;-iU=Ow8{?e}s(A>g#d=ne+RmoZmMx-=dD| zN8@J3Etn5P!j#vdlhtjph*=o0^PO>tIn-%Suw<~bYf2r}u-sY`z7HGPoCSqmnC?{z3J?TK7cZg8OxZ=IxQ$NlwTJK4G2g!YpnBk! z=1DdO`lQ3*RrL;9x8FgS71kqcfusgjv&B;%EC0a+e>S8{?d~i` zKmdEgRcbG&7Lsp7?!EfY2nq1{XMt!5}D70Ym4QwPaw%B0R04of%F@N;~;7S>cUzwhOMS-L_e$yTU1$c=rc z=g{fz(z-2$eBDsFsrmOl^8Qa=i7uz(A;uHMkf15jw}e7s2L&_pson>R-t3EDFA7>m z-s2|MYTvjO@37-2$GD#T8LCD3!Pp;|Bbg&1{(ycYIwsg;Nc8(0B=B$0jw?34pTrOe zZ(B*<5++2ib}qkRG?(8nnu}(>c`kY(&2!P#L#}63_i9ZYZk20jgutKbeM@ZYs*$Ie zqfmLkMqG}TT!n6m^x4EkWD6w$iuVpm=LFSvmL%)BPLmokhX2HNnZEW{x7e4lu@{E=nWL2tMpuEFyY?+JvZPy}L$6u4 zM;5FX^>abpryai&HDcd~6eNI9o7frRX2Jm_Lgsmk-Y-RL32})itY@Nr*Pau<2P=Wa zofJSTA56R493$#iaZ8Ne_cbRM12$PtauFOldK-Bhu??vB6aY|naBJIG{!Hf2T^4qy zjl~DBM2pz69=&G{j^wzAd&E$eakm&UkYwMNT91MUbjZ*8L3RH}&9P!jqoxLKkfYx~ zwRsSFx#6$YnveSBpxz%oRo%TRn&tvf)BE4Z2lp5Ezm1Py;L)$zq2y2b7=TkTDm418 z|1WI4RHuDlX2yqa*85f(S=GkiI+#KK8Db3#f;(PXpoxA9T*tQ=sZrqlOT@~nr1ACF#gn8U-I*-Fv7~f?!!9sQ zy?+-XTL#a=13IeVa^ObmK&1cGE_QYL#pXD$>$_5!mrQD#A(#N? z0ggMfnW+cF(hPvX+I7cL`#-MUp&#g6!5h21RPVn=ZZCDC{|kO0yN*)l87G-IauvDk zG4{dKCA=^=wbk@0V(-9DxyN?^_NgHuB45%*=X?7oi-I1|aTy2DKS^|I~{ zAHNIQ8!&|LHZb45{Ghha`(`e8TPlVSQ0k$k;6sl6UWzWKK5&y&&#hSZMR4`+UVY%dRO`4@ibQ0m?)kNOiVBL~ zDIOVkPz9`Hn%$8>o8uc6N4f$f!y2|Y_ccPUPa}hRNfo#v&45UQPLmD`WPg6JFf`xf z_X4obe0c^eHEOQtcBFHfN)yzO^ig_efT7$6RQC3=rj1GZp-3CPj zzDa|w0W=WhXDgRnDV(&2VU6a*qeDC&h2Y((17x8Z>2ji=DKhXO)iQ5{S)e<>e%;|J zt3e+{_rh0)t~7DBD=h1r!|jFFPwc8xibBA(_M&+v>XE_opqIhuWvXWC5*#&P zIkiK|#W7MctubycjgrO9b{w!qE?^`|UEnqi|#=b2SPPrkolXyiUez*8_vX z!RxGs#e*9;GGQ<3qz5oq9{e%X4XPo60M_pg_K2nCS@Z**xtptwG%?c0GLjp>nm(ox zNRsW&+?!)eO*R~FLUHQ8!4JNO3^@S%;3Nw6Ua7p=o_*3?k0 ziP*mUplbL*v(WM?0vf`ZUJ2(q7K9nP1gd4;xg8EN6i33GI!spGu3oCsPcbbu zzLVWTiTK1SeC9~z9Gx{D863I?V`cFbeChJOu*%q@ZkHeDnB36)N?uok(IQmkEjJ-k zwLq6XIO;vKi01Bg98TI6lcqsm@Q$1t27uO$<85r^bGGWS?mpV~yf*j!+1Lw595VU+ zKukJB%T!vW+;47EnERx>P&XuN2vY-#=T24k7LYtQ>f5f{&X;c6hChFoN@u>SPI%Lt z(x!6{QOZT9((Mz2MsvmYPWKKC;9#{}6SBL)WPIcbi!l_oHq$IVa@=DbN@#z60NL8S zW#m{(6y-iB z{LF9DqtMcaxW+NswH;*#IGNW>}pQu?1nqnGJMlv z=UQ4%Zw!CjnO_j`&}*Oiiz>wkLMf%*tWr zQigxx%%!CDvfG$CIhT?)B7QDqBUN`WGJGOu+|zPI3;yJT;Idvk>38ONc!SEUVP zk#wE$xJf&Wi*spt){{wlo~6Zn!k=eEu}A&YtWeQ#T4=;*~Y~WJi!f>@IzXpP)<;@L;)3T+E<{6psNw`JkoaY3>AScQ4+8B(X9Iy$z3la zhPisF8unl2`7H5dP7ZPlfHOhAoJ(fl)E)1fFE?Sdo=ogv$TIAZTx17DG|ZJ2nU*ge zoGUxABhD0$&`J>*SAD1ggrF=y7rT1M9r%QZre8cv=7-%MEGOY88q3MRnBij8$FLz9 zRj6Co&OH_ljTqv_TEWGKxpqR96VT~{wI}vBXGRMVw_n(02K#51OK|F*+2Z<}Dvl6D zwXeYdCuh2jW2q7E;sv6Ew}#~mSyCA-HUDyotq#8PpyeS5O$+@P@p~tO6I)2@uk&D zFAFpNWL`vUC|BFFo>VT6+i+XRDBRm{yLJj@#YT;wX`bTj{a_UC{lM}R*RqiIzD6vd zG1pkN8+C*ANBlIh-{HARnE@S3;XuBWrOZW%WSM8GO*5j|6%7b6hF{N@GQamXVn^0qJ>zCVD_b1a#k`mRFC*Wa zZq(&;<0yHs*gNgpYWnulf79(Sv)uL4E%dFqEDTvxFDr54w6AQEc5ml<*d^vAP)Eki zGP)`uh;lPLLe_Dy0b(Vq6GTQ$89$GFnLQSn(Dkx$N)X5JZ{~0+)#BbbI&*a0bYa>q zb1qeZ!+f{GI+pGPcMMH4^YW_=xLadlj>{aAXfNem9o3Q~ns^O9gP5JzpkEyZ@dBcuuv)H0tVvmPm z!s?GYuSr{EN(+ugnWU{&4=Q@%2AQnuBUZALE)a zbukU|!)#KQ;!B^_O65jlhbX<&j!rSJ;uZ$3;f)=JT@JW-t2vVUIEsDj4bbt}S;VI2 zjh)4MmKKk9Ts$-u-b+)pR}WP%H^!>q4S*k0$JJ&UEqJ{X8C&frSNh<>0Y5RX){zgD z_l*$Q7;YLFtPUIn%S9vU@N(HluCF|*`Uhk8JI*$CKly6x=4d(_$gx~)Ql;olyr@7H zo$MD4y~JF=NY1rz0#n@_{*C>_S|;_Rx`ku^#Yh=&j4K~-sjI}JjNBB-h4J9 zKx&rzKr(wVUI>+!y|j4cxoV3DqpP|nxu1Cr>oXahHMwnH)@od6fc&#EabMcMDL5)P z8J-%+oa@8>lv=mznRAUyTz?_4tA;;kUQ7Pf+bqnT#Qs^XCAqTVVXFMRw? zYeG^I&(EX#{D#)@4q0~<_t(h|W7ZAEX=TRn`>ihuvgTWPixtB%s0iIM+f}kwGD$KO zBkRR}1I&f+5xn*wj**B=nTdUs7jXy}TQkl60xzO96PwMfbunh)IuV9axK?p@B)cm) zIBue_tJAid)$sLkSGVqNTy#hY;Dx>DeJCfJJCS51frRLK$Yn0{up6<#eJjMU)}RN* znFQ7c*%QPXQhW96BAEv#-$Rqkn&{Z%q77g??rOBGEH2Dq>?W&ModHYsO|0ZtO=aIC zxx}R8a5z>q7hTHj@Z;7|es`30(S!V%ukyVxeS}%dQefpYjyn)ziuw^5k)hrJ*F~~` z@~yl@N%%5pQqm#X047|xHJIa0asMjGFM9`VAPqL4XK#WHT+~2@Z2o=uLG_SD=JiP7 z$-@=vK31Odb~&9umNxAN&2`paS;j1#s9CZs zqm~F+7Aa1c2X|_IKuhfE^c&0@Vnb2uUj7nlSX}q1w(~~Dt>Mx+=U{T$xKDF_GE&2N z^CI(8STsreu647z))Y$F#_l)vkTjyC5HBPn+t@Wj*O=eqZg$-m{w$TaPe**2XC*0Q zncodfsC`+ZkyXc72lR2+WHi{Rk=$@hO-!bT{fP-` zoDbNp=Y|~#&FYK=<{>zM zA3xtd)`Z`q`MXBEZlHMaGm}3foVs8QKK>qS%Tu!tV5mT)?2C+_VQn2f`v8QDt+Zxy zkfL5VyUZM&*Y++pe~gX<6pOhb6yW%^A`O8cV%t3*mm{_n;(N?I=`^ht8mz_QM zu1+@u?_|$_oBqTT>!HZqk(1|(CySX&{7GBPc*_h^{>4U*w_M4?8vsO6N6Q z-!*>%_q}SY8|K!hY81ow&cFpmJ6F+6UTEm%ZEYo{Pvm{vR!E26LFNAZ z0PD%OcNnc*3?Q1)3+{|D?`T)j4oCK2-`Qby?PB1;UevCn9ggh5Uff}J?PB1;{%O0C zb~rMzefz;(9foTc1CL(rZdcL{NA_Uf(_wb)V&K94S-X;UII;)(=N)F(E(RX#d)t+? z!;y*Y+Ygp>7_MCmJbJmWT}e9}*@Jz5huO7@fd^aN=iILJ9f|D0exM_q+Mm{g{a@`* z-;or=_U#7`b_A*YX+3&b+Wzz%N#VhMs3V-(pVou@aQoADB!vh2k&bX`e_9W=?**{- zd0QMh@0~|4k9HnTTbw=EkF^z}^WJ%|J2dQUzlM>_X+7BLL}dG!e9IIb>?gh@lW&>K#jftx!+i26Om6wp zho6ZrzWQ3-!HT)ZygDN*pR;7QcU|zgQ8Srj(|HBGFz+;(+hq&Sz@vb>Y71WAyJ9|) z@hE&14~x59<=W-2Uz#$KuLoe)VWleXkhpi9oVP7lZY|OCnz5^<0H+`^d5-z{f?47n zgmQYY54TcbOB?3&ROn_z#@!D-{b1A|&8L{Jt&u!j_^;=!$6Q$+=gRPsn`*HZl#fMW zK;FZ7&3#-MZpP%G)P-Jv>)f?{$(U?}yx7#J30zMltbGLqxPn8^Z^pDaE*S#vk4f>1 zp!XpX{-jmq^NHtlff;*{Z%2sDj4L3&$&Qrz1 z6)b)(18}<|ld-~tpFHG+P3ybzcXNeDGmc-&{9sF@gB|*V`LtS;*{4s=YQ=b5h#73w z^HzZ!%F^LJU;Z@4-3Dl}Vii_4S7z`bDLkytB9n2s!+IovEQ(i^ybbwUhJ3 zBhNQi8<|ptd-ci7srFT|5-ej@*67g7<`BvkB`riVW}L-RK9C6$rI5Fq$7GYCIxVae zhIdW01FX15P-Iedc(;@9LUz6vjvj5U;fr)esw0)dM+P7GTxA4X=RxH$^-iM5-J?X& zb$)_Hmcz#=nZF_QWD{TNmfy+#rih zX49KPY?VT&n@wEff)q`W!kbivrA|D#j*(FcrKCj;J|?uU_MkeWx7pw#t&GpsQdOQ>?8=bwyE4VNx4azQ)n&D~YT4c}~C~(}Fduy$( zj3fl^w4>`4?%+uT=sM!D6Pn^g@j^bXs^}G_xqccc{8~nm>zgX|VWqTvu-EU*XNWk@ z5!fnfOJG};SP4=i){RH0QK|m6qS$_r^1k^S8H_v@z0p=g5t>#sO-wJJ6~bP{(Q+YT zx+o826pGQs1*Kw2QRpmwD*+!&D3?Dcg-ra?ao14M%t{eD3(FQEVT3BgtkTK?F*8(D zZtJ|d-=*fWqI`O}iZEFeSfK)Zo4LG5RN#Ul5tV!+o z=R_$K9g{t)q@qkrEtoY<6xunPfoqbc;=2#XJ9bHFdMGtg^rJSF1io#mIU1QUeEC65 zkI&5Kqv?)J=>j5Qv9UYaN-K=@wIbYW7CCzazIT*^_2+z8=Mqp@g*=-pQ?YCJMRId4 zD%mdF0jBJsHgv%JtwL-Soh75{!SocS+5sJE9zb46AtWVhvH=VNG<(#au z?X_OwV>K>Knu7C-i>)<0pUjVgO!+82=5`rV*2%S_{$c(OX&^j4b92y;Te{!~RvjNJ ztmnFdWnKi_aNmxm7FR#j&z8I4v%p+YAxUxH6n1&Zlve zuCcKz%oh+dKa*d3ScZG*fZC)_=^OtJDR?Iq1HeGZD8-dRMPUyf1(s{z`I!>Cdc*+p zMFo2wVLy#b>1+L-6r{lYPhE?!yFhDs4tX#75!!=ml35A6&HR+nSf;eKRMAo)T^lNZMR%FV&*3s*k5q#rK_vr_YGe>Z0`{*C8%f zWoShy%Fy;i&PJ7qm@JwhXcnxnXwtgn#znXO?bs!3%vGtU(=_F4We;gn&6ir4VcQm1 zd^K&67N{s%VDZ(iDHL;)ugCAugO#43EU-A5sU(SAGkm7`vOINPq++5ZtsfkN(14B$M)&(O#gp`%iCH#UV{ zlZ@4Wm=W4Um_*m2dzCb_PF|Wt)AHzn7BuA}SfY*H^L_JAta~zrHdDju&CA;V34O3W zUFZ@0DWPvRbbR5~m?Mn4j2GGDgpTl-G%;IbXR9csVtQq0hNwVgAD1Eq`w??pT%ZU| z%Jajdb+Yl%WF?}s5RFiIQ6bvGsYPfnD~pvB#18q{S5e*L6Z4f;Akpkk%8kOQ*3T%I zW}xjXE-E}%7if)-q^QuOY%vjH1U?tOTTp*L$nnOv)bb7FP)rBgZB^e_;L@jEc&|*#(6~QY@dMP$RY|#iF33 zw8SW#;!`7bz1TxHUxk!VPWD7cIg@8p%<`pAsKQoPDJ)OSfaUo~XXm@R#{=eTB76L| z;vuqgopc42l|@ir$#kO>{jVdJ-y|3N8S^hFiR_7X5uqm}N=u8T;=8=1zA}Ntd5$p^ zonImfi$X6eR*Q}CW{*mWuFFRVIha0e8kB8?&}TiT zs1Q=v^ookmfo20`j$fqAv_dZ~5iczMkoz`VcKX&YEnkcA1g;0)x5{wDWQIQp@6d1Er zm}eK2LkDL=A7Tdd(aKcd(vDvG^f3Q+M3!Y3vXxZovrG*1IJj$z8|!)&bqJ%v(n1t% z5d@-zC#;#D2MvTdk*UYkSQq}V|^PN~*WLpF+NmTe;h!yE! zI-PDjWZqXixC`RJ5>=U0rRe77qjN`%=N)9FV`Cn zkfRN420AVTmt)l)@0(lWbq>9weA(Mq6n{FM*aEYpv{fP7O+QLos^9rpIDML!R)BUA zJ=WNCHg-+#P3F5X5H{E(Su_rhiWz01th}fKm)Qdt-TrbD^(<;u^!uln==XyxoL-7b zcly++tbQ>#VDGkkMpVi>GcnI*SMCCpJ7H&(8kNGxsSuR~ z<>(t!OwPtV;DyU1T&RH~}G(+Q9u2_Q>vfa4Y@lt44;42#SU z5HzR=&OksN9dL9^9Gn5S!I4F0bc_znpav$gXc%Gmeb2q`y{hVTL+QZp^Z9>1|2AG; zy}O*{o_p>&=Pqwu8>Qxw)>$*r{pPbki`&T?G5X|*h3wvx_$HY&^7STzWLMEZxGn*3x`no!$ z6Z|gi^?{(*nNDLpwLw_+4CZWlin+57;KnyO@guRHNFcIP*QIg`CBoTQz~M6C$Brz< z5|j|{+@!rsehtiM+}MqoP!M`rnD1H>u%LiK>df~_yQgi@sa*UF9q&mn2dC@udf{0C zRACE&Rmx$O8Q3+)$9^hJrZDtG-c6Fgy3*@9>2Tx7 z7GkcA;)bFufm5%wJEse62&hNnA>B2xf76*fUScPfz3$B*)}SX%njZ7J-9&puyFEJ5 z-ksKU`GqttVi+PQW4B0{(rfm1R zHZQiaRfcdL&Acrc6@2-Rw*|zwjaI<^&vA>rEg2QC zpM6_EjN51h>|c&s>}|=Yfc>kt1;n_G3hb)K!LP?{=55I+@x@(3{6~Ji-AOdTMX(2^ z4#b{gj%$}WuTGMMk~Gw6evvfP)*9Qj>M*n?&$8o zknHYYeKu!i-`0d?BE{{`n07Jsx_V_{Rt(N0;X`XBr~Spm5}16kV=yHPSW~RscKIc` znS=jJr&}=Vu&O)ZfOneSf?1`{h-czDhd~9&jr9$>fxqgKdPu1EQrhdn((_ue*u8Zu zC3rb_;T1dyRU5hok9#I|Fenw8WHGNkhPhB*HL!*Tw?5{=(Nq^Pnl&CBk?ZR0(;Z%` z#L_}b&zO6XR5=a?k6Rl1jWH6%DEAEIUUlS)=}pv&WQ|yOVgh$!!3o=umctODb)ndU zJt1Ev?~T2Hev~c+k}WkTLx3r^vS@q zHL({(Vm4w?cM{`W6N2?OWlzU(F!nzosN~{2?%Lu6;w2)7af{vSVc4cUD9&Tc>-0uU zSS;Q(g0iovKiZLU6Bw?MJoF#&c|@f`g$FgC}0ndx}m-vA1s?%qj_KN)lD4P_Io z6{ZUwI=*uqo-E^<1*8nIK_3MKz(quc z2(tdFX$OxU3@h76B=O_X9E2eVk$0LHw8a9Q1#kj~yjw%Jna*e@nzN2s(`%JYMvP;c zPV*r(8-OUF0ZgoFT1V_vO}39$n;_03l(ZVBwu@yH=BKjpMZ1kc6I~?g3SVC)J&AvZ zJ<>?+gpVF7ph!%7g}$-zb#b8A&=01&y=we}p(#6KuSri)E4?WT$j;Hd7eh`Ny!0(H zB43N6Z_5xiZgeX~1EhHPyAp(<3D$gIWnJEcV;Nc!?&uVR8Ci6S@MWN8UhIFOJzi-P zsSW(Mn9eOFGE>14T3{Zxx-)X?%Y>pOl1wY3OjmhgH#rGSgnqb(I2hPN$A2UCda1i~ zOT|bFG@n^yvWr)Y20AfK{UX6RB8XjW9=~QPdA87`|qrH+XZGqo70NaLxakQfZ@%n$3ZU39)XX#&>i7|az_+J!1*MhPYoKW$YE zz1U6oE#xHi(zzZp+ylA?r=y93*_%)!sP!fgpI~Uku(W8LCK&X=vXGH8iSwZY*k|X1 zSt`ZSP%iEICOm@}R%H7UPhnXgEa>%yJfHS=+9e`IfC&Cc*dz$lWoZsd&^=<>u!fuO zVjQP3s4pUe#)8Xf;-a1i4_g@s1Hq{^Oi`bYSE6t6F;qwkS;}wiF6_D2IEc{ zX=d99ecx^9>tKVumm*GzHpJM@6D&|jTcYrtn1^?@J!HTz8wzFu&Kzl5_5YzY^GGm;w#Hb}yHtHv>w zWevPLpnKrNEqbCxoO@Y?6^RNa76z|jQz6r#(+x&%)S(w>h?sVUIjejuEHo3)60*^$ z9TeBy1w^Zp;=rB83b$4e%CuQRT4gsD;P8={J3hnJ(y4ORC%0%tv389NRj%M%L+OS7M z!53jSnjRje(sH?)jp6@0yF-isC;I~Z7E8Cw2pV6_V<(9>;Twe`wjL38h9izC4kPYO zWGJ^K+8Mn@urkc;g4m?uy zmCRvysOYpvDWf_AGfqm2Ikp)!qA_WDbV?L!YkOi{I1Z+st&f%3BByjY$B(By9y8@9vAW#tlk=nvs)%e6bMQHRWk}!P$OxVlRZFJH4X-*d{ZBX zrUav8H$si@+b2PW*|OcsvUG<9fLy^<)_Te&wK8O^>sszEM2 zjZf}0#NNDW)H(WiTWIWx zi=rlw?x0(l5v&oA_14M6AZ`Tw$Y8;1EN;ffx-1gUqm#vwqY56cE94vSJ)u0ptO2>Ig@Fd4hFF;K^6OThEv?$A@-ghQj)600?Kv5`p3I5Q4N zl3mQ;R(?f@TQfP`VW%o1)2$hlM{k0yMvU)(=f|C;r;410O_(PWR%tK2GqDm8bXyJ? zlqFI2sfnK8oiHgZ9f?Fx+HlIU%M>xPR@FEdn!H8V7+H+LZ3{_;ct|cnL zz!pvU$!`X*RPN~t*4koB+sw=*XD?LnL>jZ{fG909PpJ<%ZMKX1x@!8MeK*N-)&SxDrs+&)V?U8Ep_&%%{JK}6)_^>vW@FkfvTJ-5& z7F-g{;-gKs^z7Np;)?>yQig#U|AQy))YI{pM%kGyrxTjNAD|^MZ^YmfS5**?&7Ljn z4CgsaihLhYELp3>gaL5N>DVxKU(I}pyygpTIwun;F#_xyChrjT3@z*iE93X;Lz zK&p8G?4fBN)F)9$$OEjIU6{&Jm_umzUd>iAS})*P@H46VByc8s8E6u5WTV5Tz40F}m4nGjYgQ+m14*4s$E*uuD=i+d);8HfS8 zkdy&Sy$DW+@7h8eefWeY^(@^L_t?AH6{1fINVy;U6z>N^J=G>Jd;GZA3vB$z#>Ldh zmK7qx7WYU5Zh$M6SetG)&~pfM+`}^KAhqLQ>NI@{j$XtPiTBsZ?hiP?F)px@fCSV? z&?2A)_gEUx1=DE0&?$)UvomX%BG>^b$6KbVT(%q=wyLn-%)*}j6Md@gl+MCf0t9IY zqF3l3DWjv8_HdSh=HwjKh0C;axaVo zEc<8PsXhA*A~D(7kkd#ba)_2+hjexwejeW~+Aqng+B=FS_DU{5$dDS{GTPKco)ku= zR?{Vs!hGJHr?vdd6=-y$Z(3F{DpfZQ`e$9GiC!q$x>mlObaoM?P>KOSiQ_cZ8LbGD!155*J{ybHt;3;E#~l>Z zOrQL0>JduMF}jzNJL!j;i+4XZ<*JLO{>GMg`_lLBR=eN6*8l&O|G&TiGeSUA{u_IT zw-$+feejqol(Qw%vAB@+7vt0*{`^&u_=l9ENL)#RCoS!0X(()<7&PTh=H&dV>bj{u zjsFA)W^FY#m-F)xJb$t}qE7P1-gn^C9C3B2@VHMj;I17vSAZGVgYS4o#iC-4@2N?4 zdD}l)we0p!QZ1|eqtxojAhmi`RBlYhKwI>$tmKPB5A^9-xr_fyM^6E4_OqzBe6_3$ zvd}o{r@XQ}2lj+fnQ!yY3fM=y&A>)AFR;C8VnzcKKd+7)Rr!zo+1Q0&ZK4c*8du3I zns#;CU6T@S6Z5l`B|1UQtRYOjntL{E;G>QMCIpx9#tREEpggwFkUFds=T|$}Vl}%6%V_pnaG4pL1 z1AA~^H z3$p85LL3-*N#ZtPpjM*sHvG<_8;8dNx`%2OC}L%@y_AOPV)=zJhw9#HNhlAyak)IA zNo)r7CAcKk!FcR%Y82SLa?*n+3f_%Gf~-}~ic+4Aa?^rjpnGZ#amPlJ>9U|shny;s z?!lxO-M399v*6xRl@P(@5z*4H*=Wmhe77sx~tU0GsCmE&M=TB{}u+4L*q^HmwTf;kfT( z!!l8!@k?B8x@(>ApUB*ySJv|2UUr~^6eE&p>n3i2NT=$SW@`9WJz;$-!!1N?mT zd`VnM{zQ^1C6TN3U!5Su&GGmEXjmbQLyfa_Y{@y zUsD`;-2c34dyd-ezqI!Vt`Oi8vHqTWCajeM_OJWTt0S)SZ?EfF zMUftn#6TYAy`OJ#-y!c`Djso(f7`^KS^m8v`UQ9JF*p7x|MB7xtNg2rBR}!4m*fR? z#4}_cvD*LW$jHCjd(h=FhoUX+&Ydjcbg+2DGr@IJ_ZCNQHSHsX+32jhxu`&0dk=3{P4S;A9@*#b8Ck_=d3JH({`2ZcK9R9Y zZIY)xdFqs> zm*nIAlOxwY?k;%@iXw!}H5h6{zB1FuF<1U!sZNNui`7J;dTuc8hbgnNOTC;8JP@Ouyz+y6NnvM za;(hkZPbwoarpx1q^$o$v8PU6#^urwN3Ke8cZcPQG5sA;6ECQVzmf8n2`*2UwI=Zi|5HJ0iriq5@*h`| zw)yvq#<=t`x8X`Y88Pw`cN)~WG&V`T)+&zxjz?fn=4KtQ_FHO}|9o-MUH(%e`b7cD z7ix=_9^-#<1TA!6@+7$kWvxf?S$o5DDvTO3mKQfSdCe$y{O8!rOf{aq+w0d3E!_w75D|YFsDD9!dU% zWXV)XQj+|cBu|kv0&QaB2PN50(lj8+Da+3T#$?^+GRvaVA zup~baaWH+-e?o_nS}PNha4Vpy7g3lLCplWogQK@d@_tEnOY&t&{!tQP#?c2z-r-6z zLy|R;oF&PhNOFrLe=Et)CHXzcF*C|w=hbX^wOW!MNd_gkL6X0bkNrDIo|fcyB*z^qNrNP9l0dRL?%E)#Xt(lYSkw*Z9-RK)YK{aryV+(#=(5uz zXr0U8Ql;2{!K#sV#@r{ssVqDn%5mEk_2jk)4y&;jo26lKL&9|$Q5k02PkFN;>=Qdx zt@sBT?84oAp^8S~h$o|CNrHcvqJaivKd{A0c8J)e5*8)~vW+C4Ucxlh z%S7ZK-dllbzJxhbZ^+AXYI;d%uD3GhfiBbU2G+lEi z*b7IWm;-y%W5(%71n|Rh z;Iu7+!@@rCUsat5fStdWAWpqR1bpGNm>@KXr1&MaQJo&}^%C0}yE`Ep1Enh1LFtg^ z(+;SGrJDHnB_@LggTohm*qH!RH^~{`;9iRmDPi(h90>@e7k!S)MyOc;mhOQQZ&vkV z@I17<+HvVN$d)OQff9dUNCM)!IOpD9_Nws@22Na{ z7Qx`Ku5a!c3K=ZRx?yJ-0})|I`OqJ->s7Ao;8bo$*v(j%sF^X48Pz_xS$UZD1I0?s z{|1;HU##At0$KQM<4Pg3Z!)hpWQY)1T%d{5)GTh1n~q?=Pc^t~ZL*{w^c{@joa_rW zJ56!N5l!ioo|K4KZK^*rE(zez#4Z~? zs8&~r`}z{@V`Ez;!ZqAA9V!7=9U*RJg#s|J7hR&(R6G7%b!5=USYv-fHK?srHPb`7 zhwE$AX#t9&wkjr#U@(ov&@uFML|(;^sL)wfIv~ODd}zi5_0EVR<=SJbT)mkU2kp3z zW5===Mgr9KDehsS%E`y@CuanSHAO!qS9Y1m*_rYp)Z-X~_Np8QQ(jQq5h0*y3sMCcAag3t+vZ)DF@R&wrBsmHd z;>cYlkZ5;6h3}HQv#nrkiT@e*IF%+GL=*!nq6B+UJK@h@o?RN*6g9V(#F*TY5-@f| zg(ff^ZYK1S+!%dQF$S&hnqH1z51q7It)ri=ek-oZ2~_(^q2N$z>wxdSZ^Bl)Y>>(5L~WX`G@7@ZQ|Djes$*%;U8_jRD%o7k z$p{;B32+(Qkz)j#n@8dJp>JDk4CLy@!O*h=P0RODWu@m~i<{xAFkC>1vDTc5 zfEH!F;edY!W~+QMdAsz9kaQTywoe96X;Z#S$VZyz-(CwLY?oDuiXQmz)n7s1%>ieQX_w2qQU-R)Gg?ejZ;C+!{_3waB> zf6h%xY6q=5W3?`mD6Nl6#~+BgkZtJhpOaD2cA11{M)$GI(ZCi7E^+S7`XLa_TW;x* z580b}rRH&2di=eB_Nwud`{!m=hAL-F)KaH15%@;dmx)S6d#o%@=R+OW7rrLC1`D8A zcuYUaq9ARWfr|*^whYWr`H8TAk36LvRn5I7=PmXyKIF>I92Gx3b&sPkB60zt> zM^6)@r*}k8Q=+HZ=&3n+;^z0Dy?pd^u6c@J57xb^HVEuXqY@vEo^FbsJ`+AULdA@m zZ7+=y*U4t&6-&C}0MIE}n(c{q3nxRmYtK_e8olLq8j`M4zEUSYVhTw{(!hx_q%qSE z%dO6dGX68l@GEM}676GaShuZ2_ngnDjG0x&^=uHB+HHXqHP9FMRVS0HMm@Cs^P6sbGMb6tGbB}(?nI{ zV0iX3sw)Dv=Z^r^S&8pAt7<}tP9B`UPi3iH(htkKDjR!pbYm-2VZU5$KanqsGX}q{ zj^krEBZcp?QZ_Tq&&i66nbHb9<{e|EnMxK1eKI)jgKDFQoFGuf?qB+qAVwij3GwC# z;@x)UK2V(b<#AviP%|G5VbA@d%GqKH6q&qAC`vKGNM_pQ8!K=-WzHXf+sP9`+)h5u zfC^=C&eMv6v}18bAPQO~Zk)nE4Q1I1-`FGJfI4|7LONgB#90=)>F+r&s>1l=sJpV_ zrBRDLl^LImGI}dB9*iTcW^50)Peh|`1D$BCcuGb;BP3Z?iHgV*pe*+6r3;>*16)FR znAWL!bx+)Yj?8Y^^WU<7B-6D(=oXR#(_DNfvSdTo0>K$RjFXcXHz(O@#{W>wV`|fQ zwR52hFd7$sBks}qrAze27F>s94i5oWAujG3Rd5zGIIov0{FXv_@~~_>2MF zL*-H>MIs65ZH)jVb!z}Bp%I1(Q9}|V&niiGd)3%Q!`?QvMZ;9%kc}a~AwNru7r}Dy z&REh86xWK%3I0@T1)yJ6*a@C;7*&C1aq9ap{H#38xmcY^{J>hXn1o^&9Og?H1!4_; z>p+y-jpJ9UP_#ggrX4E}{j>g4oh2BiBD`)Ea-xa&)St*tQOheTZH`l44K>CohssBK zdos(tkY&nXy>42vlv^f^3P_vLAHbd-Q)gSf5}k2M>36?Rd76D3O%`pQbf zZMHRT0@%Z~bJVu++MI}4$v@l05n7e3pMAlYwXxL3uAMf0>s2!j22Yux&LPk+`!24YgD>bRVA=`v2DNhpNyNKm|@h-rIN5dmNu2y^r8oTn>qMT(#!MI4mO z(L<-as?OEPRNXS&xO&Ax9S;=hX-Y8{#MO?h+xK?bKKLi?xkJCp=RG6$l~mW)b_Be zS4BD`@Xp9ET`<`?YlI$V-)=$=);-02KZ+uUs|$^MP8vg&R#_2;Dr1{WIiPk(OVx!M ztXPIUJbSnPIqgg-&Kb0uPvH$qjJy)A1yAPPM0poI@k3zuANN=4Jp1;I>r|N=vT(Jf z&@c`cb`EQ6p$iM->gI#Nx|`Mc#^E(BSpWAU#R<5%(qPF^GM1rugylmZ!o;cpX@W(x z0Ey{QvqfokvL7}(67Xek!6bD-=yA`vek@>P1%6grB_Y7TG5|I?0%lzGiPm2aA>LDJ zJAger|3M{wAZ~!tF!yqGpaG|Itm%RP_E6nsHBbT@wEhm4OSWW0h#st* z@|zkrR8n@h49JsVy@0hSW-|#h8<&5x4Loqv4o#0$=|y`(UoJ z7N7WV%FMyju293~-5=m`22NNq7kV=6JR9wshMol$VqoBN5G(W=s+$i6rtVjlid(@c z`FJwLU0!0qEX4n^jaR-K?Ic(S8q*e!lk018am)|vq0(4{6rS`F@!eAR8a}QaU1In$ zP_tZJ#%tUhnrPOID=F2!8PkeoHSv~0--KLNmX0AR(vvRFyX|7Pp}~}qKw01 zx#up3yW-zr`-HIjr@pK%7k}|>fGuE^u0h4vX@3kG zLSewIh=d_}ieL}d%u;`1O2p_1A{`VdIsX!?Xl`7om&V&SYkHKmNC}aMED8@LyQy)h zURJiC7eo>yyA(PoNv*J*KDXnbW|?{~Ey5lV1Cfun6|@8a{8V-0V7R7Hy$@47XDbyc_r!cEpEY#<*Yj96uv3uqoV)c6h6W!<(v~7dCbE44SH67|CLP z{bKdO%7z2G^6-Ww0yqlC`W<1zALh%l%KS7qnxtfGMQmzbnJB?t_z!9)rvvl@OjRvn zi;hzI4ZD3ixu}MZ`k{3}m|6^(TkT%Aa82R9>)Af_M6qE+-@i?9OhGl=$T^FKk48Ul z^Piwd1bcY?^NNXD=AyNB+6`u25U1VP66}Tj+N3i7fMq$+CH6l7>rD zSHss!RCrbS$#v`0l@Y|rMF#YHJvKEvwHF(*oTp1=^m*2iuzDwenrEqd8Hp3K5?^h78yPb zua804AJ$hQjKcHby4C8#QD<5~eJdy%i=4FS9n()1_JU4zHEM_9_f)ar>d=T?9NNz1 zBhMRG5~~<_l>~X!jD!ADdep8cT=hnyGO#tHQCS|!^zX2m!p53p6{7w!4d;)NWYi+H zya~p^3BOj?j4lzFW7#a5nIh}VZm}uNQPC`OcF7}`e041 zx>n{vJ9F9DI+})938AVaky%>aMo=#bF_~42lFdlaySZ}u_pK2U(p_^1!dLy~diV62CReFJ`HQ zWsqpiX6ldBb*w`)QF9q!TbJ^!paiKKUt@u>+Cuq|Ev1zM)^OgiUKS*q_>xet&cunK zXvHa{d+LwXpMo$8EK9*%FKUWQY?&_-C0ixH3>t1D)|Y8$jdd=vK88Y5b5pZT;=MK& z8G#Wt9}zo)>t!wgLW+onydAbr+!9#M5mfl&5|H0nHKr55^T+YrUvY4y+Wi3 z&IYC{JY4E7i@UZ@V5M0+GyKdgT`uG_MNG~5(%+_SNu*g;fg--#qCQH)*^IEHH?Y3U zVjHVshUqani^DjjE=^hxxutw7%B<#<6P?hBL}IyKzMQ@tO~~>lJ~Tz!0qlXPMfEXQ zxV$NlB;$PmheFcfz!3;J4P9obro3MOuv|bT5XDT3ZiHXJTO^%hBEP14#Z;7#u^@th zNY4Y>=*9l2H>y9g{LNW&d;LA!tZfE#-S!tK!_c5p<-0Hn0b# zenb7a?!^mqS7FgZpCPhREJ53Ll*p^;9Lkv(xUA#xDXj`-fQJU3h#8}CSyqBwP}fVC zx(u;OQ~=h{gzm9+xTS@TFtlX*guya^R|o1K5-JXM2+43;H@k>9{n1NT z2jf5Jlfh{Zs~dx14+zU4Tr}~{q>arWMH4XC{7h!?OiYtquFYxH6afnqut+n)v>Ha_ z%JgE%xyho?WypoFrw*x`G-DFpws%S!R)8YM2K62+oC)wjtQ9r58;Ex{S-(Phu{YL|G>9%vEY=HJxtrInR+iS>PX}*0P1IhM5`472Yl(D`bl*Qe33=drq!z%?8uaz=grUNQ13t&J8Mm1j+JU)9f+b=I zCFxQlJ@oMMV9>3q;8GySm{N3=nfL%4G-hVJfbOBGA5piNc1@I}WP0(TLXe^La@iD} z+^fM1TPtL@+r)Gnj?=Oc%Y=>qGGZBIG1PWwAc$ZGh_B?jHb znk$)XA_FqPA?XZ(D6k{Cg$bxVaRDD$!(h zk0>RAELJ0;+(g1;sM(HK843zHfjUL)G13`ORgZ(2>JB@zN8?6(Pd13 zFb?`;;HZ1mXGH*z#h|kz3W7MUDB_eEmkohZhlRvxflVW$J@6{tNiFFUxm)qBD$2iw zMFeyN`*Uw$!&Nj@0sHPMD!he7Dq!F97B*Z(Qv%zoDqe&^*N`!&NjTu&W*i_gB&2TUexmFAuzh z4Oh`r1?(?WQQ<8tQUUvmZ(+k#G*t$>PkpJ13S$;=XlBd|X@1;{670#%>aT4vIV(0^ z1?TV#v**xmJT$qEuO^@UBR`>9zUwE|>DT+dI^!ijtuhDwj9UL*zg=y(*zZ&ut`^u; zje~*O_3F!hPHi~g=T-LOenD+~)$djLlesfZJz`G&nd5~VbZPlH>l2**`^3aEYu&}$ zWW)5gCvd>H2yowp)pwUOvDm7R}-+r!XB(UNj)gsc{$>als4QsLr$ZVG4SOQLtcp(@=C-I z_L7w`s`e`i8Q`t*#C zQSl52ov6*dfxiEn;u$+xY*qg*89%dh_b+)-eHCOBN1TP7H>r^WRNgv?jdj608tk${ zVjKLbvMoHpqFbYB^&x3h&f%T$GimC;7)=H5o-FG9B5GBQgW)+htH0$4rGA>jPSh-;22I=in*3sA=V$lzh)N|H1w5ImewlC>%IgT)R&{QO9}H$BS#fR$kpG0{7B= zQtIX1Yws}iL)gRKjq2|N?`I84f`t|=7LSF+mg$U`jFE%UEJ+*_f#iZpt9$M*79KGe z8{BF2{kMVf`#%82hVJ2c!|EFr_e4vGdtz185NxZ&JuyRCI>=_g*I$E*!Xt8(BvdUc zzIQhZ=kI$r&A;~s|Ev4oduPCv1I5IU8<#>+`$YqLkc$)djsr=q%5>SQ&dtt1`n_#l zT8>zqcqnS_uivbZo28LMAg&0LdDZv_!?QQ5eG$91l%W15f_mUEs0QhvmqGn|rl-O^ z0mfin2sSYP#IMKlW z`6hH)Zm>?VMCoy>Y{q{6e?L}%|JA#?oCUpbtX2fH zp<8_PhsP@M_Pr~?p6sh{RRd>TnrrEDy>vm2PvjB&k))L*DNjkBe5KkRk>pj9%*V$` z+EAAP-2*3oQ~iS!n<&Y2k~X=YGxJVK3X*(KQsdL zk_JYrEPr`4h(eWRURZgUvqU{23f}7OYo7J*1rIl_-FIBiY?G|_@86x==HGWua+`h> z$o@}MvgjWe1n76=={7k#zDFh5&aSR~rzC6Lxx-f3`MdnTsY{;2=C9;jciyGJ%NwLi z4D8{#_c1dcDz;tc&U-P){k$}0+NndIpyi)b$-Fz)WFIJ|)9&1`o$pyx?q!Ncn`5{# zo%j~1Ln_JfXq6QECftw~*;~OlsGY999c;(}Vx#{hwMC49^f`jSGXINc-QcG@-A}GN z|A&GkSiH|&kPjYrx$`y#kGIkTt;b;e0asAC?}3{|6{J0Pejv)Nce?X04Pl2_3&}@>32aGJ$%%C?+2?XQAZf+z@t; z`e*mbHeov;p7lSXlHZi-@>PN4KiTRH(y%a1ZURgihj604e=p3SA7tN&kW-E(r_cX4&|!O)!7)erSk_bBDo-sIMP2@`D{cdQiA z`|=XF)+VVI^ppWXRp&_Gg{t z%i!F4^>{RR-)RPSAZn_09{1-YyWM#|5RwlT+lJWn%jknazSaEmjV>f-mw&5_OLE#I z=beI1lMz%}Ox~uyBZHVHq#AV}%EP=1)Dr^ne=)^j zIGL^vsMIqU%5BdIpcY}>2@K8+&ynGuQ-1Q3wVgm7YJa7kWKF6w?{ZNyu)xjw>&C-8)h3w#7|h$E7{r-7EbPI#OVq!LHL6fM6W+^Br|(h7 zWB0+p-h4r=|CWe`VaxF-!k%`~)7t;+BV0>*ptxa&J=+l8dAFU)J?&BD4U;%FN{dew zkC@04i5wsetvA2%&oGgJGnOV;MIRZ6& zL0N7PFWYc4)y5PU>OHSEAm$PyDUS~h&z-IQjaq^91d<_VrKPFkBNqICpH+xM3E_%h zO-`o94z8`4pn7>~zpAQnFgX7?^)u@9N?51;5_z(<<*6GoIxzMo_RI`}r|nH;S+B#+oO@uQ6ppl&cr42pkP$@LBzBgYmeAA z6CNOgYx(X)B`|kRxY2*gEBqpYJvjfX>S=lPtFU7_zDETSc{M>!Emitc?M5`{fV~3v zB)X{c-CP$5hv0#EnkP@k2Pb<+t`ytcoT0k%B+&0XUJB2v(oY^-lvU68H%6_0W(15- zV5l-7u!I{Sv&ZPC!s8~lOq)d_QxSBh_~TOiG0~G&8wzV>s1Mx{%0ok^lDKA=|8fz& zn6XeXAf!(^k$dSAMEoRC#N2sq!}y(d(IR~!D#3OP-Eog!>K)TDL43UP(NdqxJJv*@ z$LoZOV^5q^4tk<1>IwTKJ<&B@PjuOy2)Wz!?tt#W_$LXMhn(g*gE!#x^goi*og!hV zmWaCn?4gEM^-IQT=cAQcN0{98u`(tH{Ou~2d00C#4r{x<4!m)hX~+NY{H5wwCE+$F zzyrQ!&k7~nJ_%p5=yY>-eYAvUCm0D2`AUtDmt#t;SB;-M*!V8>>;JWUckLU+bvO-Y z0&zx613}DQWw;ge$v|C#b&znVWo;8Enc24D;p-Efa!un#vjQPXEc*)Ttk5CvL~VA+ zyN#j*v3t#ozNgrO%OJ`rg#S|+2xcx?@Q4xxKlc1CZlb5_SVmFm&2*jN$i@zVZ zCXn;&xReN1zmBl_o?!Ls2&*5D!YbtXQ0-SyJQe$X z7p>oBWERYwLuZ>=Fn>&0w+GzGtu}a6=O+);|3LkQ@^(s+YnMX%1c5wR`gS+(&fFnU z`rIbEIWOxvxg880o^C2`JY;8dzW>#Z@a1-fCc)JM{+?&)Y2mi`M)Dc3+|4F8;!FK! z)C*V-R}%yt6z_-m@~uk1(pB2;bH)L;U4vp>2z3`?~5F){8^!cl|RcmSmmOc7okTI>_Ry-GCRuX zhzNt4y!cAvP-9^a)IX|TcFQi3d|4_PasqQI|2>d4=9GOZbFBntnK<%4uoH)|m;yn~ z|J3dBu!D#a%A}m5}(KJF2u&l^{TRq=6zkg zM!2zuZ$he`g1cD4b)iD&xl^9R=jyqYC*zTscgAzGxiUYQT;tdE+=^V61zmdX<2UEB zUr;^wN%-X`aSD%uV3Eav_!rdw5IF1kJOiwo2zCHV%pK#s^_VB|677?LCGX5!XxZM`Ns^@HZg=u{>PqH{OeNu~D~VYq?4=sc#V1FCPI)v9;PoN=JI>FfSo zVlEskZrXvThZ%p9?2-8|)!PIiJUvm|Jl#Z(K&qF!D%%P_p>Xe=dXLB09G)&%+}Kw5 z5ft}*&nKWW%VeWpdX5ZX56-^`l>SzAzvP}K^PrjiSdKr_6AV^^RqwZ=s$Vb#NqUqm z9Tx1p)&F&|hq$>cb{tUD`)mMBs`OxFNi%%sLz@-?x`*cvIF8N#b+P*;ThS6#q@)n# zHvF|9_2`Fa*Tl&_0%`gqy9t)<89CFFFNhwEtGKrC3;&BF6Yi1U5N((xG}*cQ=&Zct zJDxB3U))=G+VXt zP@y;aBwW$=W6_~&WdTCArCe3S*jT$Zv`4PW3Q7kc+pA_A48(us#4NYy@&5$IruRvY z|7Y0Qn{Ev|d(*9BcQ(ZHv1Cb}RNb%AIXr>yGnM%I!g2}W8{8~k>g(A*WO|A(eVrUZ z{AC33m*YY-a9$O#ua3nW3v7=JZ@RKz#<-ULls_26iT+Fb`&J{Rh`I;~#=nThCim#QRy006v8M}9o^12srw3&K z@_nesptJj6Fb3--8dNZe(OwhvbQpvt#K zeeKoP*K7H|e29`y zbIxRRCq+MDRHD?pMQWCQ-WoP3)!U?@TVVzqk;Yj*5}hhwqFnLG8^HFg4td%@4OTU8 zo5+%pl#@O-ebPVm4(E8}E_kmy8tJxyjKnk88#$#O|nNV1Z|bU6c) zPF80hA&GS5*;z^053kOaPCff%Nu+1bmS~ZMJ-DFTIYC}6lSFozoqeVx7eGbO_tkW` z&`e(!&w34VZPz{K9=ld#=B90DT}=m`^<_HntY1U9S=2T2;HFvzY+nLc@x-nd-JD|?`aX@!Nr!$qP1v$6M8lL1-^fx~b zO)Sr~-D(!5%@VbArgW>A>StrB+fU1!{RKmzJJ%9WJbR4LTOigI%n1dc5`U(hCxw+u};&trQY3u9kNbkOfUIY_Okrre z;i}e@SE-Y^73w>)qpxwJZF+vHPSQCx<`s!!<|r==Pb$s{xxCD$)F^*szmOM`S@K# z(QIRM>x#m8M00=0mjy36rnAMDJZBao;)?6x&^a0LRcFdOdO;oiAVSLSZGN(kOfBAT zityybD>9Cq?Emd#&O1GFgr}^e9w?r(&%cRx{`19iI>e%wE_^Y4GF-dbnH6@}IYXwy zMB3zId+$1jlMOwhHP@P5WDaKEmA{prYw1P1V)+7CP%aQ*o~n~iD-Uz#JE!0onHJ1# zdiV;{{awZDCUOYmJ)HY!v@&|mbLQJWWxr(xl)&{lujoD7n2hJ|laio(zNI^)cAud( zr0-p&wd~iNBIH8PaI}*H>bqj-}O@w#F?i1q`Rvc2g9d+ z+?g#7f$8iY8uCfXt@SJa$+QbA&fO{Do(aG@cTx#fRD183wZ9fsbfjXF#ZTtw;ZyfH zbE4W}+Z^U!Tq&xf62(m2RKH{iXx+Zg(W?zWsbD8H=7Y z5VxO?b`t~?irxHtO2{xvdRCn|p&g8p+#x#Re+K>E7Pk*oAikZYK*7}1J5bzij8W6y zbw6cf$rJfhwj-SJyOy=yEd8r3U$w}B~+uFY1gotpou0&FYn)RAG|IZ%fQ+H zCasG!+aiG#bM+ekcDvkro>(?PE(>e}SC{NK=C4(2gK;oWztgEVlNZFByJ<@^*m;?- z+piR}ouBujJoUZ1k-)jfi!wb}Ja0!>rg*!Q*?}EU_@ZP))8BbbVp&a($~`Dpi!An^ zl5!SFrCsFN#nUWEH=?JHl5d9^%FGC6mN`#0OW66ZUh3S(&r$oX%(^S0J)?q+f~TSX z){*m`6VMiR{eCAdeew&;pYwifp&Trpzgp%ex%A$EDs};icOfKt|-D`kTS`h5zOHi)J2b$nWWFF3q-?R@?3PhRB2*tnx5FQM&G|%5h*X8 zUl7I_*aPuzIgO}4`AC9^y?;dFsuameVa*}a!gnQkSl+RQFSa;OY-v^J=ZIQx&J>WB z_~=Ag(&xY^Ki_A6Vo?g`-o1~pVT?TU)H5rD-M{!q2ft1V2zgzUC~Ivc@LhkPN5?Cn!Sp%R;~v15s0j zv9eDOvmyMj!>w0*Ak00#U~;P+2eW_YG)q-u2^%!lo0dq*ZH6l*6X**VYlBL3N&#U2 z87w`G2YsD(mptYkx8G$AW$rfVjEA5qIMHj)%-U0*5nqPu+MH!l?k>q)}zFc%F7diF-vuKc%yW_t{}(GWMvJ3ydrd z&R^mz2Yux1FXYhI^Xj5Y2vZ?McUv-P4{u9a;c2wUP$S}*jJ{p-#^TwoQ$n86HtgCI zjDsQXqs|IobJjOv7{ggYbuiBA{0ncO+2Cw(8SmiMg*z*`Wq(K9y6~gpaLbOt!Few^ zD`DJ)8wK7$|6b5CxLJJI{eNk;gw>$*q($hWNg(uIjwGw-Nb)v0lB^{AK=HyKyYaoE zl;}w>I^BEW%Ldng?!i<4)matwvdxR|zQ`OW2$ut*ULH))(E{#IQyOL%xDBm4aA;yQ?%a?wti z$Yxqk!W?h^+{D78bl^oM&MC+7dQP%>vF?0l4RTkIgMvsKVkq8CV5P_;ILneXM3ialIuoaef;77x49FfGz1j5x zlVRvAA;0TWqhEa0_GkG(>7NvggL)?+VYxX{gyX0a&C|tl=Ky0V7;d{ZTeJ=C;kzq% z*T2wY1iN8IIR%GQKc=SYUxM4o&Wx|h%IsHJlr7QyV<#!Gw#h6Jv*Y%@B1bZh7i|h3 z`gfWIQGL@|qgDEM`k$WI-{8)vHA-=RKO2-Q8kNgMUW#fDH0k>X##@ z)UN#uwJqHXk9Ja6*Zm(8;>95C|DMrI{@vD&8hBqw{1uNwBR^?j37W2diB)aSseV*X zvA>~m;nkQDHmIiWe}u^OrR)ZC^+%pHWZV9peYWFET%;u2vRr#*%ygzTf%tvJYh!ip z6)y|h&7?1eA9xv*7$s)iSHNF6$yBt+NrpR5>}Id3`C!I1j>HNFb_n7py(px2OPe)g zA#>$K-j=*dAymk;Nl6-RnW)Ynrm1{Ec%Rt#=IP5+W_IaHIriN4;H=F~t0R{e?EGw5 zyK_G5)`^c%zVbdq+^9G>WE(ISx=b`cp?T6FVQmbYciu}rz5$l^3-V;flW=zwFFBJ#Vfo-xN>9pZEiw9A+Q-W9(ZGIou7*|MKDTp4r+&XCoi-RJ5 z=gL=WOYYFlUt6?ro+J)S;ULgG_>h=&BIi62-JKrLJ+Sa=PKIt7{3VTT9kVf+eZM9S z4unXvHx&m)pk_$+81n>_7KSc!Gm){G{w_QPx8VUqLCRb%+mbj>Ol2u}j1XXgw#Fx$ z*W;{@n!DUKHy#!iwt*ucO6?l@rAPkTlFn8IZLt-`ka5L?h$m+4vZ`?~IOFTi2Bx8% zFH*UpJDxG!A(0AMy+aTmFAg1Udr~VL7uJNiUB#C9 z-9Izou;Pqvf^%11B~7j!-NsJa#$9$m4;yo$3`TL5FH3aP3N5+2?0_HU&WOpw?-u8P zT~)>5jjma97giX$2N!I0I*A($Utlu~lUx&EMHh2KQubFPror-{HlFtLYWQPF&ZI*E zlt2)}Po`#0UdwG~Bp>7*V#)!C2j%Alv~u1geZW%_O#1=sf!Yh5E*)McCu2S6B(bl) zM#bU3CdP0Cj=B8gIKm^WXNKo0IAuB&=bv2GVkE#59v}lK3!O52B4$|92rjASg7`_sV1PkYUYFf_&Lr-0V4H;$+p#V_aRIZw)2zY2qtJm(`@euFp{UR zFlg=NrwI}sb|Tk=b>J@X5Q1xh^j4H2e=-gRYoBs*0*58HFdpYvQ-j%r(g%x|vR$Ms ztYLnF(H`MjfDC*y$e^91#$_@&+6^2ggdLpXy+as(pmwax(DWc z)hUEt{iRKIr;(J9VJrC9cLt7}0tU_)1j``iRt*^iB#Z))FTuh!qs|C_DG7N#wD?C( zH`00eUMdhmFy8w7yr^@ie+I(MhKI|3>C0Xecis;r2YO$FSEU^fmlLy;pXP`&tP{YO z@3nw!E!0wt_h+X|~C6{!!lD&*ly2u4)_%d0V;En>l)Kh}+2Je-4YrIx{rZSxeDN z(n}9pWJ~PO9|naf#mo1W`l9p{=;R4cI-5!_%bvVks*UY&9`|^q*~ev{GSRzyx?tZ) z@0L}2^Pf_}jKSe!zvlG4dDWS&YH?LwtA2HjR(GnexN`Fl2mBAJ|IyAnoLR2Z;Np0C zUSp&7+A>|*OLY3$%NM$I)@$w7ovA`5*43#UNNH^H4D6w47do4DHrKUI=Mo*V(XX?h zb6xH2I_-Px1uSr3S*|-<;KSUstCxD2PRj7XlXQwbgzf3hb+JO5ZLyi!ZHZ3ZnQr&W zTWm|G+zr}=fsM<&l%_~$K=;&}oh_QuzD^VpQoB@gc~DZaQyQdlx=WrYvLV1_h2R2y ztvZpCEsABeSDM;nXV}bGk+X^`zs&qUb(eFdPWNO|I_)L9WBEQy#A>$Y6%qyAo%cF) zm!E0X88`q>`M8kR*;UY9cRuamVHH@vkabSEr8S~`7$X_IdD z{ImvCy1H@DfBe^-v&!o)^VofvDU_4nq?ZRT(|S`Xoz;a*SEs|)%s=@e+FPs13MURf ztV64F)Q8RE&91szdZD$k#PCGM?G#!fSsa>ns&h7MAq#q4p^c5Doqk5A5+zw{MKa9g_v|rEXy5Y_u|mSIyLFkBlt3P8 z9&@%yBJrlrf$Ij>81w)ZVI$aLr?Y9lc1WpnV<-#h1M##0t@I=ZwE z_5x_B0OA7>w5nlRK_`$d*`w?6S);{tWG0tqQ!d|V=-lA(p)47zTr+6LYKLwXK!~h| zFsH33cIai{OQ@4^Fg*1-=UwFmmWKt(U#=MI<;t;MHnub(0q{nHp%C8?5+DO316!cI z;Ca>9MT0dbIOj6r`SOpSYKvC_Ew{Ooquqhf7Q+b=kDziR*4~-Sb`dYNNRu>C8|ez|i$*>Vjc46G<>l^rV?O&_dj{nBLgU$D;zF zlUbuv*xa3up(oAkgGQhXduKb+Oa>v{Qx`brQw||V%S(6gz3h_Uhwqk$@49+KzL?j1 z5&T>?`p-;KD-Hv!y%s^e*6hJkw zfBVuQ9J1Y3UFG|jg3}%F!q4<@@Bx+JdNG$7s=XZ% zrj-H*RK$Wv=NQ4hr>pc229M7<1F=O%YNt^b@`W{WaD`bRv4$foaXKL%JnlGNds7}*J3 zz-Tne+RZ^Oc3IY|V`9k^^ul_c%z>MQ)Z+|Iy>OQCr1QL>S+eaB8-9{4j88DLS$XK6 z@?mF4*U^$L(2}k*xY>%-_Gk!xEHvm#hjpP6DQFqsr8i}n_EI#6Ef*QL*kQgk;!L@q zZdZ=;LSQFU2eNoVzcVbaVt5l`=2g`a46*i#RfTo2ypg5WT0BD{7YulUvVte~DD%^;XBeZt3c0?Rw@K7PXP3vVd%P8EjC%*X zR_4tPkJItF4t#+`A??LD^AwcS8S0E}o=w)*Ask{zr zJ4Sywi#W{DQm^CUd~{`@FOh5)#jz;G=c*7xjoIJ8F{_3SL_3o((iP;CyrX1yzOOtd z-<`CMQC0K7U`^h+TpXh$Hd-IN1|t~(bbG!#tFv9XLZJEsRPi4CbSsn?H>FfMkal|O#ps|&OXib4af6wTJq z)pR#BAW>p>*Q;Kjm!i6x1{6hQQ=vCpAaN;Fuu(K9nn8mKiV71H*Kah@2}#Th8l7n3 zmV7nAnfQyDFA_A8FUgqk`}v%E->a%#u(I&auY))5)m_fH=br7JyF3aN`!tS33npr) zjp-8%!MJdFrPX2ZC&9z9IldgU4O{B0(wM@9QM8WATzC;8)PngA=b2g;q?*Ju1e{s{ z+rkrdO*Q5G*p~Q11(+Pkgh}jCV^addQUzrJCx%1;i&aB*=qyBi*zH4q?ySbV860OV zM?sX6OwLBro0qAF%)iA=4$AOEpiD(L^(Os*Y7;7#*M>*I_*Fs@amWukxdnc3EtEuc z`5ewpWS%_q+s@ZOEZpsmNd(Rh&cPrT($@-w3NW#$6gm`A_hTB34@}1B-W2rkRjooO zgl{Jk7`Tbxp!z~P^`DD+fKpfIa%$b2-8{K{*b?XKy0$3+zrMDig}w-&+88ws!?>^f!`kO*|M#acHIA_S!YW(ENyhda&;FMi*- z26GdbRh**)v)7Q>$!CT_m9-6Si*^g5?O6a>kE2bV_ROOaKxS3;N6)YH)~@ce!c8|Pf70YCx( zc^E}OYth*7;ldb_@kz2$m z;J}A#t!{6qfF(%KQ_QPv05j!z8&S<-@m@pphMt%w0GjT!0#mJwOdKDK#nh0wk)eOFh)mhlNQRgOz zCd_X^6PQ9o9}j3-;$pxcR0CfF?m`d~3_QZcj78~nliB=8Eh!1(lW3+G808KfpUeGZ?p5Hd^p(9qY}kL5E*0w zW9b4!j_5r=zr_%y0|0m#(2Kqb%x}cZT1E(Cg>btubbM2l{j4x zk=`iU*yP3`5p(t2FeiWIWc2zu=yMG;EPM<^ONmBvMPcBTPo%qTytA-yGq@%2w%{%5 zLby{t?AD>}&U&M8BVokF3d7Ur0Kgrg@u4F$cP_dXgV50fM8gmzcxPa~xf5Z>!;MiW z3DO{r3k1Sshz7(obz?Pr9QXq;nBgcsuMUe6s+@?R(>k-!hPJ5n#H*cKFfBE+W4IHt zPyz=BO?dt*V#9E9uufodeN_Yxi!&*kAYj+mYcc*(x$L&^V(Xw+oLjYIN=v{3t_%a7 zsg^1bG12ujFXHH6mJIex!9i(*h15mtG`((EX4f*`Ks^v4El%Dx zVYa2IQs9v^!N-9&O0pUMKv)y&Lk%quEUW}H=(#m@h+J6xFzh7fcHKm$yfj=#c@xhP z5!OT)48X?SIKs4a`)eCQ~ILS9u@76flCyt7f;c1Cu*#TYG!#<5SgiQ(i*M$SGayGK$iA;*&1%PFlt4~BB{)Xg> zFAh&m_CIHEa{Umr_7C}6wN-8Xhcxv6gGNHO5B&eo@!>Lz%opt^#FcYiB0jOYDL%0h z0>q(^A^noXJFFZW1IH3t>PfR5&4&C|lC~8Wr-QuD)y{n$8ovn;L^pP(>qzY3;QfbU;?{+;J>R-P|WedDrdXAdIQz09p0&GR+)FK zsu~WYs>*_LrZ=8eT6o#K@>^B@zqFEn=y+nDJ|nUGb{#xf*t}2A9HUPwPQ;GhD_b`- z2W+$H=;#6K)^Y~y{@pT<@+)D7v#|*rlL1E=nQqOe=yGxlXVtJ8y@Sd3nf#0ig~dI9 zB-EeDX-o>4)H3O0@=YdBFnO8D?~rI-QKd&SDPwXWyqfA7S;3ItD-1xLOqGQnI)|-S z$H2EPuL>aw;>b)BPC^U@OeVryTXPfI#q^;eE{>xKVrgC5(15@xC(C{r#N%xlINezE z;p!q*!z-F%jhrK=XB!zDzEmCS7i@}!00Rib;)qfp9#ErU&2aM%CJiveh^W8<)-dWO z5h_ldBqD^y5!@wawU}$9x@uyNG8M)00C2>78m?*ss4li}SerTyZZNHHQ+}g6Ub`^$ z)itsNfl#H{8e(I8W?2dgD1Ze@#oR{i`V;6l-B8R~7*oa)4QBP_x(eld8wwj=8zc4V zV_^%sV|ax+UZb%_bWtYeKwASe+zjJfrW%qkIVX9teIb-87{m=peHqi#D8j8kPq=7` zm`pt;RctmpIcOU`Mh)bQKfNm{sv>HQU{ZG^(Oa4KnwUm;GkRNxNfc&#W~EH#cp|AJuUt9byKj9-K0*= zqP|<##Nn3NgpB(jys#BNapL;(HoShmlnEF7Kfjs@EaGRO?gD?frqibwyX>rN0sNTOYYp_-ICn76=t=9J9guY|nsu_=+9K z`TghO@WcSZDb6?Kk}di?Mn)535=MH!aJ5up9ggAZ1yk4k+l91p5;3RSL-JGSMx`l;s?|7%%j8KYWZ6!c75iIL9))UnRi&N zUx;MZTqailt9ZM?iqyq+_8javRSG-0*+I~O9S>(C2d(3Or%qwDYgi5EqkxdNR_)v_ z2a9+LDTIsH*OlO`T|XXEzydn3`WBwelx`7aC3G3QU7d;!t-lDj53qmiZg^IO#|jD+Dsgr0B#JxVO@AeJ!3N|N zWsccsp2F(H*YP^UgGZnHCZ2}RMRLkQBxi0xGJ;-I-ewyYv4G|UP{?L#tFBd=gT z?o=)X*qqXFOyGp&l&)g(6q65-Oo=eLlF7dynR+Ud>yS(v$mE}poOLXdA0wH59Fy5h zUO@5{XaW3*91Ocroz9=$MsoH#CjW)xoI8-rn8oBFBwuZ2@;s7r?`86PBxT!?l!t+B zb5pQSeo~#mpT5rI9wz9DI`-#GfQ331 z_0@61nM`C-!{jn1H#5192?(N&dxOcRNRB_A$pj`dnJi_phRIeYKTN?sX{9=oKYfH` z;IT}&t}?Ke3Gp1bkqHNCAiFp47fk3NpAcel3X^F}nwVf5)CrrJJj;YVIN{GoPCSjt z6ef(?W+w;j!+xyriDz}<1xz}b+|C4qR42Xwzmu_HYy^hq%8(Jl%M$8`hY7zkQG>k5P^B^)mSJ8Y&jF>vdmN8xY9;`Hdtp`#7#KdX@% z5vIUBZ$#L>8B3$-ix1ZQg_{je7sT*`w{?8GJ$ne)w&}ER)Zgoy=*Pc_; zfWR#J7(&e7!9rf5#;$q#D}#b_7+}p>TTz7%yH$!99mn=*UDOh5a4UVczerag z3%8PTEv*Pa;W_E3u@io4=}mAYF`EFph4|_+A#%u!{ z<7Of1hmLXe9^rR8rzolbJ!dt>(RQrJpJ!mr5POY1wrHj%J#oY;CPuPHK}`41nXKjD z|Ee*z<7}$jlbsL^iI4{ZV|5R!in<8I1s8Zl2)Z+3Zo}PabOE1XUx4r*k6KPRUvGe>bV`_=A>u@) z8yMR(dxRxsZjDJ`MEo)NmKt|N3bQ8_nBzugaSZ{ZDHG~|B3v$EbeTs25YY7(_ETN9 zq)IPmVYd!Ts{CH-m^f`FKXhy7hyZ$Rw5bJqeE28wKlC~^UYltjw{KvXQHZK_WkWNT zd6AR0?V7N`{MgKn6BUL#g0l-|D}58T4s=`VM<+sH8V9?cnz5Uguq@4o{*%J?EeqCA z60J8?Q%jj4lr>MNQ45TFaO346Ku&KhXhJZTO$3k~6!QCkRY|k|9=*#}4u)2%0$qYV z_Lj%7GXa_+!L3f93?}3rf(V8XVD#`L>{$qp4VQxAhJb>q)+BZ>Tgnrpr)`jn z2pp64VIx#TcEH%(5+FO+TeLz8dXHsQEC?j9rLx=bm`(y|yA=d-uV(=UmsO#%p&Kix zU$Jcp+b+-r6vQG4$Xms&mjb(U_ywv^_Qr(}zQDu_Cu1Nk+$H88LP@h~z}=gNon>`2 zIo%ChBR1e*14lv^Re_1Hjoqv}xY#<31-Ei!=>)Psu~@>|qM>S{piYE)l(C%>n}?B* zcIM#(22iUmXAmUV3j~WI5vj~QCyl@qg|R4z!Z4s%65-x8)9=;^|DuX8py_4ckaoNQ zPj~47>zam3%K0=3=f?(bz+p@rw>qqrevIF)+6F(Ne;1xsmmpbt5zE1u4VP5#Now5H ztp+G=VHcdBiZkk)=5FexxoFVb)^5$EH84#r*?=Qy>o#Mq)c-luxD0m(=SVj?`?1_Y zf(~ajKPWs~u}6Nl?(bTP3mk0Uya1V9eIw%&M|!gWq{{|3;fL0V-%*nYdjS%VGy`@l zfQ^&0eT~GI17q_gK5?$vM!Fc-g$oqiY1QAN-4lVz0D)KkegsIQ6zrlusnWFJ>_)+! zs8o5ol1r|^A@Lzv}{ zZoFt-H>A-mTO#}22&BZeoPu36P~lq(hSyByM!s_R(_XEBWpG3FUrT`@IG+iwA?)nr zATm}>^Lm$d+mB4lErtFT;`E@)#9yhiGFxAi`6^`UjV`$I@UP>HA;ke*tQ=gcrf2qh zgW;#%dWKW6M!#gD_vP4j@RFH$I~eao850BhH&H zX|K%X*)z-sGK!#{M)hvLdH4-GJP=S z9*j-T=(7er{h&s@s1B{X z=BnU3Z!h78l=Yls%pI^3zi8r#`~o&DuC$IeKg(=$nQ8OhoTZ52Wj4GgvtbXfFv~`u zrMN})0PZ|Qvpy#;3Si%eyES^lxLd>4E~T(M9MFK>X9%;O_cnrQj6Tworc=Yu1+Cuh zT6)-rJ!-QmL&@F=1>OJ%V9ezHuJsrBk~9P!X*x?9nP8NzT5sQru;KpX@N)eML{6f9 zHfYDMufEf@{Xc!!;eS%(wgvQZ#G{#94gl%*eQf_Bv-ruy{_ncDc?(}#4EQSG6pZl+ z{GMYOHWZK{Q)4{2qFZ|phb-)l@d;&F>dV>&|Cn1FGWln+;UA*5l@a9qxGiAm0p8uQ zh#gnGA)1{%XdkgsMbr2;lM5y@gqcpGhj|sPq0tjZqETP{h)H{vE^VVam4~n>!p2-y zewa2hjs6NB5975Ay$(VE;5W!m8wBgkK&0sGUj9>D1+?@aF*U7G3`7Py#=VcIH|c2z zNP42evRou-y59`E-N$%^f$j5ZcH>|fR-|$>q!Nva z9n8fifPL5_4ytO+x6Fh?EFy{XeUwmEMf_Tw(u8X)hR1P@#ge3d`N@(UxUmsmNPSBU z=WP|kaTgR99Nxhb#C>?2k$#1{hK8@@lS5$PtmX%!m8uEq@jfQg0&fL3Pda$Y37(D* zo_HOdDK{#3njAdw<9;T$F?hO!xXGBbk3Ut-41Ql3Jlz;PZ3>3}-L*V36h zJ4mD>37)m$ydTg(TB=w}-*zAN$SDdjcdRn#c*~4AI?|FTaU*9BPGZHuj>;5crTtMk zeR+^k!6)8RF2i*?Z-J9>oMO~fka25};Yke(yESi~;@wTA_V%EV=~R&M-5|pVx1Vvw zz#zlOVvsQ^$e78eQDW~Tmn0XOcaF(bb?EmQa0&zBeYshjGD{i^AT@h1ZkRpy-9$JT z1QN%L_n18jp_cHJ+RVl-`zsq`6LpzQT-Rq4S;|4@s0UPoZx1qYC%F1daCi0zuJ0xq zGMjirno!~wjr>T(k?ZTwo<>rO&3Y zi4<3!@jNbjN^hqd%054g{AV>g0MYg(AZBNRcG}K@BYPrZ;sx<%XKa$Y95?QpFXpQx@t(OG^Y%?vjW+IcJCP19VX(uGxrGR3a&_ z43$LA#N^~S4D$Px_Xw+@V&K|TOmffrY zMnDMI7F}6q5yTmbjHim=HRuB(l0gwZ0Ta_XEWg<&znj2UPm0uHMaSxo}ZX?0^ zNJ%8o5^72B_#||^0-MXzTVVrpP!j#a)3|7K99HNsahx#@NlnAJ2q2M`GmxdnAxk$R zi+i=kLD#z=Fmntq4n0P-^il=~Dvw;dmpX~Qa7k2j&k@+|Lp?Ru$2Wnqu)Xwzb5~^G zV|yC?IvZz?XJEM_I*tVPpSl&nZumaC4t6j!Zy$Q9n#b`5a}||>7tvddW?TGjTkc5} z@kcL>u$GV@MPKY{X^6W_gyI(Vh-cM&R!a2XaUTuvxJ3xduwZmw!lq{0<`H6FDU(wx zMD&m>_&DYM(rxVj5q`W3pJxkao0+B<#nUT*9+jZ4QOVjAnTMs6 z&eSxIfns2E( zvqTq7F1A`GMj6D&MfBM`L=x0Z!9J~7Er6t@T1r%Cv{9td2K7vDzywYrnkwhxJuP#X zMs5u<%rHrZ0@$5nZpY^Yl^Xd1i@}-6bTN$egNq02hkqP`HNQiWqUN+TYOdN26E7WwUD)($+>lwY4Ws9O_uyxT|P3u>rsj61ffvwJUP zHkauF=H(;OfR9(cogBGH+GOA%53jQ}^C`@XbA4{fqcs{i9?qbNEpUpFw>(QZXdCm0 zx~P}>+=exB4B^Z$xp+NSzj6cSB!rDzqGDcWZN|OGBbUN&AIWcGgn#UF?}#VdFvkS7>kVpZ^bGR7Vw^#FQ=D9FeK?6eEOOJ4;tV2W4Ko}0SDaBy;D zQnS@85(~R^$fN2KvU{zrh?f@Y=~JN+Cl!~T1+xm1oxr0$D{?kP$XCD6R24d!kBinO zm5z^?@1jCg_fkaK>sF*i?wyr>x90v5@eSLYUlt!+&1{ocQ~-8GG{00APoFwoM*{00 zZUwC4WZ+mkU&HzvOAF&l`KJ31bHb6Wn?=IpL&dMH)enu^o=#vSaAjokn8tfT-;2iYWUL^P|qw!cf%Lo#2 z6MpDCW{O${U~7ZWVBTi^0Wt?CM=jGic+h3sLdv)sIov+UZ>ikW(~-*sxrP^qO;wkg zmb0g!_JB>S3V;kp6H9i;Z)|oDzN%xIHL(^S_Sik@asun> z4Onln%IU^luwmROY(qDQhTS0DHxM^VM@;C(2TPl1dt+gDj#;l5Y=Av55sjYqV7fIg zJ%RNPx|agx27OEe)&oFRa?oC|Tro~2c2eRhB5c!*eL{vA)4c%&uueyE2Yu`T)^E(T z!-z)8VvZ4}85Pi_S+#a=DK#0i784|SHw)+k(q(j75=*TzW;QA_=F=1$BL`!^zrm)7$41;vaA`4&F^;~*o`1Iqs*$S~aL*BCz{$jFR3jXy^+0@&@N?@}GOFReJ! z0U1vo;E0tJXU3q$Z}GahNmD^v{mL4wfWA#ecssfJ2`G5YkjB{Wp_N`j8n)lIHGTlNSkK$hNU=*#F z{swrMu$@0h6Q1hUwxvtQ_!HF?o)0IDuD12#U2U}C9{iB$B9|0r2J#AE#Ck{nEbr-@ ze)t&KT=!V|nM-z9TQueqb!EmNj{9{0)+%9w4gBbm;>>7Y!Q#FkrV%V?(eH>7e=u^a zx~i8hF&1dnw*vMk_)YTa8f`9*88)p13ydkQMB%@R6I?uv(WCkB<*|0pm==mi>;$>E8FNxb+@q4}+eB7+##jhiV7KKC z#XY5|-~_4aj*GaA{RD3KQ2=iGy-HnUIx2Wdm%BaHH^jSPB9nx_g$x|8px>RjQ`EH_ z?}UciFQKCDPa)(YV2SL&#JO?AlO`8WW4I5~ky>u0XQb1o8na7^C+X5u9M2Cgk*F1w zMhEAf0Mlo0BZCE}sWs3|;tP}*@5Suy$k-ln4T|{t^fEG% zCIcUb`-lsd{OWv!OH(&;k?P^!VsaN@fFWg0N<{n(?8sH>24r%*I0wtv84WXb28bCA zU+Fje$Z>3#>vm}k+sQ)Drl@;uQ-K_`Mi#0Y1B{>b8-DmlY?!aoup}wx5J!{@rAo00 zRL@NE5}{Bdfn z!A*dqoaGF!pmcHtNfFrV;(opKcu=2x4Epm+>8+(p=lG~v_mAptHhlocV1$Gh+sFM` z-JIE_yk5G5CB1*(u=)Hjex>3x72I~jA!^?fLnVlzdoS+LJZ0{tC_A+bE44hsiT` zJg`q#heUBEX6+~_m{!li?l|ovb$gooC2`J_XBlrn#52Q5@T{vMW*a@l*3)!HHq$B& zPU5(xRo|sFbk>>ob#jjS2Dpi*3H+UiKATN$GWIE@r(t6-f3<4cZlr|uI(%eiE;Twc z1;wZN_PZ9HripXI z7YBq`l)gU`7g-s!UP8XzBZ=;H`#8Hl9!71YQAXyA`GeG*nRNMjkC6af__be!?>v@# zXtuff1M{W3Q3G=S3n1g0VpxUXA7OWnjj2u0B$JAQ?k((XbTg-)rKN$s>Xngtq7O#0 zRO!d>WvR`E z3_un4qV>vGvS+V&7w3zZ5f*d3RPY733O9}!lWd`w zVd;|lf!ds=7tzNl=wk$1M4%%5Roh~J+MPBx8JsLtW+ES-H-jL|>M`o@qb9N#JdcxZ zEGA+4f-+dh|B9JX;8SHXR~_;)zDJY3qot)%V>`)AT~fq3O-1D-Jq6na^rR_~uNY8R z!A22F{R)jqxJ)zgftVv!19aep%49`>-8STx>Rz*X1?bvsEC3k6HWnoDc?Guf)4A7X zQZY8uR3b&j4D1E`irqNlVH`>(>ypWmpcyk)10a823@nrR4FpNSKA^rOdtscfm`y!# z592sFI$1|0iNtI0ITemUyaopqBQ17*F8gI#&>j}&xO6YU32eY2shA{$UJ24mC}N3* z)^TBp>392(ZEA}JLs)Ll%b*^W^yxILjW-vH|Ol>>@2MLG-QrY&C(U0=- za$P=U$`p*9?MIgOpnb>^bzjiuDY|5m!6Tuk;E{|p$t{hzhDk8^vdu|Q03sTU(rsjj z!W1G?j*SU5ASg%)j0!kBX4Z@*1G;Qi_hWIEAs`eAp|mr}#|45QfuNa_iX;vpT$%*} zkW1B8;cCijRZ|O(7U1VHm~MuxsA< zk_Ng(mYFVFNzypeEsnT`9VP{^b3azw{N5%kkN4;bTH?;KfW@Hlj6}r|+`;Gr26nw+ z;ToEAJ~y~TYRl~_cB;TdjMUZ-Jkp(pW{3FznK z9xZ6Z1umg>=La_hN3}h>`{uTXoiGDW=s)1#r6STmy>M3QrME3Lk!8J zB3%MyO2v|Jx%-fhXtz8u9fCmEZ9`sA51UPVvUyN86k^LD2#LtA86xm#3-GZ#2JIPG zNg6xi*#-%*bU#ene4$wgXt0c}7Cu?dZ+ zV`L|wXA*?=^){Fh+v6$_z$BJN9wjD?5le#`ub7~xQoLGbRB#|Bmg|Y*Dsg3}rTKH} zQC&$EHCwVurcVz|_l+ehVP|K&0y{PYi&P)M4fsA7z*6esx?;jqPze^?t$?hx=!xYM z$Kk&FN`o`?XNjIZeYzDT1G|05Lu!XqN|P!y<{Kb%g8dSG6oefU=!9(Lq)G;T(uV|L zT)cu%uq}RNw**?-)W#T8V7SBC$U*Cn-D;-=G+6-6oTQ;ye6t4Uh?`qL8%T&x{Y=99 zbI`P%kO=*YO@lN+K!7eS>GTLh0|G)ZFk>?0bM?>2oSZg}>0#8=)KS_4dT0+Kk~wa^ zj_gx{WkU?TNh8Kq4sy>?-wtFD<2nN?97dQ^VQkSfxP3-&Mz>a0Mqv;@BBG6|y4I3R4OmE)d2q zz=pwi3oedF8Y-xaID$;A&x?Ohk6}v{mA2i&Y$XQW#!?X%7Si0{sC{MF94t4Z67Q%t zQTS&2pBGvKA!V*e09!n!Lr|6>S432oz|6XrcSgUtKenO>-r@5tDTZXMW8%c<}x;W zL(b$EoK3$MsHZhd*GxSHd`ec18dfG7Lf|9tcEOt%EXbHY-VxcchmG-elEtwUyMf4- zv;bvc34pFcMbi_&Kywpgq{YF2iw(}bR6P@tBLbi{*w?O2p`RH~5EP5FE&`vC3Argh z4fa&b;3yDNp$;%nn+o|L*R{|Ohh$hqKvdA}a5na!Ew@!Yi!Tw$z`?57-Gp&^d!UQV zj*M){MtPYRr=HjysEpK7o3Arq4@xyu1_ijHkUGFp8!CfhV8>*l`d=hHdNp%O5%`Lv zH^V2DU`3!ZW@@O6l=7L$afN|`%E(|%@fn~pd<`kQIDx(j21Ij*wcEmpx<4j2o~@t%6AI;;4@3}wjodBQ?=9xIJ#jv%7)NnY9Sx3 zRYE0$&&Jszf2IEKrt|%NcMR>XzWa9>0AcV65DXi7p#eys;~)YU&Bzu8#oAYthDVj1 z9JCJ|uD&PCYShNxFM)jv6%Yk#SlhK@(mo`nUhvn{!RbIBQF(R;vSqrHZjUR(cQyic zP6_qUk&Ut`(_P#7uyGFOMXUMFDG9`NCJj4wEAtqX?;1k&kw7?^Ke&klCFYXr~G4cdc2C^ zf_Ob+OSnsr{!<#scEqbqW==anfnm}w{Z}7#smO8uw@1m-7ymkhI5z=}^ zxf_K$*1#ww2~W3(Xo%Qm?0#f4Q)WCyKCti6-x~o!W@QgLhTf-s;HI`sQu)yk#2X4| zdqC7$3=`yziqm-g4d>{obVnP2p0B=zcR4;$jL%tO@ma)ll0+A@6WFy$BM56H{=v{^ z)eqARo|&Y{j2rZTTZ4T~Aeex!H55-LAU%2+dkibsH{O7#1`Q7g=Cdk%J%&0H+%F0l zgN?Ie(l+!N^&@a#4YtbwH)uYf7Qu#6nMBm;M(X`a>PcK|2D2mujfkeXPN-*hYw$c= zgm;?JGWS6{pC8(XUaVe%i`Q^Y2!w>g_;*k;Yx3ECw+}5*KmG@i^2p>%i>CxMpQ8R1 zcIT+GR~k_OIx9J7A396@o35595e_kO%3o=cNW6IlL#7mfNmCexZ=pq^erXYBuvz>a z>sLVeKu`-2OP%V=O$ZZtC#vhr(Jp9F@wB3N55{D=+H1Epx8zsqXr)()%ik+;;-n6r zVv97kROtND@&0BdAORkeKooSH9R%wI_%oTtd8`MmFix~)^HL<`J)Xkh{ z7>d-v(Z)#n>KRbO8tM^N1_~J6&Pop2++FH5>){Sg+RqJ`4GSE$qw>UtX%F}f zl7Bxc5c+JCpaa-H?X%cX$;g2H`cVPVXQLUg-{`a0QOU@F{j;M2qR&PNJ1aRLFaEsG zW{yfm23_7fDj@o7Gz0cqeHJ?^85ywOJ}MykY%~M*JAD>ADj6BDd*36*B1a8&)^hNR zqk=-8jb_m0mwgsHDj6BD|MyV=(PyJ+u;;7y(u(!r2wHjE*|7HsY_n)TGXQV@I4N-*W1FI(Rhnm0K0wEN9tGjXvQqwdWb95zLnD&awjg7 z6U+T@v)KVvTcTg-S2+V;&8W>qnbv-SDYk^yV!wAkTy|rNBv_>5?rufg!q3na&N$7Wc%3lhI*hlIwRhw2b#URI z++lW4HO}Kdl9TfoI$FDyo3=(F@i&+UTL$gUQ}IpO#_d!4P-yK%*hGgq`v<9)4Gl>? zw!;naAefLegKFixA*_Bf@Qd;mvifE|HSpr(oh*lRfV9{VKMYMz14p(=jh24?AL;Z&( zV2XBfDBKdTZZR-8A_0*vWJ5`kP5-1{4SA#P$H=HZ274~`ZQSzad7mWfp2Q|<^`F)s zEGkg{$uc8=k@^S;J{%*2-=uc#B6q!r1D4ECHUmvJ1Z;<*(|bTnx2yAMdal;jL3UpWs~#C+`72cf9CM z7Y4i|xpO-{OoMl16&>V#5p%uo2A{FV^{<0WvsTG&at=Ossam=e7O4ME z{{&y3bSLg(RR$$VvFB6pc!&GZ1Hib=V%CKamikZFG{~4- zvK`4RoO{igb*rgiGiFu0SMQ}5BfHDM?i_t5hED28+oHlUL@i2D!xjsO$!t8$rc!A1 z@D!(jHCFMrwR~#AQ$r1&;xq8nbgk()kCyoR*;kxQo>BN>pzuTMh+nIZu=`YFKxbd- z?N2szFh2+R+>>f_;O?#!gS?xQJD^qn|t-L?F!ppf|_)AAppHv8*h;I7u$BJ4gMu;#U=yze73Rhf5N1Ed-hwf_k@;rQ99ePFfvIHhiGp z%2y8V*=~3*y)i-1UHJo+I<&RnMN=QR?g-G(Xl})^DKrFj+nGbuf3cGm|IeU@W?#yd zNt$$m#0vv>DS{-IYzW%tSFs))ChY_I65j7)`Y#zHgN(b-?QmA>XyFa&|75mOAgv%V zBV&+$bP(Zf5V{EkfynKPK)2ft1$2u)?9(m2HNAQ!-QsJ4F&RHZ?Pp^LrEPbmH8~r` z;xN;O&(QdWao%_LZSW!NPsZPJBPrX*N*ugRs2te>f|0GzQ=F)_U3>Jv*!iPHT7uDz&_)kIuP*D>?y(y zkoU{~6qG;5(R}8|Hpw69&qfpU!aTFL1=Z7;XA7n21$Skaz-~YDYwGu;AQ)#f1&201 zv6inHf&)=Ww0pa|mOLQBm|2{o+q3vBq>W^WM3N&DPe@5CgB_>+LLI~p>3o%Vn6*-J zEVX#?PtW$h+o#wh>Vj6&dXAHV>|}Ow&^hd3^$F?0E5LS)?+t++!wdrWjC_v|UR2cJ zv*O_i6T)s7AJlHt^XjAc3I@L8gKx>q<9E67L7ZlM^hu*g827I5v*{?(B4g5V@?`ZX zza!7=2@@odcJP6u##w$leokmY7+=v$bPu%Pr+p%5e)8*s`v3mh2nTnag>e}=zEFYh zeKu6$8!9n;?uDP?5ZG{j*P>a#BalMg&u zWc-(uW1CqNVKD+5_UK%dypSi z|5t0Z^;q3cz1~mvSNr1Bvq$7;6L-BdOm;;$LLL-2z!Sv%hIb^#SPqTS>1sSK6)4{!I@#<2I;4lwu20FLX# z8q0jxV{cY}^7gj_?5p?{Cs%N1{o^VDM_%p3aXPiL)E(Vv3`TRz`%Zr2NF19@yz7ox zX@BIMr}OIEF@Lb{m$EvJ#i*U9!w^BQysa9Kb4N?|{^Xo~?&y^kcE^}n^=Dh_HbDws zb5I{a8)42073LX~4y(oi9+H6o)MK7y1b7c&e&ju^R^-APn=_KH`@N@Nxa}*Sb|cpv z`*SP*;~La|6E;wq?v87;k1==5Z2LG5LonwxO!WYmczcg@*{2jiItb`pz-aF9?kDAT zf!ccS8qoMN)qD&X2)y$axrm+*x-H|~Hfo9b9OrNvk2jTqNu%Ex0M2DTdpxfWb(=rL zz%&l*HqbklGwT?ahOk~-BCH7SyH?dPXQ_*9Ot$~#WK;HA3zEc|6A`RYrF~8knRaxIz~RN{s(8= z(3|&FV|A)GAFv6`o7LP8-LY}oMSKNS%{v3!WZql)bwg=Kh7Su3u@g8Z8_!SG7>O2I zp0#>$)E4zcCgv?A0yZFG%M8KXdkwe=(v+cvat*8l~ohzML?yo-7VT`P$>&0I*sdDrp)Ac-%mEKlB>e_<7oH# zY7{4o9p0^~@dma_r>gNArcNPSBbnN>lY_jl6JmAT(ujui?mZwI;Dk+Uc@MF*KbFm1 zBTeevA0Zp}Gw=q!xsUPbLhtu#?vuRTZK8f>2fU0?o7_=P<3_%@_wYw8Kcca8r?AoZ zs%>MoVy<|HYFx%PN>IqZk`F^o^$Yd@1N8$1Rty8nG!7tA!aVuRI4*cSJ&?*`ky^`I zY7S3wHV$;hyuof9OwOBvArW5e9Mj_T!+CYcAXMAu#sG{Jorq#JIMgUPjfy$N80R^k z2$u?0{6;VC+!qF?4S=E;6lnf=t9@OHCx|Y6@1XMnyM6SzPJasOIcXxWJK40*dx!RG zziN6I6Qp^&2xbO}crpZZ0dBZd%_GyVd6Z3Xxa`rz*F@1hw6G}E0xDzg@`+-~S=;uz zZR8qffV4yq2LljP!M%XMt`VnUa1!pv)a3jjD2>gv995K_^}a!fCm@*{K`u6l^@6TX z^A6BF$6is{4R_RU%4ofol8^4PbrP@|fiL(O`1DT0A)l>^Of7Y9Nk; zz~*T`cRODflI&@^COdo35gFth;~poqQllWz6C1po|1dh;Yw%LSjq_haq@=fa?)>+I zaO3-O2!t&ziPUl$2;DF%_7M*yIpK+2?061$AMH6K&Ua;Vm|w|y^e=-Zz>zXpLj z#N|`pM%tZRmXoT?3nkIwJIMk0ctYY|#F%5{puOOy4x9;l!^0sz(tX}v&}0@g#-$2} zye&))CeJT{9^nU#%=Lf8{QUewNd~zOd5`AE=e2?ExA5e{o-oEa!Mm?($*rh^k8aDk z_7q`pARcmQB5~)h<`W}!=R@1}YoJBKdcm7&UBnFWV~DxB5z+b2D}*z#Ua%P&4Nwtp zeZlR_ff$HV&(bgI7&+THQNOblihO#Ro43i$dzymuaq|34*#eyS5^DHhO;dS4XCvsu z@7N?TIviHY`{SPT-*;hQ@^D=!`JrP%$Qk6Kdfw9nh`B-c1%w5Ng!e9kpv(capwL7s zg+@Wh-wG8kTt#hglMTu*h~ahJC<{CPR_7$V_i(&ZS8E_XpF$`jq^cMmUVv{x^@Hz( zrw{m)`mGs*cEL6{n@fK$3rXOa1@}ouEbK9Bos-Eg2Pg~@F@_Sbj1Nt4Up0v3BmDzG zx;IRXSIuh@ET$U#rtq3t`dC0ChKTknunh)wTVb;^m|)+9L%RM)K7JQiLd$R4yIT2? zsS8elRYVtvsHJHpj#O!X@e#d%*EMBGl4!N<=nMZi-ktf2oFO2_1uJ}dU2rKXWvHE( zpwur|k6%|^>fN7n!5Yj?mVASCt_3~uYKmhbY{tp<9^(12cW@(?pAIE2m_hqNq1^re z;HZjlHuL1xQ8`X7#&RLN*?x%%|EYrGd*NT$4u$eU_=5cs!BdpE7myD?_XFypethCu zlst((yy#>8#&Qe)WMtVNA57>iU0RFYcZQ&9Ma3UJ1^pcVYlx$qS98>UFU zj`aA(C0x{4x{ssyIx_GLr(IBn@Gbg3<-HSL@?9oB^vC7G8WiEUsQzQ{WcfXS-9CPz zGYr3T5NiFP(H;Um0IFa3Ar@%*j|2ARX$+rk;0CpW( zhZv-OJCsDvMSdkor@Fw7M4eMmaUmQb(j1(AfF|Y>pXLikqD9c0f^P^9a_{w0)EB~A zDP3q(OE)5;fehZ>@F-_Zx@FPaW` zJ@~r^=`+ZE(Jy?qz6jriP@sLHqd*=Htm_8d?cz$Rcv_MRr_#mE+;o z{)I3r7q1~RiVRNprW5XMqbF^cih>LJyzh}}`w7NN#sD*@3z!~6Y?64r zx9gG-#+84V)ea^valHHao2AGlP&JtrvJd^xS$Lb1hq68y4kz16jJsfadkL8Vy#*Pz z*eM@o6FJ1-`b-QK5QFPY?|n2@^nr$vgR##$qf&MtK*IMegwxa;?A?8t?JUDhH^BP|*O^MR*L$xEK&PK5gmFOECxj6qxz4E(8D6u1zNT;x6e z5r&_<#wq9*%x(4^j7NUv7PZsU#g7+pYVGKs&@)*Xbqn`-cd)UK)uOfRN}Xxv&Mx32 zuR!DuD+e9p^PRB>$6yc7+XQxR7fg;|Pu6qK4s(tO46Ki6`@iVP%>FOLtEGR2!OYOS z@ay~y582s+j{LYY&Ws!e4bqst_o=cDeOXM8398{!wV0gci|Br}_>^EGy!Z@%BE0wv znFwdF^Ws9(0~?shFgSUT)emE;oP5L2JtoJC>yFg>aG*^OB~eoPY@M{l)MVnMnWt`3 zReEKjnG0epvAB#U0y<47g) z;G^dOpTQAdaSoI1OwMA0=_@BMnm{G7u+>~AlKK$~A>Y+C^`WqCXl@Gi zh7lsS%Z|r~QkNm7aL||$k@IEvOpuwNE#o#rnZC(yGR-r&G&ho~Dh$m#$KT_W$d9la zX<@2mm*O2EmrvEQOBt}@3IYtk$H`@jVOEx6s%=3%%O^Ta%jAhOO7kS3_?uWZ`Aue- z%bs-$-<0w0DE^f*iDm_@K2ODYlRSyygqc9}^G;)0mLX)KE?=LfA|Iud*q^*?jrTAo zGzXKHjmNwY+W|LW2O*;F%ecu5Pj4kJ{|wb&pbn@@XL#GImpqf59CS=L$(f9HFI}u3 z4`a|ehZE5|tCu{%mc(bj+e4u26Db2lwDi~B_ter?-Lq*Z#XNf3b0ofS>0f~TrR#&z zS4u%9@0!vwWDkE2EJ zPNhCD{cfA^2WKhnmFOQX;J`V{##a?!7=}> zKiroskl`k8Ea)+YpQ_96Cgs>|;l;M1dz@+L($d!UA7-@ddI3NvZAZxR=RuC;XAn)ZBSaB)+Zi`F=a@BF%*sGpx9ACUAEnGvDwjnc zxr?u5K~1xD!mRln^P7*ig?=Agdc^p#^$_B(md7ykqNbNWkK(~vAqL`+J@~;cih@o) z?7@4TuW}b!b49tQy+o{0H-@ogzOEvc2!$tT2m6jZFQH?N*a*{58Lro{x!9Uk(-6gW zHM`AB>u@55{bx1xHM+hkT%qSR#lkp4-dwMnP$qeOquC#;*V*a!Eu^F_uDFM?fNu@*63S!h|Y0vYff-^NY$B-tU(xDP-| zSA>NhI?w#2QwBy^@uK%CTG5|huax&E0LLr^g)s^IBZPg$iWErV@H2ig%NIJBp=#@nP?+od=v%3dqWPty2*Fq(#P)ek=?ceyUpUCTOuJpFx+kf)lMAw}xXmIgUGV!(d@1I8lxrcYKodV;sKb-n-T-m|Vl;CMH{%>|*i^lb4vh3PhFB zLA{O&K!>xk2NRBU5CrC?xy&KNIKnHmp~gkWvez%>!La*85}9I@UY-3$p;~u{pf_%0{s^8&1I5nIKRC6)HBK(+|)r3f4{WW^`UiikNxS2-pt_~g_ zPyNcsq}#dIU5W2k!p+>ntq8|qIfDdwiyj=ijO#$>;|{18__`{Z2>Uc|J>^zB^q>7O9P8UQKPPsQqs1C3AdlNJ;!7pll@FS zL(+aclhX-0D>-P*>vU$ZN`wjL{jG2EshUZg$y_E$COeos1E&!}Bm0}c?k^*ZR$PMK zo2N;^)8yc(GCHatz>-RV4Zq zh| zn%_=#z5uKRug>q=eouJUsRw_$V5xIfv+on{8eG&&{N2*D*@ zWIT_;I5h}-pQp!|#nA;r^D+IL2JGtEo!q%slOU+v`D3^JH1~`f-6BPb98fD)U@rrF zA3R;jCmlRV?kW7OAAdWAPQYTw>q>67TKW;lvT`J+c$~_vJSq5XwZLwhe47(@NBx07 zK2`7_qzY{Re(!$M-IZ6G2GR59K_&7+6mtn9(W|8Zt>RK>69V3$rY_+fH<00dw8;{fgocKrv$^wQvoo)C)2=m6)( zz$%>z4RpR>sfza(_^!N1*iDkR5n=ekwdumk~apA1~ijyE>*KI`Kt{B58!|(aq$N={E zYn(C{fg`bU zn7pza2UnJ+PBrmJ$Ak0GR9P8%d1IXqyJO_NP7`#>gUx`AN|xvGlpRBZjisJ^O$qBd z`{|6liX)Bd_qit*8&Mc8XxghHIyK}_1oH>6>Z!x7SbIlYI>)Ka%>)2gx&2k4zA^`-5|p@V0fTV;So?SKo0Wsk@Nv%E%$E4!sUEY#2S)^r(DGk(QbwI^ zhkL8DjfegW;1KJ~NTF?HaM*3mJWeR31IPE)#Dh7eiHxq2Q+gr@j~hgRSYDOHcnwZo zl@#)IOMHH48#~aM-!0FOTZ|L7I>=r&+Ll#D7+sm0i1Y88nXBIO&CFH5hI+W_ed?z> z*wy!m%qONn?8o~MhHmL6KJ50qyPWgD@>fsqW&^Gk%}*O}^%P&y%#*{XD&~fQ zCk>ESS3!Ld10}`*ukR3ZS$d_avg6%0;d1Bvv{{an!WjHdyZ6WB)w45tarI*9g=qum zUP-?Ggah)vY1~TV)zhJSR)sP+;?WCbkbK<}&c+^e4xj2Q@RWL#z6lx?++`#XuX~-n z{Q=-!{al7@;5QZ?oP;(efwNA6ISt5!`)-FOoC|2y5G49&DL%@}b<6{56^`xiTSaD1 zO)Ul|SC#!0P{fmXB!UnXwykY}OAA}DnrB{#t-x-Z@PTuow1~jdjb6&lf@L_XOe_Ps zEFXkR8HQDl2^l=4wmkw0;B^;IA@AA>ojUp?>ePeDRa|zG%|{P@!7?wyJ}tS5@W=SD zJI9nd3w;x_>Tb+;p`C4|hfZUq-{IBlh-wGY-M%sO0NtrQTYVBQ|hLO&gZEQ2rgY`YwTB216h`*rk4s5IvIn z2x0%A8)N#5gI~^PXhO!=^iOmLU}q%A;4{-zssbI$+o=MI)0$DD6=RJ z*T9R|P4>!YW1`8h+_IIL0q9Bcco!m>pQ`I$3>-K*Yk2jK$}7ElAAH<*)QXciBt`~H z{>NFYcW;G=ypvpwNe`zHnE8P-ZZ#X=@Of-xbLjz_IxsUl?sevLu{gH0&>6J3vLAtdoO{PB{XKl3$xsrzJ1y+C(#M=7q~)K0F<`^Yzs^&@ue*a^ zCjwGa8iG4VqF)n(Fp29WPvQjQiNx@^2gK-cvVZGO@Z0Jq6jWx?fil8 zV&~NRoy*+o%e_Nezy1Znsq6O`mbs5#%M#{EpGIP&ts{*mnNV8(GHh`z*kav%v}aau z!D7#`J8zqZct}yBr*M{Q@(ekhanRqcSjB#;(5%c3%BG>UHh_#_PR& zy_07irGf1^OBhAF28Z~&mTcnagfTt;#_>q*It2&h$=i58&gaF}vH$8UXXbDy&Q1S@ zkQQ)$)Qleb)}6fpN7|$pN4=8OJq?*P3J6;I-7)5PX9Y9MkfbvZE@Ie1WDX{;eO~(E zP3hXS3*hbwd;cqE)4%FXm~*1P*WTfddKz2jankDAj&5yi`U5o6wa?Q);tG@Gwa@tZ z26k)Sl}@X@tYXt%Y!<%unT%4*GIDKM8G{4Pd=8wsWJ8J{p=Qb8;7bzrVDh?LU}^7+ z$Yjmy9CkaLjbGFOf3Yo-k*{<39x(ECgZ$nEc)FcGFzkEnTSV!gw~N@OP{v^(#MJ^p zYNsq&oNoip8^+o(IrH~UJEnKR)f5YPHHBiy{mJVVxRE`0?A9}c+|z~bI(bjw%ENxa z==wtEwwD84HhXC6b<+*(w!E0r!IOmMLW>lF9|S~2-_qs%y4SjamiH9sjANk!+T3+v zX!S>R-8K%2#0N&7;&ei&CER1i`UQ^lMh{~9u6y!6qDl!%kj9eAH~VPb9?L}Y z`tnRP&3mB_yJPHq&PrcLT_5k2T%wt-$7(X{o!MRi^SXlm`tQv|Pwshn#7O`3Yw5Xv z%-jPIW>FOoX2>=tk=C=d{Vp2dTtScH6E`p9=3{x7lis&zk*uA6@D`f*XVZ*5!YnVs z+)897c{iUJt-1a!6iL2C#|3UvGP#CZL2|rJh*B_Du-Q*%=1{hB(4K#zb0vgo&0029 z1}%lfD>)?vcjJ$;6(J5+7Wkt5=Vel!dX+i(-{2kj{7}&8T-BQ+^;daESh59X(rNS~ zIWnyu$dFK!&}yeo7sHFC7dlt7-*>b6UxMl{cCXF=qsaxmpA4dYNluZHPkQ(B>yOC! zkYrOGAEL|F^wqL5oL!2==3EnGv}nXz6!5_CBwM3_Xey<1A(w@X?(HVwx85Flpqe z7=uTO$pjB#DU+Z_;r6LD)Reimw46mQ!)q5~!&4+FtHZeor?z;h-`nmrpqs8s1 z+Mnp%%lt8Ei_CYf(VIApMMEnvGeSeMh=bYI4Rs!Z!1Qr$xXmgX<09Y40|+t(+ql|* zSJeA0l-HWy8g2Elx`78%)_j<`(}4cyws}76&b+P8wL);ScC>OY@YlD(_H&?86CCbO z*tSFp8ef<13r)q$q1iSU*Z?wIHv06yOHcwI$UQ*#+Nr>&##ank?du;k*jH zy>W~STu!BjaU%`>wpG0XyBxo!!U)8jJu^v)EjH(hv8lCoPz2ZjESnGvxW$s0ZWlN)f%-LKY<)h0_WlEC((hg*k}aT(jWsYGKt z(m~Djzij=YvC|!#LRqUKtbd00_KvO1mKQ%u-qa7#6V5R6w>EbNdM;umm?cXhlk5G- zwFoyErFhd~Fu_&y6jIaWtq7UXEyd&-!^JV_n0TFY1I8Qm?ApRj*HW#L`SFC=02%5g ztVv)os<*aiSd*LtgL#SPrsR#)=*HUdn8M--En~wS%`VnLe(xd3zTGXv#w&q6uHCtj zoQLAmxit@06rdf{x#X(!n7A!KB9(QT%GjfOR9~g|nI;jQX~7vyckm zsda^%YO1iixn=-<#}fhCTwvX?%ax!N6gR&x&Z9Jk zxjijd@3mtx=0&GVOU&kgT6ZP*E$0b#gxf3e)o*bZa1-NJWMGT#VFlLaxmCSCtjq%!ja$SYAfZV>>)rBW?0Z$uDud%eX6|cyB98UyJ8ElQ* z?%aZ(QFN-hxfo9f)WP^2LZx-10xa6`gnj>LV@J>ipGYKA?y7Adc7KqDO+-q5H9Z{DvKs@cfCCPn94rYmO}_t{l@By!k~GO2w|^ z6&O8EiVzvw@3x7LI2-uu27?&1lhpnIL^f;YNya&3@#GMmK;Heyu72uBC2xYi{AnYqPy!+HCY>ra7G1Egq4vHQm0*R{R~U0nT| zf!%)kCC9` zHSH;!h*o1aXE==e|DrYasV4ZXG1g>$Bz5!<|q8Yx%0^7f?RC>pXREW zT3xKJ*6JH-o2#C};VZ3v#_PI2Qh#)vkn0QrzST9lAzWUsy>MfbZit5~ae-pA3APbfXX|iHJuYTUB$`9%j@4H+xz)JL5nBeUfku6-HjIzUHdN_EIrdORt7B1jR<~@gyr~=)ELO)1KXm4P z$GIyMoh7ZK5nYc)kdGb!3qDoH{A`0vWx0;xu1Jl>XYrOuK4J?l&aqTwfb?Q>YFM&D zH{&8nkOL$tZ)(OBlywcBj7i&&YUgfUQ&|&p6M|)Z1Ge}!H^w|^w_fA5S>u(p!3^cV zP1lBF^{ywyeF(8oy(joLVkcS_!;M$gOj&j z3~i;=Ky`*p_dKnd)fMu1y{m2~VSRd)htNk30lrbC>&gKUfPxSD250) zpfj}?BHdIS#s+1tCJI(1?9QPhoqqx?aOF|GbVPQ3VlQ(!7|AOSVSoq-1F69ib!npk zp1>aH`lc8zYiy3YO}$X94g>_?idc9)IHy4fFZXyx1$OI@LC$6jSYu4a!HsDlz!+7k z)jYMxRoA)d9#?G_p0eF2*A=zcSPedG(1~z)Exs|{5(BE>k#I|*CIoZ@UzEYnqT#0U zI2$JQ8tR)Uq2X-oL3{2@=N?=}3id9a74|@(a$#%`4{$J)08ozc3^f>G0K4cg*u}Dg zft`p|p@|yglw#9(ItSG?XfGDVz*J2HeZUxcO1Qqkj!8%EP0qbwp6137_>JAc?!HVpD7%0$Hun*vn}N zf)S|EjUbgB2Z%)oG$Kv?TWNjRPdWGLBG41c1Z43CP>K&u-X`B=!O}P=d$v|}hPF4j z>Mj?bn^r%ByQ+SpJ`rV{tDSMqSGCjZEO#;2!caO-I(xPAD`&s!eD1nKv2n>gOS`k( z%MI+dVJABGYxgGi7T5iz>)xl`UG8(*eZ&1PHxzP1C+pD2P_Yi38>)9h3*69h9r}9c zW*yob+Nnb?gnsCTe(r{Tp+g^r4r_g!KGW4Du7;j!(U)m`t-jsW_qlqP*8iek)B1h= zU&0I7%faQ&1G)}M20{j+&x9%wet;m5taD zrZz@IdKE8bz>Xz6D1K53xv&ABuWKsz`QbR{kx<-NHs2KJ zSR~vCuZzYLV0CzMiS)9`jSDK#MAVo`>(4ZmN2>*z(dp2CFzs}KKpI$=Xkleo=f}tM zwXq)OpIVGx)H&oK=TUrCRR*_*s%^x15Eu!MUz`UA^%TQKnbo~2tdjCbKsyhL_z*})}WGpG3v^|BKodr zqmGwDfr7BOSzJb}WI9XN`6>n3O#-`pNVD_Lx~3csGz@k_2)CjWR&&%?;uhTm*F5F( zdMH{2_o5NHDryxX8}@26es6&JtBDH4P`D)3iTVb}Q4M&6JnK%-dh0uD2jFg^-dAA>M7!KHT_ zr7pY@4`X88d?{J2YpSZ@1wv%NtD+_<$XG3+pEGJ#Qm2d0+XRU>dhz5s=dld=si{Yc zAfEhKLGLc3jTrqZ$XHVdGREP9K;rA(;bJKt#ph59EByhnS(7rd$jC}X(f#OU1 zi0h5VWkawYA6gEmPzphp&u29wy0ICnSb!VB{G5)m0l_`63RYplC?iFx`9){Lh^Pn|RJ=2PERMgr<-eO}X zP=aBz;Ybt$;1nG_CNKz==;_ zM8=89+VlQk>;iRO;=o_6)CBnpXSM?$z(Gfx2pMR=m^J$&7-hZ?91X$@=&2kq0jDh( z9lT;3;$wDGgnQr;5JPy?XypfGxF(tB7Z^`~VTivFf2g5GAd4wmv*xO%t|=O#^3n%z z(rRP+g|Q4uuo#Y>2?vNsWs@X(o$>EW?99yVj=bP;48+{ zV6s05{kJVgRv~EMgC9b|oCn|_WY&2mpH@tGL|dhWXi(~5rre4;H3b!gR?&~uAdwhq z@YS^tX&5Yo{m9WcwkPkW#xp%^R}Tx=8!u`g@=z^=BaGjg{S^5mC#?*KzX?F0pej0{ zBlmco_pb3Q%q{I6EQiFvtJzt;^ut6^;K14*c14T4BLhthN;mwK;2aEWQ#jaQ*1#S? zjbWQ)xWKi8kUAYGXQ&4qc`e3nIyjw>qbO@)`er(k6FMXY=1^O|&sI#&R4UvtIb{6M z@irXbKvYu!MN9F758I3^E>=4=l8(803Kj%~V4H7vY z#aNh-Mn7b>j_O?qGvba(M^2ORBM3P?or)alksXGB!LfK|2u>u?Q`C={3Kj4qsP0P__pp0prDrXL+S zzLhy}Oj`Wa^ve)PnkVHJmFB~^!C|{{?Sle>NuEj5ta9ki`IGVEo~+Y0S4o{aq{ywp z>0*8=gWwRn9Rxp!F_bMBL)ioe%Rr+^Hh@89K#`mnHY*?2tN=tP-N;Z6+DD8wenLG$ z7?MH|(vHr{ckRfG@T58-6d>+ug0ZvhKo;<(_7|;P`k1Yx&58)j)LX z=odNIQLc$trIf5P=`d{&de~VGWCSj{iXnVTtOEaLHz8%h5X}$M?9Gah9n$RX zA+s*s?Rl>oKcmZJsN=ZjZZ26y3-wr5BHazfBTTE2MaZ2ge@SV`=ky5{NV#d1`T@qA z;lfdYVr2~Ao@mS(fV~SlHexvPs)0oiQxzAvHaAUh=MI-^niP$ZM#P8+*^pRN;ff#n zhPVkfg2_DF>J~;IP^fG|IGEA=AT~l8FCsSNXU>`s^KjL|anw#Ar^(WRpIS9gWIB_p zYRU}q8Sux=FkN;H(9CBdWWMrHkw%C|gyvc~Q#ZzRU0Gqs*(sV)S;1(vi@HN>nz zIUiVK?ZeaqWXW7V*lD~X>k@9XF%)6&%`ntfs}WkzlEOKVoHTDsH54kfM{h_rxS2$V zdBUecXNTwed z4karjob#gg5lfB#keJ=TO{$!2vYQ7N8QvmT#Hx>thRVQWp(sHKTt5OKnp|ZoIIF;* zAsdd^9Nbe2gAl|ZQ;qqMyhtQi3DBA8LEdY|f6BTRy@Upfs5Am9pmM1gcE=N#7AzNp zk6{Yd^53hZkF*nqbV>~t#YT( zO?{uibWs@M6>cn+wNVt+R{lgeV@AmgIkU8Ajw~yM9F@$T*Cgv^&r(rXeic*}wyCiN z!&Os@VJ(?6y9~>NA=I(0paZ)zcaHIMSju8pEVXRWgse3}5iETp;)6DG2E8x{-GE9% z3@~{H7Qq@|p{7X~=P--_7&L8wlry5R8FP8eRbiEXF48=OASvQrHCD~lA7C`3lEv82 z(Z(CTY3i$ttQd|i)Q!=BuBboPI2A%%CF>h(_UJw-w2*SBvYj4vM#;kIS#A~QQ;_c3 zJr;p|uo{Nt(A}P68E?`bz*eeBSOGFp`8cKvHpJ}&z6K^CQlR?8Q=HI+DW(2NR$#}3 zg~kv>+`~ki_~@rojj760VJ=&s5wg%4pfl2gj+|c@`}j#q-Il@!BiQIpegN5xTHF)G zfT42PE_ckS5OTO?H_wP+^k#G}k9f=&?6{UVut(d6wjp0N_G2EMA5poNY8jq57x82z zk_dCLf`$yiT$n@!hcP)nxryi!hnC^L=uM4}g;PNh&_Wydljy_RM8hqXxdtNx_ zM!3tIMkL4)abnfHO5=d64r5+qalNoU2xo}3;VR|wbUTDLNKPTA4ZjmXLS02-I#H%v z1LFnGs=1Optx8s%Hx+^%1SAz|Gqjh}s;bVDkWAzUuy*3W?#OL5et~rqq{wXK?V$|1 z5;uu7z$es!cD*0OdB79ks=U1&l}$cq3>bi?5Pr@hu(d*EyaEb)7nLT?9IAs2I{edg zcjVq^yp`0_52Gn-8uaRDRh0w{T;0PgEJ#jP1%eBm=+S{jMq*P5VkuYwtTuv13@Api zxY#TP%j@7Ok^)xvN!Wjv=RY(43sxHL1Zfo~tU3>&g0yf%kr_g32tD+~wZVGm5|o2d zFRG&Lo}zMTn0ZYh6B&@IjX7=tf;j@%+|2YKZ;|oekd`TwWYRoEaoF22G=&-nM?VD` zp(g|pAGRG(sGU7LcwEm2MG0g$puAPk2N5x*CG9+_$IcUoIC#grh@%H1@{G5+t`d~z zqX#+74l?}0ln--CSYu4@ki_EZ4ICvL38qq5#(}k=2gkM|XMe@CD!3;Vr8+4W)gL{E zma1Yh$*JP$L3`d`j9)U^fYzw)z(OB#mOwfhf+wl7CaM5I9UO?bu34LOC%swaM>-Tp zg@9?eh-=?IIZb8O$c3Ut>SkqAwPc_tr@6syLI>Y4e#KBx5#X4IB90?yVvZNG)=;Du ztQN5khkiHqg?>}ScsnaDlBsvt204_5Ee-H}&q z97HA*LXc!loQ2?tCS1@oC@!{2QCB87gEIk=fT71|sy#(m<^|6u(&9~nxn1bTrZ;4c z-1X&Z7(@iAAg(b4A;iv-X_@N5>&80}v_?oEkCmJNSB&fm64*chG96W`wbL-8a<+0! za06u*L2kC2hMV=|pf^utih{VNHsrpb3563Je-O(XXZ*$qyKxs$0EVL>fG-#J*3b>b zClmr;W1X5qy6ebp3N4wHiX{{DZbYmnaF&HZQ91k(PZ+;-a#f%iGi2J$2~_ZK1gc+G zM8nsF^(B~E1bfJLLvRoZHbjb3*3+7+nsN48hP5^9_7QuH-(edYoI2WZeJ0X`;|?(| zR%I~4-k{n)Uv6Y&{G49NC86ySpq+hJz(|~F#{Je;0QUXSK)%ic~%qGYNtiL z`9XWmcZ}a-T_94;#WmJVm|M;ft6_?u5eUhuV0+wUG(=z2m%0UwNnsK?)`0R6A{4+! z=a)DU3VkzvmO4LOJ&5IvHU7Y7FifgD3p;gyA^Zxmb!H3X2u8I^siRsy;LHaoU{xik ztUv-)>I%|}Nvj+x#Z(!9)x`bWD4E5E-BrY=GqtH_?qyr|3=<$84s2)e^0{o)pV_&UhCg5G778 zPJ|&3QP`YnhAP-m8|vP&kJ^!FW189w^59}+My$cJZ>FqqqW`m;C|zO zU}7Mx5JR=5dmebMqU&jJP<2F@yIK&NIJO850K9}TgssVEP8JDPbPhd<1{<2VCu$lT z6dGb&IMYDbYhkdX1GsP`0V@y*%`$}ZG*pV z9M&Doz+X~V>L-5_No1(FuK*WLQOOOCDx;=?bG-uPJ+)Aq>gcppdlJ01G!M!qx1E)3 z96>EcJ}Rit>qjmK-2iQMPsTcdV}dLc;`s67kY^N)JSG#r4pO`avzWoBLgI^@$6>@l z5I@c-2eZZTzwsJ>@CUyhHCPybX44}Qx6$44fm`4ftQ*AgcmWaXfa$G+`_b))&_!D}qduMS+62ov^Tv2?H-@;jN#<6=n;? zSl~iOZU;9x{h2d_us;^Nu^U9lN6|UslQ!R3Fb5tedx$s#dr5@cnYfp9WsZ=yB>nW7 zb-QQh3bVD_y~IzpQm|vEe^2}T;l3OSqwE6WR5bg+oC_!?Y%Ewh(e9y&+dCI;#aqloI5 z@kItF67kpg;JFQFovJdxtR`K; z=2R^R;M`4uzye_rwv&?@q!|!jB9h{2GbrFDWZIt25l@NJFdd9?CyZLiM;aC`xdcF#Th#RBu9MhYc0Jlg21-%Ca zyi%~+M^4A9wCarzw;vU2a^j_z01{2y=m%|?kiz;9AcHIDUk#)lx@x53v3ga6kQ!M% zE>|U{4Z0r4&PWepBmPUAt~>QIo4vzzmT;#d9#xy8?EtoWtGzKH%qp!Q6Z%!r^B71= zRMA^O5(^Amfa6A6XH43MO%Z4Kni`7WM=+Dcb~_Fp<~X<&*vj9@h%n=$31u+npeuxt1!{XerZ$_rT;Et#S23^Djvk4f&SVz8YrvTjpN zK7CrUz{!?iM-7LBJ&9jZ92X3B;9P z2p=b{m?Z%mAJ{?Yq7tlG<0aI4Fy&ic@bUt?B8F-b6*;M79T$ zax6Sx~+UDra*sfJrWN=C_e3!L|ghu&YU-{Hcvnlkt5vw-pOsNuWWFUvDU9qdh^)BAXgyl1d-4JAiaqM5 zCws;AnlFgSM)yyjnf8(bdrYRS`lntB?6LjRXQsWRz#f-rtNy8%0{hJV=`+(_2s<-9 zfGnPsX|MfLFNH5w|MZz@FDbCcXWFWN>ZQP*&_8`<+Di)TiJ7+QpL!{Pr0V^@{a2_WCsO zAOYLARZL;4Cle2Qy<)xBdVQLBz42nvlfDkFr%~ z$!KggT{H%d*KpPGj2iCCx70>(THRnAczO%i>|9kw)s>FPCPqY&2F4R1KTG^y@F>;a zh}>L)BcnhhFno%|F0)u2z_`C_^H}erYMaNPy@vLd3vI|{I7caKEZStncqG{=yjq=* zhjJl`QDX}a6U(}WHE?cV*L9aT$Cq_wPY2o8y^W{Kc?8*Y2YJO$OkMXoUhUx(kDg!t zJg*M%YA>&j@(SO*^(I@mvT!ey1bf;jF&($AY(;}%AA{_{uj48!ANPiNU$EWkh|=BJ z&0ho$hP+66Mxu(Q2Ook0J-D~|bzUh7gh#=txY86nkEhF@Owe6=mY6|2_wv4?=M`Ql zdS2s|qUTLsDSGgUUWc9`xC*UCk-&RM3-KmWY4Gl9{-R=L#(L0J^pPk5;sbu<(VG}Q zAAo3jkMl~=o9)pHZaDNpWStQ^#w${zSUhAmQRPS^qnhB$G(U8ly6Xx6u=qAv{}79# z@gX>-G>&Nrj>Y2HlK9Hvrugz!c^}?su{U=iJ+rSXN2pV`VJVIuxAz~+8jjBv4*7uh z4%)|Bvtsx;)Zn)ekKrtHoj6x|(0=A_!ILtzYB_TM0Q%3m2InRY-Jyb zLvMir1P>31p*Y$S)@39QDIE)(^0Di>&MIEft`0E7=PC)Zwf= zvvBK@wCGm4=nl)mry_C$IvZA=4nGaMef<4mRuZa*;=@+LoDOqNOZ5&}-P%FA_tAD{ z^Lf3;COuB>^ZoCFwgPp1E4l^W(AO3U8jSak?0dSJztkO-ecf(s%Z3-(HkWr>y+__TnII841m2fCQ`Q-i z_ObP1Hf}>`A*Etag*lk^RvyFH$pd?FHs1twIvhR@ZQ=CaVK2JEH|zr~CF{lRK_DDI z@4*)Y*nPf|*`xyZl8&+6#Jqx%hqkG23Y={kKmHjA`0gP%Fa0>qp4@ZBAp2Xi{zpU( zzT{ewGY+iDy~Ex>m;GqP8Ka<_Iez;t{`_DMsvL{w?83myW0X^VxGJXwr!pTY&lc{YEEpcU-SGtU!q+0$C0Y+<{BPuWOTq z%KA^~|KuNv&%lZdUk39ie7^3iTO1_!R|tHA zRxDpcTKCw0jSpYI5y4kK1)~V@q++4^KDE}7Cof0eBQL-SwY&K_7Eqm`9*jIkoCk_V z82V62bvo=O@DB$E=ER3@RKu7-VUCT{#JnwrZ}d2i^U$-KyGZ!&<%8fYxR+~yjNykJ z`!MMv@o)0Mz3!8{x&RO7r}`3u06RPUK^$Z_d?WB70ES7lusjgjl+&$nvbd~+!U#8e4>N&Ot z^POpRTJF$;hd1WkC)5T<~4qZKHFL(@J5IPzkaR-(4W?tQ3-`Z8S$KJOwuT1XS1DEV# zc857f`6(BJ76f{r2*msrXpAiJD*lorOiM$;3nXEh2YX73sP^c2iu6oV9i^k^-Bfz; znOZ9k9~HCmc9N(;E|*45cIg;7lyp2tI-;awkV4Oe-8uT}q6X|9Ik_8AeG5nq83N0oOL6MZ{X?lP4*e0gjGt`@!qp2tkYPW&*FP5{()lrJQm+(@joag%wh3G z7H^=KIG#m2i`^(Dv4cr1EFLD=Rwi*#+lc7`+ZD1WeS~6iBa4Swe2n7kFpEc7{1e5L z2#fFA+1XS6X`h;%e>r~U??X{=5sN>fnEDwO51^QKD#$F|#H%=q-=Qc3W3mfxBW?~~ zECB*V+4C%pp(rl|OUn1+3j6~nfrS{&eHEi;v6#;Sz{F@q45Pos;xQIKVeu;#e@8Kf zn=8glXTk2rT*{)0#ij)8oH>Hsjln58V$6pq#^PihF}8xmG8VV8_&$qQSsX<%j`90A zqB0I_7UQmG@f{Y=vUr=tdnnEvz+y6sDi%=|D?Hfkc|Qv@e+&QvcO=7 zv&ONQ$pXS7&RUKaa`E0wm9u3c{SIF))^bk+w(;WV6uwe~HCn8NMO~hEjQDqfoe-f0 z>|1rVb6_*WLcRy07XbC?hS7iztG-6!R1&^{jKf>qHu}&K3k$1BCtqP_FB;+N;CNpa z`(4#LidZ_edB7_5pd)XQ!1)7FzI+YXJ{*K%;MLd&kK}R|@l+cu68fyV09mKb*o(6*U-7JV|mL34?O|PoukLFStuV&?wjPq z+tk>?LVkkdeaR6}n~&G&vEmC3)B(7P(euJ0A}cWznG;nxzwgoSMhA{z=_b7%?3n`V z*h!M?th`Gc=TYaw5cNe4-ooHU8f+%WuRDP_CU={mKZxZuA{T?<>x(byMOw9M9HVt2 z9ZbfzvN7$@I(+HOyHYIl)Q#Jac!&}YKdQq(b!TR;43rqBOtJR^A0-c+Bi4v!Gx1iF z(t9X@M1RJfOZUFay{3C;7x)cdEn@qV;A2P zi}Wi1j*+OTQbq#CvkDElsS4Y+YOvwG1$*i&{hqF3OC#B0W3NS6AASZ~USn0Z04Ka+ z5yDougvCj0>*Cva!3M|njPQvTcJ7g--+j|{^aG6)wwrlx|LJ!O)0pI*jd3zMcC>Ii z2u}OdZw|Qn-;w(doE>cCE8bwp^h-zTfCj!`h?nx5qto;8`VpCi7f!2!YFDFcuJj%_ z)KsT{oHanykbrHa;9hgx#Q#C|^ozE-aCS4RHL0 z^Gc@6k{L4!jk!J^bynDjmwsmy;sny*Lc37TE1iy)Z)X(F!F=;robU{9kQ>s@-krhJVnhRth_Cw0Ty7On_<@-`qrCAoRf80m^CDZ4~ zLR2&geQ1r7a0*LNJ9xgFjp|NgAd!%V--?TTa|-8bN-8BFLcQwM@i2<80;lJ?(CiW) zAi_>A$R{2pg$NQtq-6RWg_}Yq3}k>7AUX(Yv`VMXF$?FKVQdC1tX$yugWQkA#dsG7 z8;k%CXZ-+g*<7Hzt%E`AKY$4+&UnXicZ=2@5c`qD1jGcCO#MOb+hPe>TZhQzU%`U} zMh=wlY$noGyqLQ|T+&~|oQ?+$#Q7<7x$@4{<$& z*QL8N_lM$A2|*6~pvy|e5vM?sxruOgiG<)g(hf=XbekFm@vXcfgc4c4evoe_{$8vXx<=Tk$!DyVj^6821onp^Eye(Fww}a5hlcc^k znmiqRT3qG{Ql*4;e%it9oxWaZnm^ms|9Rr_e-U{eNq*&wl61p`y-8f*VxFQVC#M|H z-}L;WzBfCt^TvoPWp#bB{@b#u5L=q7;n!uO(jBeAnW{HHlB zYXdDA23pvq3{wWnq)b^U$vJW0P~C@RlHf89*>=_r$ zoL*X<6ym#BsZ(uJClb(!-aJgHSB*uggK45zdV@}&L$@K^8|G-ulG>U0{(N|~o7 z*n#0m@F`^yB*FirxmE%vBt^odZe}}QCE*H7J=oWYn`HSc z*t}+CpeiF_aG<=zS9)^N-i-wmSJ2G9^BW!5?YWc1=b7?@;R6PEL=`?cu>NF02CY>x zSXf#v(Q7k-D1ji)JI6mKz5rDZgUK#SG#h}#EVH1{gc<6dc!E)*YURWW@mXK)nZlQ+ z{JeVA+X^%sJAMZI9QPL8kFS|dACA30;x&9%bjeQKTk?+9gW^ZT%~%r5dKCAT;iI&o zncvu5#cf*Lh-H;j^6FJ~fX$xlfNhgoI6oi619srG1wvI`TkM^6+fvl5OyZk7-aR!n#j%*^tlK@zu2CEBroxo)Wzp1L z@IgL4!1;%KaWg|bIBO9;H%WB6_mzO8j&CnSw;DRS4=U&!6Yi%h>tP%2;+7p4h~JqJN8UrTPi(> z9+m{p)j&w>xR%)ERMKIdhW*oTI0HcokY+US6tbYi;6qVD^=#%lGfF+DZ^}>)VrL%| zcd!$+L6|$iReS7xdIVdUu_3GUA-#p|iEM1h-Y;eiaVyWF^bdayJJd?=c6N#0gx4$% zbZvVF#dcNiRrHs#vG`fVT5v}B=*e%0JGs9$NnFuq55>VfEqf4BY>MNqywaig{(18{ z0v}2Z8vWaZ`gnExR4=soHg+DH6LxU)s9xF^OwVnlP1T&R!_z*cda6FPFTKvq z(mL0j!b3^IlL!?!e4adX6x<=ORnD~wiaZU3gQ+**J-O)@3u)-i*F{_ z(}(eM5Wy>D{yp-g&*S^br*YS;r@wt8=GYS=M$lF!aZ%^w3&poQZeE*?j7%_36&#rD zzA?469-RGUaTiDTRb{q4Ebjf+VxeHiMvNDCyE0a~Nl(I&Jx*RqZdPlpm^R_ScSP^! z>cwKFn3LACnsF5T45wm&S$M9_17ne^Flo&eO_-W?x-EDpuX{z8FJvN-u|agWRC z@=LJ`zU(cR4cPDK7{s!3()9KmdwUMOl}}FTp!{^NgJWI?vlATkI=akIKL=W0Wy({i@ zk~AgL%aJHk`F)j+Lbq-P3)9JNlPBc7027HFSw6GyT)VrwD4U}wp{<%V+~H2yoJvKk z%a@LkD+G6I&Uz6nf%!WkW(`DzWC!xhqZq03cRZ%-m2BL{-Ur15EL8ZAP&Mk@lwa}= z2t6j9!}p5&kgCJZ1)VAJR!UUzRqrt1%5G9Rm&w;Uy`%`fVEV7uILfBaVMor8$ii}W zHMksWF5D{RK$wNGQ}WQ6dz#qD1?E`}tV*nS6V^FyUg8|J4ve#mk$J>Cd$!x-Y_8az ztB!+F!yPW<(yg0RNG7-2XmRU@16zpuQ|a!On4DMIlLOsTWHU8>$-L+eFqJC`c5L`R z#COS`9_!{kIMp4eG@R;=QxBeLD4FWPDP7`$q?LSf8VCP0f!#TA=k!8|>g*v}0F@M; zY{B-*HsQUD2m7(#47ws{5B5VDH0Z}FDX<^z$Br}TDh2i<88qm}Dk-oZ?Z=KY=!&qd zO#A`Q+I%d74*Ri63SYk0j~!>wRSN9yXV9P@tE9l*)Q=r!&{YcT%^5W4$0{kXxAbGj z8FWS18SBB;3_9$`Dk*%~){h-$&{YcT?HM%a$0{kXAMeMGGw3P>_Kpl1^kbD2*gN~N z;|#hY?2PqbR|XySW0e%XJkgIGXV6s&>>p&%pdYKGz|Q2@q<UPLai8$@)Z9TrjBj)PKQegk&Q#C#5 z$|Q!p_(q{OnV8ebSXv_~Il&dGDk<&Y*)7 z*e_<#pdYKGz<#M8JIJpAFHIm{&_!koIzKFov|LgkwJ(3SS5uoZ}wxy z8FZBbTWuxzf8vG|W+|}uXMk)!R!M<ZEU3QByX!eX5pdO{ToSowbR6{*J6{9p2lz0Q9}_lmQzZX;v3jutDpT>KZ- z=@(@I^Lf{BbH#1;hAtFkasO*Pw6gdpR+1|kamwkrh4KJ)O*$v@;*vY7a0uVl_&k9# zrUcK5ohNzqyjruih48 zo7}t+yU2z*9KcO%bjeQqeok)1kwl;mCw`&LG9HY`t3^d-&OvhRJu&}wJ~sIHAzopd zAL(wN^hNQucXN=s0(Ve*YpW3UmqgZZxxNAiaG~9EW)VA6u<(0PkqdB95t}?CAAA>E z(hkMvKP4Yr;a=UP?uq1kF3&qBT_t{*)aWiWGAGP5hixOiMREgv%MEDnoHHioXK~}& zZT2RNkg3lUOp%QFhm$0uGSa9e!@vPl^FK}qq^5hy3h^tRDt4P5betkgNv)~`VRZ{| zo}&I4P(S&A!c=#!eK#Z#KLb3lxqh5|um0)RKk*>K4nhwp0rMobZi&JRbZ4XovBGbO zU!#Y*wfa=Hqw%`6l#JtvT}6C)lady_o~+cm4u&x`KiYLti0{9DCAY?Z5ni1mQ@RuV*KKVRMNp(?9CL}zOZT+Kh` zj#b_3=yv`w;8SmKV@A?>mrw2XZn&qdsxfJsvQfO_oZ-kC-g%Ba(XZ$Jc-VkLqJ9C+ ztX$hbIDVI1^$U2eVk*1pmn6+`RKa_sea7qdoVg0 zcIU*X_-$&XQE7o4$96@v(Xt*#Lssa~z50Gyz9FzN*IjBm`!GW{xQ8D%l)F0|aa9)2 zYE*=otA1?GKC0-BO}t0^j$(YPd;~TPBacsl;UH(2FC6wwalaKzZYbwH=QwGcE;(G& zipn^__9j@S;vqB)sFOI0n1^}pnx=^@B(V|y540+5{q_|m|H=4=myXs9C;YKRQ$oANfNR;UpXyJ>amiO zOz;eiOW?Vec*-O^HSD(0OT`~KstV<=CzzYvHzMkB=7`*oK;#twb6}7A5AiP1%1%Oy zxNtYtb(@k@{DXLXi>uJ>gjK$KRk1YRPh?9+YLM2c6^oF8)_{lFE`DxtdWu$lsxj4B8|Q%HxN6@?%G}gWVn+F6v@OIo=V{ zV>0eHIF3{iklNXfbJ!WTF=|qIZ2FE>UT1?-A0*DHP4WXf7O{(=tf{n1b#b5SLcwmg z{zn{Um7LTnTT~Sk$;9pW63h>dUBwyv8_hG6al~QKjTDmS<<^4`z9VA6TiWc(m-X)R z9ecZXvI9e`?V{Bnju5tzD}|oo%DWmi9we-SdhoZjNWH`^6l1+Ec8>76P@|N1aJB=x zZNe7u=XBle6z0UAaCiE6btb$cehYZKH2iyV#2seD8#eghu;=r`r)#IF0%x4Kpu;28 zj$~_|7fumJZN}|%raCx6SQ8Afzw>Za*T}28yY*b}y5sPLt`iPl2xWv5J|w~`o#2+^ z@SMtKP~=(4pxo_b7pWC^ri2>AgT9eoVOdC=p!Cprg*}7 zNk^$aeWALW!l{Ke>3KDU+NxUIi)1MpUA`1uC*H%s(*9L|*nF!w@vr7t@4?xJ)%Oej zY_EU!ly9)3eK@!|{0>mV+yn=6S#YChqF%y5L0^iI%HSk%em8-C$~K*ST>MpTw$hy~ z9yt$P;%xB;yVOy@5qxl>_fy7G#UzE~U?mJ$}{eT}+0FUv3g<1IGHP3Uu(f*>?oo`}#Fl-M_YH!|W&Qa5*JL34@ z#9?5`N5V`If)Ir|%2`aad%pRUTg8W-=0xWJGk3~~)7X+UN9hVERR$({2d->R0iyTv zs)|>S;i|cbSFhqK(9A0a#|iCueA8q&adBMkuwYmZpy2Cjg>pv)f3k4Sr*6tZ_xe2}q5iZU zY!iRCUqSEA5PDU#EF>GiXgyg<);Dl&)|9H?%A7Ub!r>qfoBo6=B?AjNrSME9Wg5^G z?5WM-A1=uuiyV0CS!AdyL3|ZLq3qRedP_gX>qmS86UHOb z5V2g?`E$ibsr9LAp5&`fi||_%axc>d8}_<49)i!DIfd-%tFp` zF|Rr#77o=Tuh4Nue&G!YG5b4^Ej`M>ZY5@1XzN)F%@2UKGVup(1>3|YBnU6RXx=VV z6Ym>vWcxfTF6K?oK3{K+WOH**@`4`$Kk@kisObx;RoGSVKcUUd zEiNA*Kb|&wGS=LY^cbgGILf{Wi8`%MDq8QgaP)uJK;s1IT13&=Pofw&n+2~<<<+UY zI*nJS@oLa)da4~DW6>!2vY1igU6p!QGu4&H^S1GW41;ycyc*@+)hzFdpN7$W&bGfI zc7F!i*L)iWxbaF44wx!tC^+g$!BJPLXLVK1wiO=i&eOhTn2DZp;)_}(ANFGbsYR#v z)?(a|hny_$g@R?K2WS7r@Ie6=?S_gE_yu%&(PVzegV9?{31{V)jKDHz!FRqYfb638 zX#rkE)uH^ZezyQT5Ru~Qly`P^Hz||mLMLoX6@{izaICvcy#X&sWhqNX2EiR9> z@?$tN>1sbb*fPqT6H}LB(d(4j+wk3^MJsfwbF)r$w!A90q7BiaX_bS>YT8{$dcb7ikm7hQ!B~>JWj=KW25`!i^!46JBYH%glb%f zU`krEWw)Ew)WBPID>;suplf>0Ut@2TIwsv=43u{gx5IIKDw%r9p+1LKUzS@hOjPTrcCz)#-E(kj4Jo^&zKfOK&VrhAKTh9SM+8~FItpb8guTk&tJ!O^RsU(ZjcWVA7F7qH!LpGSlokd zJlI9wHHIpblEB^r_=NK@?+>PE>O8j zwOn8p#>`lyIXliakK|)0)bmaG!sqCJ;Y?$={bu%nU%N{V7oW~}_E!1uqpJ2rFH(Zn z*;rt^mH6;P23F}xtTu-hoAeMkbI^-!am~fW=V8PURlGv} zP51&vj%$h+x2790AjjCG?aW(^ymZeo2p6{^!*a2Wf~l))EIA$HnNXY9<5ml#?~NaS z#a?e+e9%5(wdUII@45JX70>gfVM{Xqpr(iT37g6pgi1A$FBKDdI84~ZoVpj(+kY7MezVZq#4>-{K}4CK`=7O%4SJ&V7v_=IwN z8~MWkt+gltyKucR5~l9_EE_XD4jq~z7G z*%<9r{3V}ENUd0!`g3mTUt2mAv|d75XV*p;cDs!)Oqk(&|nk?f50ply287=tgY zBG5v?aBfK;v8zCCJqR`*5n!{|KXe&iHN%K;Mv0>)cs2;GoWqGUZop%Wn+Cz?sAMd9 z-mEGUHzkXmXHGD%GRngh)JUpoPV!{Q-4ba|15J^=g^VzvvVID`1{-uq zE)5+&7kSAjuW&V@FI@xHLcAwzELXo@5KVKnr3mTC+{KD&GF@}oJm0zPoX$&*~qN# zL4aV-Xne^HrWk-H_RV5~^&E{a9V)lH3w$6Lt#Z>wOujl_P_WyqafW5ieofv3 zjwp_+NgZ>2qsifQkhG=sy78S|mt3uWVj*qGuB0(~1Y-ndEe+6*TPBa~z@$Sl;E=dv zJo~vzH^kLO-nTNz7sU$xV2tk$rDrwj9Hz!t|pHg7b{RbR5- z7fY964!S#v!G~wU_KIad4WF-c6r=NgaPY}uh|AL3wdkVTYKYL%7l0i7L3?h&0^O0JM@xbDS{l&+B3c;bEnXjM>Lx`%Hx zCiC09eL@`HHxm<2VM#9C{)7<2TqK{d zuypK9jF%zdWyo!=@mw}p{nVp?ULFDs7IF!+FzZ{PWJlu5CPPe=ko_PJTv`?+nRjUn zxQwQ35{KK$L=V~~9W$mRSui#H0DMOh;5!d$z)Kvf=|Df1&@soMswfkU{4JgQvU}w* zXgJZz*BpZl9ZULOP#q9AEe{31F!DWO+SuLhM0fJRM|G=T%B|czv!1Dx_r$U+iEOjl zU_&$C~#pv@xOrmxdkld zBpSMdfCnGMKR4d3thoNU1?KctTHYgUhtFHos>d3%>g&5*;tkj`@rK546VL&Eitcvf zRby&S{B!YyJe~BFp62T^U1u)O+r%PcTDl7Vx_bnz=H;T+T>*PJ}LWQ}9bQP5xieGtHyVdV7X1K2wl)ouDTRDUOo4r4K`Mq4+StPe_L_+#hoo#EsNT z{8W*hx&js#m__db0hNa(ljw_L6P6n@Qe3HSA7(sqD1LbsE8pOTC-~_&fSnOMxI9a4 z1ptpz+<~%_-@6B=@L;5RK$csX_=DJl&locq*{E)=Ro%cn;Ctp<4|WH_Ab>y)IzYT; z+ySP?DQSn#PNpCndZ=Jy8ENy7#H;W3_;QX>M#0w`tLzP&6H~|`{i>lW{VI4@Tss=S zyaP<$eSzFgQdO3pAA+~ncd5k>Jaw`Lm)E-jd3n7WcQt(Ei;~5*DQ6qy-2_07qccId zyh9mssZLwP+5}gtmp>`L)rz4$A}+sO-cyTv7>;ka<8;M9Z=ATa1*O4!Qjj%jn-6R? z{*)e!|HzodQF~LfTkTrhaZuM)@~sBrh{tZVS19q|7iro3vdiu(2Fk}<(HW4Yi0e(F zmIJ%JaH(+)v_7#L5=;ikOwC+T;tC}0Ic&te`#6_BieYii#&ntStjmlm>Ro1B;l25Fhrg5I`;BB!|Afc>mPi&3$x0{(RK%Vkut^c6$ zeJ*Nxned90eiii6{V@h!xx{sZ?bt%W&GYIMW)$1x2F?(U##i3!!tR_ZjDMpQD`Tx~ zylU0;w=y+w0I2~?6n9^$k11W-7?u^6sLzdm?b#?WqV4 za#QyeE1$D6@dxdb#~GhxZ+u&%eHpJ9^tP$1Y+il9d$fV=*w1r|;PH!X%e2Kl8gDbq zF@L4s#}gmxsCE;172v&@ylUYU_eJQZjIgwQD0s!F@NO^V)e=@+vY+n7TSF+HP@Rcb+}a@Y_GcBeVET zo+3Lc#$W*Lm#I!UCjm28kv7Hk^#`$*{GMpT9EaNCN=Sm?ZOGK|$pM;SjNj=9#;`sP zmo-GCKomP1yST~VzA??1iRcxTx5RmrcN|A~Bkz5)#7g%#)r(euy2xy7ApB5(wc5SgAIP zkv4PG5_0AM0u$GH$4*b8-%0+r?^C|Ufz7ol8_LsuhwFFR_fg2fcgG{OKVy!(#2on> z{$_@-eY-j45@%eVkq>DL#Y#&d=Ze#8KVgUN4?Vw5VHkN(J(3T>W8*I)J!s2+)?h3a zTcB5Rxle&spIa1S3p76HAIqknM|Sxxh9K|`T}arb zEmsOyOJ-DK*C$OM37oLo#zc*pgt_eXicX;#{OP<<8%!q+f}d}TSX@m@>|-K!y`Had zmjXGEEwT1A$lk*30-)y|`%bLLdvte9_=AD9xp?ePtU+1qY_YjUj;juzHn2zI9X@kd zBW2(SFN^n>XH-bM-A~)paUPWypwvLA?B1bx$7H_5Mm~3x@Nwr)%(<%lA=aNTQ`6mk z_5cIyo@jqJJ9dNpVZ39gS!^pPq7wo43XHGYUyEE1L1KS@w-02;uC*WNirvVk%$j$s z@f1|QCG_<9SQ${!EUG`4jY>f2?~s$&jULa>&Nk-hb*cA62RF2J?zV;4#aPLy%BNXa z-oQ^l<9bN!1^`Ozo!_;XKP&95T`?8Jt7wsqch@EA0kd{07S#_3IwL*koctSOKD$|= zyGe4tMDcv0_=&=a??p^}0G_`i;8Kj?b123YP`(jN>ugEI`$`9ImmqWUQLtUfVrO2S zQAZgIn5*`hqyGw6oqUsN*EMNzxdOr+i<=AuFefI3xQO>E!QCEEWIwM)QNy0}SEC-| z+4&S;>D;9^o|{xn4kezysME3#`_6bGc97qG6dv@hZ1Gu)<~4qd+^Palvg&mD5sK=n z)A3++z-(VfA#*aqt4>$2+pO_M11r+Ys)}n2bPZZIZB&AXzTS+lnxrw)@1rSdz<|!U zIl%`WB;mvOLw<+&9F4EK-4)|ix3jr$lFj6ng55Fpc_YM%mwCPSk(Xv{!#vEYTQGSO zpJkJLTZpHN;$!{hey(x0GnT5BYmfT`#M*RtK)yNC%V*=+cp?D2NGjT;6uNGf7 z;l*4llenmJa+k3HT*oWCXoELOJoVm%!eC@ ziPe+M!dz0aiRh{oW$;7j;MJ9u)rZX@N`_GLgDH!Ru-tkOg7cnOy%w6Z`%3f1T4)4k z;91a!?d|9S+J8u_euq~|$vKJKezSgn*Z*#VKgin27Q>O2KK=`KI8d(Ns3N`9o6R|m z=7jb3-zrw$YnOFxZ+GOOeT?6Tu#ZMihUE`OQdc8Mdr-+Iu2KMQPykuE5GkqcU&T)^ zV8>W*r(6xu#9~D0hgKg`BdH5=f`6pDb8?;$)uX(D@0lKruko`xS7@PCSKUv;milhh z&PI(wD&U>d!JRchm%(VbX%9W}UW~-ngUvg!r(*Rnn<1L!`S{z7CV7X}!8I%8W?sD~ z*3jxE)AKkJJ6GLro>4)u!&^v4+0n=DoN3K=T0lC=HQT$j+|FEoa#!2mbm(p$|7Bw# z-}aflhm`2-0S5E&f&8fwFmyjxQG*jh{rKtLQ#G~rWZ-fA(h)}Wl$#*~r+kAlFoZJj zXHMvZn!EwDm60Ay{EWf37_Q2tz)Xa|h^ruhU5}3^baFnKq{n?OBd&ts(To7v5FH65 zj(>z{TM8_*HNY zO66TnafxnIVnr$`Bem&lH=g29Q+VLGRv+iEa&Qt-$)WUA(vihUlZ+N3#UTNS2*BML zXz~q6_*3IyU-0s?-trZ{>i2qo*dcLsnkBZUI?x)5TNZz64TlBU0oo5N7ID+W)kC!` zj+Za~BcY8NnYwyTn zZ16&3F{yti6;xj{ z(1G1K{tLzhRMSE7$%BCZa$H#EBq|#8>FVEWfdZF4fC^qSkdLRClNz1J*as39MLewG zR1DiSMBbB3WmC+~=gdyOxyo-&oN0r5KZ0ukmJ@s#=|NlWX5&H_u$=fcmbP3#TAQ_A zf7)2KkHImc1(5Nq7y^VQK5DeP@Cb3pHJ~!C$yghNFkzDrxN-vlD0yfb^OkW@GCh#G zXPq@xL<8P>`PTTz3n)}Rh}ZVB(17t_92o{&dGX=Pd-#{Z5AyZ zLEj<@_%a`zem4e+d{HsPQdn~f|Ke~MdqD?aC{rEK>*az~rGeAwj zV77O|T?57lgSXo2tZkGCJ1~B0TYDWaO}2vFK7PKjBwa8iA z&0qTvfDy;H#oAUqC-T-M?0sVG&0doipsCyorenqH_#&nFtUKQAMgMMG!tPXNQFY93 z{jCl#MjYt6WIR<~Qtc^t7#s#t*JjB_YH@Waer*B2Lj_c}iruU2yLi^Y7M{|wU#yLz zulb+gC$9GM-ezD1*j6U~pv_uoECsfljK;71y{+g=M(escX3-u6SSMhvy@TSSd>SqF zv-k5SELqCfJ$ob7KHDrB!j?~A_mX^(yTWx$4r~s23d#g_RT>JY}=>M4(`oqfTB%mW}lMG$OWMgZMWtqd~WcIo_sjxpu3;WG( zuy^)^-8rJz_*@^b(QmRMJR9|HxW+yG7L&ED5LZTII86c>;g3^_>&GfRXdC&0u^bPs zAL|x3pMt9m4Et}KisI&n`SV@=yqrI)`E!NjnBnSHHoN}|?$4XQh@TrCb$@au0st;qkx8U*I8@Ve#{q|3uwii=)5RtFpiR=kb5a zUw?Ak`-!LO9-8J$u~OjNjGr4q8YRZ1()gzFLuvfQoG8sk^G0cIHvgNS4#fBV@P`JO z=|TJ8e;Ah~+9hAjon0)8i*<+iXkl$geH>8tpIpy{DXqC>i587A6p320F&wJ#h5hvg z_S%OUqB0z+t0Quh#g4&$GcK0_+X~8tXdo=ZO^s1Q`V#%6y_#DJtco2pf(=z684d@k zjHu753&@6=XzdBQ(6D2J&oZt66?03HdP_#OHc(~Gm!`wd^z@>+ES_Cl>^!yoQR%m; zYVjS%`DuCO(fzS;Wpa;mi_1JtS4prbY=-Jgt4aci`6nQUG!)CyB#uM_GFR8~~L~5wnFnba_71XzK&EVrMaA z2smMUBT>IE+7too`j8!z)xkhGBVH7jy3#?3%TNzuXB;uwm2{ecuxSN+4YmYijY&5i zc|YeClUw>H#y%Q=fCobjX~#afE3|{$C@obs`HXKFF+L~58yaMwE_3+BvP{Fb19D-o zDj=;ugPjSR99fJFU2Jq<#7iAon;L>q3AqXQAj6q3pjeh@1ezMmU=*B_i>d;R*x?;& zFl0{r#;I^`QcM;LOc681H>LQ2c*li3Y=_Z_osy<;wltcITTSEprtyX}-Zw{?=4VWE zu{5tY?={UIn&z*iPx!{0zDm=#RQhi5J!bk2n7)ss94{M8d3|>^ojaRaO=AR6s0!8B zOMioHVSD+!fUAQ;{l+R^RkR0U;f(``2R@m3nkcLfAvlEd^8X+GJUo2S{ z3eA`P+JIl$7VUi~tX0JsllB~GT$Ms^u{(}dW3BW@0(cvM2H%Fypi!W-hr>Q}(_KRtt(-IcoCLBXUIsH*En=*)1XHVB!@vLNDP_bR6)|5b!j9s!ep->nDxPtV&ys^ zpYT*3-6h6ac&+BJ3`U~?vmrg45=A`UFqW6QM>JddFpH-4}M8OuNWEN^-L@R^PmC_#87Ki{_3<1=np2A{Pf;MZW z=6j}kF!(3NbxE=aK~^lFK&FsamWDi%1H;^nrt;osQkq1XoH2W9@p>@!51SD0_-bJPu;-GXeHguoy@6a6&*I)z^hZiyXpbT!*rHr-D zDYt^Y#z^l-Le`RzOz6R|(~TRY1r>sAY79wQ{^a4OkJExhewLySyuSny2T)jII9)Ug zRZH3$GtjF@AYMq(Ax(GZ@I6L6Cw?&`kf}0n&R`Oz}N47hGXK4 ztc?6Y$MDg{O{OtP8a2k{rg6JzY?H%nyM2#srOniq{JSPsB#yHamNu%BPnrUn`jsKL!pUuIhIXw|C z4*i4i`IJHE!>{+3FLz|Iedr|P3xu7KUq{7$aOME*_@V>G%^7?4{&LnDcKgt+#w{er zb7C;eC$RdM0ns*E_&jE~9@@aU9PG?I%!AS@kuvwRULpA9uu?%qcjvG>jW05QhFa0h z*EiM$d@vsAoO?fd+cc>j%9Q>~FWl#SZgAofg-%bhu%F^PG%8dV#1Ay}0P*!1)gR)2W;Qund zq63&&z2L7jBqeG&$Hl(~(rQlZxYDo;`0bXo$Y{D_L*FrO)6|wFoMEV;2;U@b=q2J* zyurjb*%>lEl@^j3n3+~Z`;ZB^CHUZs^dL5@)VMvxg*JqJI4U8Xj&ih$5yJO69nyA2 z4{LFmCBdMDhUg#>6m;xjY-pMBRUaI4@4!k^P{W*@(_tO0!!!5AJ9y?~ z-r>LpEmscg_MCaf*SujxETGk1sRiaCe%nHB%a1v;Mf26@4+nkGG*MRaklkPBB?`LeOVs`R0QG~=KQ1@-gc;QDx1c^+^)wv&zzvs%Ke@ z(H&AX_T_1@cV@du*t>dw+{HIY$*lC0=y@0IP%OpMCi^eyTb&zuAxF$?(>OwfYCEC(+mhFiUg9vMZfT^~Jiz5%QVb#Vx-SF~IaZ(Lw*@6k{2~p`qfxUTh&PrngWf61PURdOz z(tFSY!b(q!$}E>F9^Hk;y&hq1Oa>O67?pGh3NN9F$$)G?c$3yCIk4M@e#iKZ16waO zDM_JdAfQqU1`^(^r>${pF(|fbgR-WU)~O+)j70=#)M%3#>1hSEy9DTr{6YJ$4aR-i zK2$OcXh!O;4~&vBx!v+4R__?8loI6;Mu-j^xCym>Fs#ei$hfIN)&^BltPj8LqyW)} z8}6ipTF7+wiGh>ZEVdljZ9@+j_q%~xk9eyu4kU8B2(_woGB531#G5WU^+>j&yX}lm zjPJrCl=K{N*m?4aBcA9zZK}|XijwN}@Vg0Ln}9tyYCMqAdoS}4y_%5JdwDu+oy2A` zwmlMm9_)^>tBeOVPR_J1K_fiv5G#L%oLy1dC>OQHu95MsbsOcQ+n(Gb_rCUvcg>^6 zOlzu~I<-&LXSC7~p%3PAmNj+iR6}N{2YJsJ5BbnSPNh69^w$NE8LP%3Eetv4AxKkm z6$bGwljAmg<9XJiMGlCZ__|-IOwnx7C5`FKcfD_#L1{i|ek6T!eAh6oB@3jySgw<& z+gUS0e^Ajp>xDb#=|oElI){$;H3jMm;>K4Ppvdh-EAT^uMHqiXWK}|M>vPJ z>ispcST77PTLx_%S=Pvq6%DCOscHMnWOY#eq?qqoe?;rxh;JH?Ft&oTLhKHj z5zbp!O;cG6iFF-Lzv z^BkC2`)lBMdk&I2-W?;x7~kVuK#!Q=^XX*_(1*3-C=kM!SF3Ck7C4aq2B)oP3m1c! zU8=_j*;cdPj9`#~RuIve-^o)GnK1fk_A>{ERkWu5uQC9iE za1F);EOqAM6oqPRhLE9V#db}8lf+O{?bNi869<2NBW8(k5*Xf~FVw(x7=VbH;dPfs z#~+L+FgB6vm`5iGB$jwW4K;dl$~d_i3uo*tgaMI|4EV!{ODNrQyk?8l-37t65GK+fm*VdPV%Qc#MI$=-bQ0<8i}ozer928SQK`Sp@x`YfT;sW zNHBe*hLvHK(o8>$lnlT~p$#OVrr52hSLUHr&eXalWH~(V%)1U*`A|b$3qjCyA*%`% z>S4KhTEO0zfzG352zpV;Sz@zZh@?{aFlr8}Rwn!G+DA+@wo5-O7$bQ|F^AX>3r4%h zO&wLPlY!Op`3oqJ!G@leha#^e073$T4Ks+@o0{X;O<0O)sDYXBBQ=4%O+i8)?lK;C z1PBre0mfPuI1k4I<#%>?WWsc{4#kyESZybJ2S)cI6s|n1Gj{Z5#yG%m6kr8Lq@~9& z!PaBg5tu@?tVj#!4&WTT{Q78w79@nm+EF3p%q6INERp$w|!1>=#Qhx>q`g9hVhKE+CStK^OpYzkAim0Ry8EP<>4^-&oCS`O^?ydlOe z83KxW)c~gd|0C{O0HZ3d{^#DENPM6`2%z<`2x=l5k|0sQQnSfTU?q=bHz5gVi&k5; zl9#sC{`=UdJbYjgU!d|*L{LbuMO*u68(SZ!*iTyo`+c^8PqYEiqNV-xSr-|<^2M!RFPybavJy(W!>7_N=0N1Z zKm;ftmLZ5o=D}__@deGphZs+2x5PVYeVHv%LIHh)`+*e{ z$|4;j44$w8w&tPbpbCS8?RL1sy4~)UY|Hpfe27nweEJ*o&oC;>DY=){JrtKxSA3@tr) zc%}*kE8@c_f-RzSz2Sxe8W$rdXJ&4E`qO>d=5<;yII9f-vH^`plnP`~`JyeuYK-42 znWvoDt30j_DMt>x3|iXB(F?&?c4rue!$GLNJyh7Pw}mBRyQK*#Of6Ts1A~&>{Ge&r zlg1xtd$8^bFTk!2=MO)lQTDCJ3*bbu#$O(!F$9g zX@%u%vC}?Cuto8uaoC&2GZZI;=|E&5r@$C0slXB%nkR!$acTrc24!wRi#rm)a+P7@ zXDa9MFnAnAA$5LCaWF(+l8QMM$fISnL(1TvF#eLL74GI?&Bn8+Y5@|aKUlQK*FrEx zJC43b3T+q78HSWYuLQ?deP>jHm7+;hb5B?T?dc(MfJTc_=d^q1W5#pP6G%Ijx}6zd zfZ}7vQ+8{&B+E{dV!CLS;x6$kDRvr&zCRr&ER7p6y+a_(K8Zk>uS;{5`D2M#)!$0< zO`njyk-ief;ml>TZJt*f&r9Dr-*$p z4oLH4vsjv!m~GPRFt09ONl)f%GRLT-Lhww&AQ7&+7;WotCI=GvM zZZtMa@j5;f1KKO4aW$5%jo%v|NOO>Rjx@h%&X?v!6X8OpZ;bTS_qOTn(oVWw(GLyy$%k&82PjWnH9Q3a7LU%tiad8*Y!5RDvJGPo0-1J%* z!k%dl8&FPE2v#?H-z1FlW$;gp7v&`Gg4kyWoi*GeGntuWz0i02up!FK9kFx71gqO zS`f<@uxo(t2_3a@H)Wk+Y;n4i+g$cuHkJmsW`NNcJJH;vfe}*ilTdSS+^Vw(56JXc+r>u2n{IPuQ5l;_uC0ea#vPnq zgBx9YKbA8;3|w@E^*RF_7asAzz?DE4&7$2WhOu4ao|Ld%c}QJ%_ToUA8WVAPgxhz$ z9}00oW4QNc9}3}E)H3MX#_NX&gRo7!JKW)P2rOZww&%kF@yMP-o+X;(w0p4e7du*? z`*mu|1o71MnB#0D4tR_YdJ}%`MX0RmdgR5-#lhlJjHAcdDPEx7B*_)x*$DV>f zuPF91=$=Q*u=3O6VJ7g@IrM?O7_j%?LrH+GVqF*msAREaaJKOVZ4*QAIG=!f-;-}b zMbu|Rovma{WqLeZ;21h~ux&^VI#A$@(bD*<(MgnMXR(}StK$b+2Z#8Lzfs|7dl(+TNfRbi`IzNY_R0YjSB3E35aJ4CG+b8J zJ0g8d(`&OF{U0*icrzaHc&I2xw$$MwjW?!jNk=*2Ac)Nu%z~ylxCgyy>;Oo6@A44z z!=J?>as?c+Dcm4(PS*9(B}(+Xme%cAf3oAjkX&OYYdNlg3dXU@W?)wmb4yH?anQJm zbI{(MaM~68hd@+xD^^Un52fbGy;ZUK(lq2&<1H<^s6L)3uq|FyR-u;$8RYrp@n*z5 z&NUax+2nEy7Fyt=AAC+2sFf@>4!+ZP+m4bW{e@6My$mXz=&3s z<;iNS6vw%*bC_o-&LBZI5w$%QwHfc=WDDo+J)ip3XRuXW=n5iF;6e9BkWx(51>CrS zua3s!KpYpV_54Yj78`fdptp>76X`@Gs?!BHOoTJ#*g5)=*fzIS{>s`4XmK9QQ+4>@ z*4sgjG<&xGk1*a-tiTEjcF?fi4UE{J$I4<)GZ43BPH8Sd>4}8j?D<@nJJSMuhIl5w zZaVl!#{1B7a1X01J%v)CEA4?A?vD;d<^ndSfEcY0iYB3KxiK;|Sb#)pxxb~SHaz5}ViCkp?BIF3+P4*yQBKCp)kGE~me#l%vx3IQ zZo6G408RE(jB+8lJMY|T_PUWRCJ^32RF-vd_gT^4@Qlq??QT47knxGzk6E!t)JH*b zrKlAPO|h{%6I`C~;uM=Pc;+k-262(bLBim!Xib7+k2*x{PiDQSWpIV@4;xE-UJ3{0 z&{!xbE}hX@eDPF8TXC|=k=e(kTX_9th^N5*NO#c%d3x>gQLKAAT@Ra?0CHN$3?C#O zE=CUKc0D|UHwM==9$$p(IxsSDQ-E_C9T(>#+{G- zi3w+$x!7CDk)^qQE?%m6^6>e_X9$RDK)}hAsUW>@;sk6JPpL+vzaqGFtPB7fM5dNL zgC93gHbfCeP|3}d&ju){D!aePY450y4!F z6Xd{he=>T|oIS+&mlqS;P8|=sW4uGksGPTE#`N4#7g*YUhgQO@F_C<5qZOTG%f(U0>?e5_) zy$bZx8>8w-V}*aBEIJ29G{--_NMeyKmyAg?Rxa*~jsM|Z)|8$Jm{@d7^91OC1Aq1B3VEV6co4w zM7g0Itc0A_t$ z8NtqoU3L{h>yT=9>#&=R|4q~;Zqa%>QSH;_puZ;rgx13I0;8acN}GHIGjOtpaj|-7 z49hl}2Fzfg!VEYq$m3Zl`-M{LP;z=OY%n$o)rtjX=C&9{Cu0I|E^L7eG{j8-t_k9j z6~e>)73H#YGA*Wm7UDGnqeeM|VuzV#3Cl~|kVlLGtW=b{W4M1smQAuX)s}~*;ccdn zR(<#z=ooY^qRbHX3=1p6V@uE)?pE8DS8ck(BEr#uk}=Yus8fgezHW%9>$f3q281n6WH&SStYOPzZYP1&GkAnZ%%f!~tUIWD;_D z_!+?TwsaE39shAjsYcGQf2wEQ69;$8aj%<_mAV&D&uB4AE3tj2F!opmgD(D5V&?kI z0D?bC6UH#oXV*)Z6(%n1JLkjy4Zp*ermPX>5g6i2EtzxXnYj|YbU5T!XD;+l;EBI* za^{&Br)@q!Eoz~mDoV2fq}ic;N?cS>22RCMKwy@G4(^uWmF57Reqy9&xe6uH5q7?4 zl(rx1zI3UuNQ2{+Y6V7J>%wSD9?sxenu@w&IkURlR2R2Q;Y0+A8sa)TV~*^F5a3nO z^(Brheqm-xV5Lt%Xj}`zMP_sc3JdHmwCm)IlDP>orkI`}D5@iz>6nVT;!RWyerSEE z1!uz!1@dF}z#fZ+EHjThNM5j146DJw9(Be72<^zv26fIT>YwC8Uw|!sKY|I$YRMaR zn?I2>r|(db;z8pFdxbSb_dI&`wdPSeJR!<4dJ2P?D*%J^z`dP{&|N%&I{>gQLa?$X z(!lvS1Q20fJnOACv7CBvgJ}nG&OM=?VqXX+WRvxahVD0ymZi9chwDY!Dwwz`k_-=) zmde`7N;rf#?!c8hIIvapL+$wJ1pVV65Hu{G-6+*EPamNb-~gnKTi14bR z=vOE3*5R+>Mu9xD6v5jOhIXJI%D`alpmG~4ic!H?=Jml?z=Ml>yN&?bl7azulI^QD z4t~WP=u`28^jZ)(Tj&+I961gG=t>N1Xb>AGD2w*z6nd35XI#9lO)*GA8YKR{z%DUYx*{_;|5cP$_MSKH=$H=9J62D&l z2dCgrV;=?wIVg{~8ma0~Le{f*h`oGDl%j2J;nd zs7h`;XdW@g91O|9B4||z_f)`XbtYxnRKZHs`9t}zgIFTwZ8V&tfg_k0<3dG9H_pU# zdkfvIz(xWlsVe>w+M|w-(WAt+5%$Gxd1xA*Z4U8`VYD*NbOQs9xS&b!ekXBCrv0!{ zqbLoCZN_gv;t8C5(1LXwtllVp4)Ie{w1SqY-hB8_NKa>|o1Yx`# zS!@};#LQwOU=;h|HRL61+>|o37EM%2uT8X3p#n;E%vN%=f-zt}c9|pG9-FDWd8`0p zqKgTFnjZ|GV-96_A4b_KY}$c=@Fu$jQr1@4F~8&^m>JP}h4wJqi&w$gVU`>PF!YqE zZ7IbZG~C|Nz$^iWv#|XcapJ04hJ9gX>%Ad&0l`{rXEzGs(o)J zii3&>R__pK>5EiXLV>3SD^L&>RXD0m8}3$x;$vro8w6M&P?wCVdGhcwa~QM=hq^HN zk9%^t90FnNVGdA79lYonEyv|Dj>`xU7{gs6wM_+KaqjjUH42jHv6<*^e^T@0VYi#Z zX<)fyh%QqHJ`gSeQlk(r+{_rJ-X=&W?79;W4Q&9M(4RO2W(RGmwKm5H^2(D06;+-L zh1k}E=InLmh(v)_JJB44u*FYVEJ5U{v$sZV;7S8_;MHo0TE|wd6b)N}GHj4N`<_%< z9N5Q%6%+EV0K_;tICPSEJf`O;R9=C}GBWYVKmt>)Dn~`-V^mBJ8-BGC5vs<$11N3L z+AGHcWjIvSa_5t-mp*GwTweH=ql3*uzipl%OSOFi3P_#pouLPGj>zm759$F=ZDH`o zwRu1RapCNc45A6K?`ct_a(oUhCD~@r1!45)8X5i*Mi|gMwk3o5a zq}oS_T^(@4*e%8`)6bUvGtN9SNj+#CYMLjhVG79^SmE-GQG+t)Lw=k<0{+v@BANqoo+CRKgdg-)D}QDl5XUEtp_{T{E!4Q5h=9apWO;FqR>!@P~vai}4Nz zYo=6!K7<>Vp>3EB~~iHfL#V;QCT1&5kQ zwA44X0y7>PcT@IKFc#;a;epoGa;T`VTc>itiVA?_VZ2J0oBn91TD6J(6NV-@Q3@km z6HtV44vvCm2v1}KHCj}sNU77Hfm-!<)9@der^>qWN?3C)P^b%R5sm`OL6d^{2@Jly zUI7IUmqoc+JH|ccqDEF{x{!Dv4V`B1ykP{kBc|%12AC)UbyDL&Q`R3a9Z>QK3Fp95 zjZih5?XV9_PvEl}tWe{~3al}QFD&cSQ#`3JevBD77XqgG!C6>IELAZVq@j)YK_E_| zFozdqejEp&>+A5PdFYwuXj#BVD2WzWw7;}|0D;60+;~w6pMg0GZYeJ zNh55>`(vr9hCfRhU@I|pa6*D`5nL-!Z`NbTfU8v+a@H=JhV3>_qvMI@1wkAJH9AMg z)v#kKI2P$6qL>n40_Nv-0(e^hv~W8(nd5m4be)boL+ic-zc8J4H=Z)w#7);ZXvQV)}emeiVW~Eq}PW`XCuFnR@|ND;d7eiAIG#`7pFlI$d$JRuxvGAb5N&F>| zSo?(`keE#DoFp7cKn{R5bOqtD&#lkJr+y1RKF1UKjE%mj!gNaF{UA}f1n)C4#Y+-3(l3` zFP=bLkEoCTlzb(HF)yKr{71{i26rGgl;~FcSXBMX&IQEd80Vf-*q&KF6 z_}NI@2@nZIRd_)BHFAhUz!Bfta)~$ywLhP5bpaeJdn15~pmZ?n@8USDK6u!QNvqme z!bxepz|R9h&V4j=J`mZ!B^qAigPzWc$w)UDpAkh;deB&Og2+l6UA#ZhFGp;Q|LiG8+O#ZUEE?KViN1U0 z!JXZAczS~D!9A>}5`Fh9j{BJB#PGE6d_Ej9`}rwM&R~+ygoT}zgdoa5`p^qvX-Y3_R92&Nq0-P$SznZ1@QC_!E>4HV<1TzGi;y zMBhm#pJI&kojUq7<8*mOPVSjdsoge z8=K6QR`crbqvafnTE{;xPBee;L*F&m{s4u3&xASm$tlY{_#J}SO27NHx;yrlgzEJncKGe zUjNH~;T+Z*fBoB=a_3v`yer>(f7b`bhrYje?Kby(WPbdK?;raUoA01$MX^gNKd~C&P_HSK~i*_nc=hh|e^jvicfC zUOJvm&DhXbS&B%^1bxxvYQ~nzvEi|a2yvwgmX^7M!7Dt7+Mm??V8n27ij6%~#iQ~O zEZoN_3R*MZY;kj>ymFddF2WEebw>o(Q#3`ctBF-5=b7z5@^BLB+ABLHDimMyW!N7C z{5gGm2_=9Ft|FH&OU9Ot)fnT?3fVSw{Y&B%F$gMyr!v-aZ491)*s;39;DwjCk(7S& zMd5BevRaHp2`6|9H^IR7L%XwLN9_gsHqEBdl+s|zN)qmfo#Px!KT~D=0;5`{`|Qtd zZj_t*C3Aixy4@LT#HsSze8xxe4{q)OH+Q?6%W`vXySY+3XUM3VyUNY&b;}{6aWJEC zV+_ZwP;$b%bei1_Qb#DhDh z-_Rc1Zbbbbwsz~4^L`_M4NY1P#`GIm2lt6Oj&Yb|G4C+8d+cGvoqrf{+w184rHCo% zLE&NK%ecdcn;Te%Ydjc#7;zUJM%-ujKklT*gLC?yHrFqja2Rn z?|%rvyr_I%aZyZM4=N(4e#fK4h@G#;o>3`fw>p^M%)8^^{_Mr}&Z{kLO^pA7I zhPv%8KaB03au{(>?SI@!>p`ghX>;Y_{KJTQ+F`_9aTsw|9!A{yrssYmfTkyDJ*e(C zvJ@iH=ITNCFyfwm7;#4qBkt&7#9h<>xRcg{+Wx1_)q@#_5qI5T#O;Y!g%pu(CZ-#B4__|m_Og$EdT?LZ$H=;Y_u&3!x0ikV(}Vk4 zeT=Ldcn|K`-Cp+bPvTBm4=(CsV!DC%@a5ueFZ=kX2lu!87+E*)9^997d)dc7J-9FJ zV`SaHdvJfJ+si)wN!&^6!FT(Zm~P-be7UUK%Rc_;!F_ojBkKmXW7|G)mg7{}qktv=9qn8x6r#A)h}oTuGC z?GKD`9K@Zp9{em`uRn4gzQpztaU34p*T%rW3z5d8~_%g3QFvf9saL;(*~Ck01xilQ>vPFVGr&*(gv3j01xgvQ>vPFVGr)R(gv3j0OC$s z5AIG0blQbId|8q@HF6_a*K5cL*0r247kW$sO3wv<4rwuM80K}cN9(1GxI_<(9 zzHCezTuJ~uxF1caYTAW8xPOs0xRd~RaQ`x;s%aPY;NFxrxRd}8chY+BSW2MNF6`mU z<7tCS34jOpuTrX-c3}_hU#AT&B>*1WPoz{e?ZO`1zeyWhN&tvEX+8Lllt8Cl*u$46 z(*~Ck01xh`QmUGEVGr)#rVTD703O`GOQ~wwg*~`C(*~Ck0OC$s51vj5blQbIeEEIa z;8FtM!TpDns-|7ogZr7Z!KDPigZtT(s-|7ogZsI(!KDO%xRcg{=Ticmc3}@+Hm40P zB>*1WFQim8?ZO`1FQyGHB>*1WFQrs9?ZO`1Tha!X5&+^(S`S`M33S?pJ$(6N+TcAF6`mUf29pBB>*1W z|D96Rv~A%8u4ZdpwBxGg}*GZ)?7C0 zb8F2mBo8t75Ob?9oArgYde^Kk;(R&cRI$T)kk22)^AxD~Ki_i_$Bp~$clHOyI1Uf) zx8l$HBj@679W__H9miBRz`n<8 z^u6Le>*H9}werQe;s|Sxs17oBteYF==1z8Vr@OhaZtiS1_YF5!?&hl89KR&4akq?m zQoQdz|E8P!j+<+Ab3br%Kh-&>@tH;@+P!b6)g{=5nE0u+Z9&EmYrDue&f1>2bE$b% zCfkkd62&o%yESKn*p%830jK8xo{`RoNgi|5WG<7?e6 z(o}x@iju{aF_!oM^j6neOEd3z*t#dP?P&h|RE8@jkMk7-&drKdZ?^7PfOqKpLCCdb zS@&ilaf>47zGZc{2w7l&1(6r!3$X(W`163(ep$vVy4}rZt`Q%~7c=m1j|gW&xFaL2 zZMz`XpT@!&K!@D^%!~^8BEI^Fw{Ofz0JCk^5j8AV#J5lpaYT*VLM?=EUFh&J{50WY zSRD)A?@Ce+nogY{{%&nwkRh$JWAE>V_GREhu(8^At-Y}@t$-GH&C7S5>-ONSqq{wL z=Q%Jn4B;o4FJ*vWwD@V&954jW$OT6hn{sEsY@onXz!){y$_-XKx$&`>J`m5QuZy$9 z9JrAp)v+t19!5s6o5ND`L~~3dn{GgqA}>M`kOS18$QRnsH@DG>?2d*1;^1x`F;DF7 zM*RD8H1^$MdSSO$?|p%GO`qKD>H8~T8Q%XBpT;f2*A2-Bl7cS0c}E8a-7fZ6TVQ9* z9DMc9ltM_@;OQ`d_)9KPAFBm>-w>zjn|Ato1Q`Lwz&4+8n%+Eci%7 zp0(O@GVobMe=^_0X&N>~d~9u-3h5#g`2zaR2DK*^S*C^|`Qmj{bK-=#t04WeK|jaO z$c|J9-=X>B$YSG(KNp|GnPxL_HCShL#iB)W33K~n4VQ9sp+?m_Emu!P4sYi`){6bK zI3~vJx6k3vV#=QyrFv1@x5pB->XX({_ltiVR35@!^Qu;)-J)h4en$1-Eyx?13T&5y z57BEtRc!_=MO1kNaWZcIGBOnImXqEW`_xeK_QgGt@U+~}DKcgIE{F^)y}_nWXYOar z9Zw{2oHUC`G<}+GcZ>fx@o6teJz)1G2X<@Eu*je`FsSA>g7ItIP5yt2&)hD1H8})# z^^8Ea?*MbQb>hQf$Yn4$8p4XM`Gj4#f!35#jqXlL51K~|7XO6p$aqD*1U-N`002sZ zq$;}th@TWdXuu9@zldI=)VL;TB~Z#@-5~Z|27#(U3zR%GpZ=cMZ@ngJ1r)n&0-ABf zP&A`954uqs0V|ihAeV0jTDXlHY5FCG!?p={TQwbTZwXqjvD$tDP(@VXy|LO_YsrF| z9iX;mha$8#!OS?ghhHuJb!Z)S=&hZtXaw4l3ZPvC+%Cp7Bo7$Z0VB$75w)}sS+UyA zo?zR!TTiYL|L*BMY>@iL#oURZJwuwdmCvl*0T-)wCr!rz=H6oRHYLk|`!tg~@}%dUUh(KxT$dp^`6MC*a2c zseFkF2v`kxQM0 zv>!46k?f>Mb}Esqi**w@g}dd%W#T}$7xABtAlAjq{2k_1nC{IL1!zV6@ywlrRxo#+ zC@`;j1_V$N510eO%t92Mk{Mzm+xxD3$;2~sAC?Fxi>>|#48ejy8)OEi0~(|$iseg& zI1<8X10(b5Ph#m}xAYG&?ANoMbur9E>Xx9fpj7)<-XU?vUA9ju_FbuPH;&tCVAK}} zc32&q70uS&v5bKb!}?n5)8hIdh@APTbsv{C))rUX1`V&j)LO!ypLU|ieG6vY!ekMX zB}~>@4|1-6a!WxD-XdAVWC@eCm{^E1cDHVK&eetq6!q(@HJpE-7VU?w&}AN5%qDYU z!8Mi7p=tF`$roW6i2PAHe;gR=UuKp4)_ugg0V)S0)iB5$;WtkhX`Zmk{MtzKYpVbV zj|Ds>Ol|$i=t1j{7Q<%=(R4R}HVjg=q43WguZ03|n%&&hC|AE${nSPL(@Hcdyl7gV z6>BKgW!dmU=M-OBPJamgGYeysXehQ;vuRzih7FirG|Yx+Xt*&xKVS|{iCRlw4SO1e z<&4*61MhzLX|R)}Q}F@=MF-XrtlMMznyqD-;u~NZRB#J$Kv;C2G#=k(WPsw%L(>_5 zYn~V*cR^^UL+H#5Yfa`o>p}9&4DGP(jm;cMSsEx;>wyA4mn;C1j?KcyhH7~@b-Hl` zjk=!XSX*Na&yYImEpcFU9_Y9aA8A($7Aj*1dNuA3eRL;(7V|}x_XVfq+EL1}g!pJN zeqy##QLS;0$~Oi;wqy?wf72Vpr|cJrbp6_k<$f>KZQi%vQMj9i&onZ#Vl#Kdxq9dv zxIJ?RdojwqU+Ihw-QOiEOce&F7(^X9q6~L*sM!TaWX!t zic(=)`qg)5+3TvA=!^@v-qe7_mCV`IOfFG;X*^-PaTI^fVR8$TCsFRoH<(k&hs^yC zl8cUIGKxun2@79*B$M?_{ujx&FJbZvB$s3`;m=F{isaIZkbLJ-B;P%gMA^7ojH7{U z&IL@i;^k#SnGn+Df3gb16{BsE#RbBQ*7yOCI4kr7NTsVkHK9ew$%b9$i z$x0^AGWjr$d-&sOmF=6y;Q2SlGr5?_%}jp7WH*v;4PbIQlTs#VkN8#_lVwb{Fac}C z?0~GQ4*O+JRkdGMhsz=|SQEmxt#keO1T{X&EuHUat9CaJYc~ek-^)HVWXX!MQ~i=3 z@5X1SQ4k-p4)NRGrv@cHW<5jVtqrBeuV$m7StCtg0R1?vEM29 zR(B)f|by9lJJba#UoUEE&8%m%}wK*~a zA2JRC7Cum1Q6}-dWS3!)vN}+MH#P&Kp-LI9z;;hz6Qhhu)pa55||3PQ$06t0Q<( z6|RNMRzp%FtMf4wY+VA;4^h97HW;WN~=;B+*A zFI6}2v+X5VX05V<5wk&>Ru8zVE%2tk9LS;plx_fnPzQ2n1$~i*fPo&H77F7{i27ue z=1WjtA%l@A0A61X*NFYyGVJ%pPzY~beq4g5%FvXls2(mW1BwcKxqb?|5LF^*cRmuk z3#W!8%0(s0fw?8McO!8HnP#GgZtDL59j0E{+tK} z8@=nVfVfVnnVO3xE8U~?s1JPiTn2!kFn)ecysQ$undbCK)9`v@m{zrDI9LiQa)Pp= z!jCVPM?z4WP<54zx@N7iwxULc@+?UEj572FlwVG-1=Fku4VT*jMM=QJpGt|kA(

KVa^Y=D)4LWO2JkP`J4y6Wggs0wluiPVN^IYC}cq?VQw_SZiH zFGA%ZSqgjX1L;NtuLEIOH@P4n3jo^Ctu*$q0(csiEqCG0BI# z420_@%fhn)C31QWa7+(?_R`z{biFzNxv6%l)YL`-5@ib|%1)OkJ6)n|sYKb3tPVs< zeKi#U7|YtyK#kq*=HVNS<0UGpr#9|Gz)+^%L5OnWWgs-eG6R#$NK~SAbrP+M%F=LI zz*iTTq}vSG5!LX*vrxQhx{G_1ae`a5Fo1?fX2?JURu;U-_nqU^he-r1%@^2Q)yQ$O z=xo3YPd)=GfIlVy8Lch}$hrUo5D5U>0dpgP^W`{{l|=!?;7FNS7ciqibZ4|gf~$(*U@MBt@d5DW{Il}M z`HG4HU_I!y#cezb0(S(Q9iK0O+Z8TQ06IXd!rh!b**FQ%!jt70MZqE&R7oIOElU)x z!h&&f0-6Hy@<1M%A`3yDSrjl8(@BpmGtMbv9*%ufm+Zc<$Ui78I z?Fj+Z#Jt{`$R3#x06`!NWzh9#CPbvjBQ{a=r&Qenjw_ic0czFmmh68Sr$E2Zvbr3Y z{#?~ZX9w!cT(FzkQwM$1f<@gL2Uen7F8DbvU!EO^AQy$&qgcolX}hyZpxdg)$eeS| zo*s6eRveze!Yv;M?Y* zPDVrBSO9q>3zF1>mh7-GQX3U8m=-9JL%#fR0i#all#&q?Wu5af2fq%%99xouO1g>) z$0_DGebQ!}DoZ1kA+)a$jIbGA2mvOufK{ouodX^+5YNyhfCC<&_0U0dNuso)qk`xt z2!ql*-&utLBcWj$cT@Ix#wc)}YI7FsHS7^U*5#D4OQ=~nr9R}8IXJ6OLU|o|pdzA% zQrkmygtiVrWgQA-VPU|P#pa=NjL{xWlZtWU#(@o>1J?cE#zUYLkVGm_BVgiR#TMuj zToZDn0=+>Z`8v)jM-PVWH%{w?ZIs$b39CDjPA*n}(;TD{ELph3hf%;#23MKr0y&{z zf=WODO*F`zN-FZr2?4VN1A_8{v)?gJmk_Y8uBUq;nfhYWoTMH!WoH>@D0zXU4wrD0 z3(J|4r-6er12FEDR#aBxlpq%kLr|=7;L`aM1F)5qmW)>96v%>t0z8|DY9(|4!qdhS z64Xo|fF!UgC}DAx-Q{qg_|la9bt9)ozNO79cZ3At;S!EQ=g-7QRp8=o&i;v!E77_N ziPoX_!UX{zT4zut(7r-6P~vS4+gAXEDVzvM)AA%>Xa+e>j7L6t;~z8${Bznp^b+ID zFX1J|e{igD0ys8-qf$4n+C#|r0y**Q0DwE=6^B#$2+Ax&4KPNHlN^#Ap0_~%$0(tO ztmyGs_xkyACivs+aQxIAUO17KYC^zf7&%e^mPqvaG?@pM$S`CkVSE4yjxb?FDs=P! zU|{0HGbLn$2vO1P0y7#m@f!%y1rq}pO|vO^$I8vI!i}%PlzOh2ze` z2C`7YKlZZZwlqVWyuU7|7 zLZ2u+wp2mp;IcVVBtX;MyZ4VYULsWJw90p46gP7$|o1vT?>xT zDTD7+S6)fioL*F6KEA9Dw8cL$8H1^h=Xkxe`SC%cqdCx3RLSX?Fn<` zIVx9P3C#m;c)Gxihrk^zmz41md3L%fH|baehSy3HfIaUr?t%)%IFa}WRY%^K@D5M?N&P~tp=(Dokp|$$*h~U zWZz|+ui85q<0b?VTXlt>$w)pM zY(2OD@o0NvS8$cy4YwdPHAbIaYZPJCvGGmoY$n@;K#*6gBNxvGFt?FV^v^BcpIh}$ z?3UJ>-QsEN-`MIHfI^HD(*Yq@yvF^2%Wd3EXa3DN8}S*~J#UX;BM7+>+)O_aIboS& z)jp<*+}JNrM$v-TBh+jBOoqr!x|&n?b*J4;{*R4wY>*4Uu07&=jMH%WgXZtP5|Jff zB3|Wnd)4(#RK?zsf82zUUfBIT54!=biCZ>`=dGvCF(!cBO*xv~JvCk&!F78u%cmKn z8=nHJzqi4|K=fl$deAuP5@RAeL37y@11Mz<|J%qB#jMx5aU_9RA9Q<_z^u}qm_@eO ze3@iSf}~zKxEq9~dUC7YE1dra@w;-45cm~mZPh&m0$%!vL`(DGvHDCMKbTK zf)Xs@mk|S(bt9--i(kFgb=y7YBOrHZH_Cbi(kCy-7A=dwUEU`sdIjpiJ*C%Tee%MCdupGc=oP33 zcc|B5ee%MC`}{sZ(JN5m_9rtxpdL)?6-=MJ@bIOgPf+v<)PuXS*J6G0!h^f2Pf+v< z)PuXa*J6G0!h<{9Cn$OaO5927!Sr6i^vMekUm|^iqF10E+|gc(^~nnl?wUS9(JN37 z?%H09^~nnl?iqc8qF12AowOd*^$Mm>UU>LY-zO+~1?s`w&}*?idEvo5vrka;3e= ziikyFD=HShZq0)UsxXrD3a1EWN<07x&Dz8pJ(US~JBx*K{K)rJr%!@CUz@ zQq{BzdvMQA8(c~NJh(4PscPDVJ-9DU8(c~Nh&wqwfINIVCD3UX_VDGBw85nWz=QkJ zl&Yp(*n|5!X@g4%fCu+?Q>vPFVGr)h(gv3j0OC$s4=zs$blQbIe7PcRa47-s;Qn4p zRnso)!F^@g;8FtM!96FXs%aPY;BHJCTuK0lJ83;=N(pq@g*|++PrLD1+JKV);KALJ zM1`-ghzED;R|q%>P#)Y@B~jrkEaJg^^;ZZu2~fnHv>tpv34mW=5tlEmnHL&A=n1fO zvS?m!ohVvHTStj&Z$R!^ocfG)_Eh%EpLIWmEEreOc*F(955K%_D#|HYSS7YjTSDBk z+1e_^W((H{tasbpIBJ%04R&qsdAcV8;uWw-ic56VojU3|9(63SD|Rmqpk|2a*c5JC zNGPvbkE`1mMB4@2i4Aji7FU|!cp^>?w$<|#=|&fKb3hu`V$=7Y4}hnw##(}xxbWke z8_c}0Id(6$AdAB|6Mt?%ZeNSN=&Kem%mG{dDB2!eorIkVXjhx#PwF| z@vO82&u$pVumSaxS7+V8!ljhJ8zx&z7pNCyQT|+IEz>`P`X?j=p%E3;hQ2}Oy@3#v zUlBQRx1Ro_@lzi77dV}N{k7f8PSg#8M5@bKc%R&Ri5J4ep?*t2C8U!HX`S^Lkf8SU zkMVkklOc`xsh+(iuG?kf{)h21bD*Ds*3tPmuU$$&^AdmJ%yZ}Cmv~?BdKP`=Ik8pC zto_B0U(B$KOk6&7J+7e=K!~IUI&j@C)edtkg<9cm&i|tkBe#x65WxyteU-kBkL@{~ zC;oZX`-UPkcu%XDw~{pOkG;^Q;6NtYiZw8TsO$~`_xtQbjLr?0LnfZT32&c&8o9RO zB=w;6)Snq`&iUjUYGFLuib>2|G(52R?_UE+q9anO3p zu_X3o&6hI+#&x`);DEJ0w&@1B!7qja!VP~#-yw=lama4o+z+h#Shp)SH$xqIce{z# z7k$WRorAjR!yMVsDMrZlVsRpZ?i7>fj&x-4l>3b9wM9aq2`r?5xT5!Ag@S2E&Lv9A zhYdYqJCE@-Wu$P9nP05?@I|#WGYA92%kMFHPPMyrWQ}oy^^jfqT~aYr6Sy}v7mRO1 zkkHscfIw;Hx$ol9jHFR5{hp>O(8<>wEA{I*(M>&)cCjK&;cgsxlQEY>zH4e2?S7bj zFTFfd{pxrmuk2Hzq{ZXY*bT2a;xR7+c)a4Fx?Y02!WGteTHg6g;chC781r!K9(V2R zf$75KYHj18zxU?i{+)T5&MEwP6KP@?w6*F3Y2g4WO$>et6rsh7gKyB1bx43f?N4Su zxn7D*ahyvXB(KK-&MJ$iX`L21 z^3a%hi*XaW7~#|v!3Lb=wOfW0$Ds-gBbmt{NrNyaepex@6Dcmh% z)*CAD}DlrXINrmHWXjhnF{9evth2EP6K~#9fP?&iRwmgO-s? zjN8Gpn_hFp<)(u;aVi=_9nrFR(~WL3Y$4L`(Wmnke`)t3Y;@jY-6u_>FEQ=_EJxs! zobMAiXLpBB-2i?l;y-O6Cn;Vbzj<=cwV+HlpG0w63wL?`dWeJSljeXh?!**i-y%#Z zAZeSya%*em{EeC(%CFqElKs$KC`d{#6Ojlf2RBp9Fm=JzMx3EwQiWlDBjn-{bgRPM z6qs$?g?rr|@ta!K8Eovt9*g6d8^Iax5y-{%YX_mGH0)O}0DKWI>V;q7&YJl1>E3@j z6J_c_%a}`yyFr$kIEAV~?=6Ed>8S`aSEwj=9gka1(vHWy^eL5_g3AQ_D054mBA^>@ zJ_)I(aXJ7O7Y_pNqq^OVg^w9a)U;g@pdBHblo=KaUd#E{ROa;jPl99Uf|&Rl6!w;@ ztxZhsFx(vg_Ry1xhWvhOU+k6}Imv`+PI5eG9Q&lP)LNmYDC8~t zXuJ1tsWEzwpmF0s#3g^Og+O~=zlg$d#HwF#|5TPdutH$^7n_+Y4}63+9C#l;+r?3z z=qbR898!iq)h8!)8uxHkaEv~$@`+fO4f}W0Uhs3_@p49Ll%RRa({h_1;8*JdHw!OhK@72m;S8}*I^H}j_6*m3#wn(aJJ)C2tL_-xqutJU z_pvv-OBFgq(qF)3$ zpRZ$Yc={#t)>mM}ZpERo%v=A&sB+5%M12$8LmTw zIKe^Mjn~Xk!&ne-70upqW)J0F?N-k1lQZrxR%wuX#LsDmpmfZ!$qK`t2pmh4HWBo6 z^@~6EBx)R|0HJ3A`}wO7HPvk0?lB$4{X~ZQ+JzVhj6cU2hPCb)yl0u0VdnwC4_X2D_RqNkbT zz4f-z?7v)OdqQ_K|(JK2IM*h?$ov8iE=t0xCON24^A;~i z3UA)ukYFx)8ohYySdWB}CZg7|c-D7~hk6|Sc&SdW^<7@v2BqiP9}Z{PqbAOihV;*# zxZ)t^IM_J$Wn(SZi^{?H+jct(CAaNNSgMGGFwh^0m6?i_%BxCJ4;piBHXczGv}SJ=i($gC>jPygq1r8Z3OQ>Ea(6w5Toqm5 zJE)35I+u5Rfn0S7a~P2`!c^!xsInnGyYnREN`id0fjQc%J9*WfZ69*~VJJKiKA(dU z<%D_XZOqMN4(s3QlX`A9-}8h$UTxTg9(dt8j8`wHZGhN4 zPcWxOt|!cvH#s)E7Q20=Il6$^y|LSOQis=S9UR+kv;+F>?^?_8tVeB(21AJsFNFt! zi*t{AV|NTjS3P$O{L{7^cnbI6c;a06As91}YZF-hkIninjCJv7^Qz5UnBa$FoOU=W7mHY~i=)T^pM*7%897 zQjZH?IDtr5-MnKVQLA=07Ts*nXwZDPPIt5_+Os`XO}3529b9r(cbnevbb_&nmIM=x zg;V%nZsB){+MmpL(0KML<53M7eC0{;#arzrRhJ|pS+hWyuRF`Il#K;{RnDgE&f_(J zE^+5X++=K*V?WvOoN{_)n6zoWj6dD@g~LA&GP^~0UhcH$&I>)w$ABKUl}_P>Zs9gh z;YdQ^IPRhcj9)r7`OZh(st+bsEk~ywj0daex=-$W!Bco<4~6e4atrT{<39V_#wJ~L zLrlB_g}G}9{9n<<+)CzlF?XNC8Z=-7i@e6d$gO0qi@E!l!&Fh=Es~W??sG|A<+Sgv zJL9;|S!O)u&~#U2@>Ep)pQ&(hH=W*SJg#hRJn3OnI>{aB;2wGx6M7%?x;RbQ5R2`j zWq2ZPT7cZ2j2^TE-ZFlr)YCP3cXNgToz)IwdF3?M>?XQD9;HvtPGT^#>9ohmz^%rw zo%_7+zQ}rQ!6Sae2%rq7W-u#vzl(mx&$#udtSgDyz5vU4eOk8#hav}zQNBsuRfaO* zYEtn;oHT9VKM{97?Nau#rbm&dh)Sd<$PYC*>lDg{ae0U|4tD!f`+crFG@qGc{6^PG zTn1YDL_z~#XfhIGD%7UpCd5z3`!;hZ;>FDS#FEo!thw>IWEmIRS7OjxaxI;P)z;l& z-&)RTp3ooVvfJG>#%KHo2a5nc$b~@+L&*USCA8@%7_|TDAQm8jI z6@I(OlG_v|9MRUh`YQZ;IAn_*Hz1C5#fr9HLH251R7NF`m+Nc>P7! zOKihU78Fa)^Lx}sZYbbNtYj5P307ADmR|+;pOoYHL3A08V~lRODwzAoY>6lXJXlf zTr=JX@b^x2z%MT&(DAV7$l2kF%i!p=;k#lTfJ353!uH%dliyxh&({3ax;eIDi;cVK z^rgm2a86fjQLp6EsaPZ3j*4e=#KCn8ZJT%N1S zI4xS9i&fs`d2%Va*(H|eIqhyaVVkjq7zM`eUo9q{$;8M3b$L*?0mw#JThJ}AvRSd^ zvy+t#bmj8dm?>lI#)34$Fk{PCAp!u5bbOOx#>+0URqRZJl8U3T3u8C=V|jD2n9AAR z1o>g7m@3{As`6UVx=gy;xvc5%Xh*j2Q$%v59m`FXffWR-!`$? zy1&QlGXAKZ6GbMg^0OW*40FUq>}i_?sCE$e6(b$+D^Ank_s5ovv~G7Jl(wMRU=_i5 zIgqR#!6@D8`$i14qsYNf7f`0;(UyGtlBl$wgaM}8VFy2QnBKxgPWQaTcHOL^ep~W0%G03 zPp@qiE1t3Tixn?1+0xC!b{y$dkE%Xt9CMz5F9O1m=0}otS$7w&{JOQLcqPA&wBido z(EPg7%Hz?K0NN#1Jqmb$yfjn&T(Mi$GR(;;MS{Ejag7jvhH-_nEI|%6R@N|iopt$h zRSui23DM_dUL0*%n0lu>g7?enANQ}FxHX84!uE!+EFv73{T zO|Ug9KOiX(f3a#^Pt@xT9|w2-L&jFlNCv|0ts01rPA=>~P4E)WVrpy1ov&~|c~u6v zuYnWcuVIf?wJ`T2bJv<Ai^&|v9n^UI+L}5a`k5PxSGG=Gl#F+JB+Yz+?2iF{dm*;8EV;D%VN{$H;wHu z9jiLcJX#UCp%^;&nz;WK3_JMl;3wk#BI|MPVHSyudcG(?+!k_O;{M5+Fs_@a*jFAA z$l~T&EjX_~W;=i@7S!bXFO>JK#acP4eIMdr>);8->v9Pm>-p9Ov2P2)dw?2Pzt3mh zTOsd%&{{it6{Cug+aG(t(7GS5wnyNFgYf%k!2MXy#m1*1n2ewM@--ZMu-Turi$C`nd-R_nX ze_{L=dEMbhe{GH(__1}n|AF<^9{=h>YhULBCrM7wco{dsCi#gUuBoayFFtvJkI8T{ zCDpDHBODM5i4P}mw+9#8hVT~an<&DhB*=sSN+SN`{G!HFI*tG4ouVOLiaSk4nJ|n5 z->|4gI3;#LRPd{`5Q8e!a!qAj5MQ{!nj(^!2+hQf5Afq7Em5qk0kxX&qh(#<;anuE zr!%>bNgI-NFMunyJd8JtH~9SfOgLL#w-m{mkD2g#!H2lJ`_M8beESfM#99Jg+k#}> zV|>Q#(}!yL^8+Lgb3A@H8_Aj{m=NPbc}zk`);=1?J@z5vuYAN>Yeynkr;-bid-y4+ zWCjK>n!vrW)jGea{O{HmhCsN3I0EJU?k0N z#z2k%_vjN`Oz)D8Q!z-y_M1m{qByc`BQ(!jPTOU?$(68^fNaf$%pLFMxIm$w4OTgG z1RW}t$%cxq8H|8C6@ankLgw(TYgkFMwZd%O%#Djo^C%)?(~psAXoq{luK_-Isg3)T z<;D)Z{vx+sCh*x;@P}$Yh&kX9aB7kBIb~+UfV3|_Ou`=VU@aQ4aHHHd8{=1d=B=-> z;4xs`nt||cHJS}hJrC^U^q|GR*4UW@8TgWNA{pBf$ylJt__#+hT-Zl4XE)L2%jlT# z7F#A&^T-E$2=_8JKJ(V?2^hfi4zsmh^=NG2CR6hptVYQgnX^L;?z#&zbZ4SBMq@1* z&)Pe2aVK*)1_Tfe?ynhdvvZXwFgkNhkR5)MdZt`IT?dhH!-1Y*0I6w;?zt+$;=*0zMx9#@tm`3-6#1A zj9su74}A=|Lqro=`6+WNZH0Ofp>1S4B@k$~#U6SCuF6AiD1zkHl>&on8+75b*xJFG z5=`z266}$p&YsM#4WjP!)lQ$ZobgXX4FzR<>|oTUjOGM_k9GCf+KV(T0KfK96?$xr z`X##?I4dje2mZy?tVjDrN6b%jpftt(P}r|O}v)c&C8f?o0%p6c)BF?SnXmJsV|P!iYjsxgCo zBr8I=^!(hc*t!dxsmr=KF5H%0;S$!OgJ4zJu$E9`#wDuVy8C0l z+9|Q`We|~C9?X#4LmX$ zUj8G(4A8u@Q>&pT*hJbLdjxTT8Q32DL_89LjH#{8M`~H5ME_JpXewp=nY=C)0 zf!SK7^`Pa{x2VxV)=y#s${(z@pyd}^P z;2)X^Zm#d%4{?sOYqUI^dakiA{yd&TN30jN1ZF<+nVA=3mu%PpQJ)*zw?nqiMsBef zuo10aUn%dKN>@d!e?}qr+#~5>n}B1pGRdZtB6hVH-LaY`X)^|ZyBFz z6dS~PxTP!Ms{4@TvTTX5u2VfIo za{WrkUCXoP#6{L?vGsm=?=FZ~N3p=E{n_FK`OszJM7d@c6O}`P$oLI&uyl#!^q@KSGvi;{afWJc z_={e>UcC$MMptaZ2XZyt^}VqT|57iAog1*fYEVs81cPm0(*~R^rWZQi98y5~(SDcU z_Kbuo+l$2nyHA?){$~7JZtuj&;CsP;Ezb`uc;qw0#USa5wKqT<_U*Mki?s)VaD6R# z%Qdt1iuOC$J!AUfTd(DU-`oPVHpWUIGJHyHQ$kk{PD*BpgHZ=Vpm}w zyxthviSyw;Xm@e3R*<+T0y^SL@lg)v`w+2bo`wkR<_cOn4`9QfQ=LdbIoQ?yu1AjX z6NAo9M;@AnecSjP&d2&^t=nS*9wqH8fP>{*p#P3V@95oR}7fFcKO{Q zU}pzV`>#RL{f}RDSN|R3F9vl7T2Cl84mgWsS+R{hvbPtOqwou{y~6r5wlP;pj?xB9 zFE@r9(~2A<>~gH0;&UQf#6}Jmz%pC$rDenq&6M!X2ELe}l|mm-^N4Gm#?=+uxQ>+E z=^`9Sgxp*K!p?XT>^>PW+|=uj@i*Oa5GvGjm^(tBo;947J$n4X_XYg@Xx%kM;=@l^ zaW>TC(TVYL;JuQE6Mk>1Z@zGf{P%gP4vYIShsSDXrX|GRJ1^SIfxm}*f8L+{7jZ{kWfb6f#ZIWX{_Sdt#_pXOB-d;LHBSVFUx zh<`B<*5-}N;KaUh8U0d5a=&4Fm|d}7jD)7Yfl(qUJ!n4l+h&GbmIL+N8~f#8(4y{K z_{Gk+V8{EBBBpLlIK=%BC$d{rPw>K#4}Qy^aNl`xg!{tb%V}?!N3hVNs*uLm@&DO- z^8meyD(}DgJ_U3TNJ2KY$jt)XNiXTnoUe8*aEvejJ7v|=*qufz%6nW_eNEvrTi}?w@?Mkr>k((KWbUW}wBv_? zx!(#(DH_>*)0~cg^iUvGpXGb zV{(_elgV=XRi^&o64ad zEp3J$0r4~}EW8y*n08I{EqFaC^Bt<-b+GaXZtn zp_mj>dsC}9)xk;jN@T#@?8NfEu(f|-V83Or69aE&&IJ;Cch=`b+8F1-;1RC|@5$8~ z>r-^GxpRcV^hCV|{W-~U@clU~?I@Q}SIQ+BkiIlH_p#vI ztNl^8SIuTd@DjIdZ{D219zN+a!IAcsa#Z+A8_cUGU;;%{4U23O{TOQ zKW%<7RtLIoszq3@u8R^}M*@q^|}?B_SCv zLK=tNZ_VZp+go?So9uyh1(Te5NgL-EsH&SUNmSL%Urtoj&2pcBRni+M?$lIa8BDr8 zLD0>E4RfXig~#Gek$QtURG@hhPMU7BV_6H zh1KRjJF3lZN=rZCb|0)ueMZIH`B!kT)1bdU$IrpZj|aF4P>i+h&r^mIYEw-UIlxv8 zfP2?N8cNr|;IPvlGk2anDf9h27SA!<0iQJ7;aKz{z5^0WJYX~buVe@}PZwYx{r?Jx z12&q2efXAO(gBOTn+$}&_v;bmcXcPe2JW`HmAkF7u!pCg5=_>r!R=d_yZ$cH#aF?R zVKCejJ`(ASHAe znl%y>X*pg)a@1fX^7JdO94TXIVaD6&MZyKWNbAz6Ao;kA7tUUE^4#E9%Z~{ROnk|f zz1podnR|X5UG40+nR`D-7hNPAPcXnP`#n~5k-HRuhwpgP7Vg|~ZZjWZ$M1SQ)yt|9 z0Pq%P|J8YflFFpt8>*{=OLIw5oy9L5TH&mY-h^77ngyzH5IUvPZ9Rsz7>dqx7_ zrI$TBI=xUA8n}%Lc0y>L+jgYTMPEKzL*Q-I1%vUju0!w{HkYApd)Sjs4^B}16MeBl zNH33b@ImMPFEaJ-+QQVIl({#fK{8`aN=!=MY~w1a4%^Vz)}^}PSk{B#$sY-(+s?3Y zojwA$Tz6#gQM$Qv=UV=o8_eZSteLj0o$IAq8rnnKp6+b1eXaWTT-3(JSAAVQc4pYf z7e0UT4F)kdNJkGdpb;*_QV+OKgfqPnV%7e;>S8Z$nGz&{DeA zhBLWZtEp=>p(AMmHqt#kU8$a#wuFcc8s?&`m1(<5IN3C1TySDAb2Nk(hBI5a(kog+0%`}rV3DUy+S8^dy{g})d;8)( z7Ithg9qaE*VApZ4SX*D%VEg*gokY-db&ih8l5l1OksFBM>*?ZafK8(}zLdrr+igSV zN`n4c(@m+BqYxvZ`QHRHY|Sz-U!CrZbWK^m?QC1c$M{C6V`~~H*wod{ST;0rp;})$ z8XeQdaAt#T?CJr@C~UG_9UTp@$V@IsW7uMv4^8aKRij$wc!dTeuh*P7Acr^A_im${mb?n^0|rKC~GnMy8Ha;=gdFzC%~%t$ERvvMYk+DY&GJGnm2 z&77{z5SHj=ezeW&VjO0IaTInn>s~qP$FMid{zh<;ZEGm5k0fY><3jkurg=bnxHp5; zz4wNk)D32z>lfYoSt^x-C=PNj?}@&~%V75J;zAEcSB>!dBvtZru;RVJ$*kG;b3ZFN zzWTY(DT z1!H&Shs%oEyT3lVMv%$k)~W(f_n#SE9cO*8DC^!wSVn!VuiD$zBgAjpDc{#xZVPt( z-f+^-gYw`#JD~$rbBq1G_v@!OYvnq1?~TzladWTdNc1(WbEo2r|KY!KrP00DN14q1 zCRn;#ZOY;3-G5~LaC?H@nAU^AW3LJ3XbrUD5Y$DQ-erFHLefaQJl?mX=mqPgTaDS! za~WqOG&nxs;(Q5osQ=+xEN%B@+|u?y=-SRDg5-3QlZIJv^lP*P4tyYl=yEh?ww~oQ z*#zdkT@G3>)5kc}Kd?^Q@TE#l#rZ%y+^)<6+}z=#w|R2fCCw~LU=J+*c~F72qNCR6 zn@X-$a)pc)x2pQBvfe3V^nqJ#>`Z$=AqX6Kbme&3>+2GSI>|nbN6pvRoq6Du#N_e7 zv-Zof@BY?2@Pa`5c~Jd_pfb8G^QP=Y54^4?yfyJtsT?XNFu$CGed}4lcz1(f+^H>m z9$i@N&TN?!9J@O>Za6sZbrGMzSZFt)8d>K8B%d&cEUvrE*0W-o&wDzkl7G%JzqWkm zKm^^wF?5CdQRa0$$rRw9)tIH+m)u|^{oYXV@30C* zzmbg0mTv^d4+qB%1;_s`IA%SaW)HAS&5H(7$m(6kf{EgDh`9Bv10pQ9Gh9L}qMD$f zYXXL-7}Go$DnB}ym#dif#PN3wVj0@L!7IzOePb(gWjE}!zb*9@X}9(DLG_J7c~R*r z&Lh1({+%6GdkX^=^TUQ|j|Z3Gx3Cv%x}j?8m{mPX^~+7A)JXvsN=FskO^!2zq(2*Te;?&vOl*4Hc4Zy<{&J z6N2ES++(%%Bhj};ww|lph?aj8-#?tauXFcNW7LZVD((*!MK^ic(ew?v8)R38r`s4} znF>qj){m;RFh3g^^YR6dColI9;eM%*8H{cdTQV7D%g-Rkz{^*=xxw_%5ibIat4DdW37qi|_{`RhXAiw>qD(`J2(gC-9?1$Zc_ArK=;WIi-K zIf_7JpQv;Xog&muYtg`rKLk49`Xgej4X3OgFt8%bIz6a9)6rhIFsS=9+*4$sERo@$ zlP6lBFTDL_~Hdt&bZ$LW#139+b>jY=!f{>_vS~BCFAkXa55e|LERxC zGc4#i65pnu^*P#m*3%q5L)W$(r=XdKI-`zvZ5 zddYj&(G4EDKGq0WUM+!|C9EE11q+K4SPvh`y2R7&%)=AO;AZqanJ07t=Hau(wol$L zcT;c*RC~BhxJd>+jD-cO7$oPN!U2N8%QQf72!PL41eD7r7~mEW2NVc-R zK=W^b=8p167#rz4^@0Qcpv<*u0E)| zM3WBxo+R8ORp?po*ZN}mlsrj-ra_{h4yLw_weUoM+b#O+#xL|y4xVn;(?dM1I+Lf3 z3xmoj!X&;4@saPy8>JWmr;ASC5v*WXpZTcX4ghf7`dC`r_TnLH3r`anUr<5-iz+dG zuVfzC$kae?xZ4hIQ5WLCzDKsW{*IPp`#tmVpuVU8-0;YjglQkWB&ZUv+1qx)fWI}5 zPGo++d4%p)I_`H8u7@y#U;Hv-$;{tn9@Ry|UbxC<`{K8K#=^{Dx1*38_Ka#w9^-m2 zd~y^t(EEMA5b$yK^6TmItLD*ku&g_nd3p4Q`bYUL!-xltMcklR#xvs4^HoJNf~Nw6 zVjC%iE4hK@MIGqRmwhjOKIX+KHwKL`&Lc9BNvnC(OBzQievMh&K+H$4hn4yM!|u$Z zZwXv>-n?QS>(6O%8WP7312aDtG>K5!Q@-?BN5LXAU-}==dYfXSoMfSyTehIHp|wV+ z1K=8;q}evZq7>CLZrf^$o6y!OIKoR6`swYNjLKsT`srQ!S=hs~&JNP*^1N)>JQJrfv}uOT z7LJtO4L6OuMMRn)4td3yX6@xSyGgt4F>%N&IK*tbhte-Ksa`ip{!qWf0cLs^(|p#i z0!iA(8j_BJA}mC3eP-XE2=I7nVK940Q+Rjgv17sIsrSjjTEgUhY;u0XjzNNRw+6Fj zMZeE%`(tpf6DPoT>!bq3b~L+gsNdn3?54;3B528n5gD_iIzBD`Wk#E|<*|NrkVh}q zK%WKMKI)gp$JQ53?F0UVO&?pY&RpgJbv4DZY4*!OYj%&G)z4`OXQn z<0$P$6T()HkIS)j!pN^3<$6v3Uprdwh*}_IQM)mnAbafBVpKSIr(*{<4>nA%3EEUC zbTzdtDT%k;Zx|}L;mj`AuN}c+yRkkwv-{YM3?#Vi$~=Bjamo05DOAlaRy=DZ+YS}H zOrE?nI4zKh@p!R#JQxihuMhkY(mU&oQIAT4>Mg-h>*c?gy`FwPzSYmvyLSTaiHr$@ z+4bTo(7Z-H*LpDY-dBT_o(*}8LBLRpvK7JX?zk-1{AEm)oCU z(a963o|r=%$He0EMH$oT>$THi4NG30=3Y`7{gGpYIVs~7vp$zg;-p19Cgq($XUz65 zo{Bz-Ch)3x;w>*ewM5fMX5S9GX&aB&Aj+AFPdqG1D7crHIr{xmcZ5Yh6SB}7NoAj->9cH`4(?uLx(bEpSyVYYRTTSN2*Lai#)rC3pE&{A3ILU3h~$Djbh=N^1AzO(Gfw_1kr_$hb^^_ajCgip`uGQE>x)W z8tf6aw>om4j|m-8zz)Z>9vnY0=*^;ajkq<3))NKH8*}XI|5H+@^c|y>%mFnMkIB)k zL7(RC+H77{hWg!r-rHnnupQ2DOk%7lHy;hmHv;oB%N(u^O3n;Q{?V5Fu;le1m=y%w zHuzLgwwFUAn22d9r`~;wlSsRl2)+aVK{7 zSU!={P|}eKacgw;^>o?xc6}A6t+OxY#o_TE30BKL*PrU{vn9nS7J>-v^7&v@?K^<4 zw5h8HKT%U3_2kt|^|g+niQ4MwSoR$C%V15?T0X9=coL*?bb zUKm%0yBhlXOL|jbM;CVnG`FSjERKO#)$^0_&SS{LpFDKbX~Fw#h)Y!-?)|1q0anYQ zdTn*gt_`?=VehuCp!1+(uNEL;HH_n_%h#V`ei%AxUGM?h*_meS$BaPr!We-ly}Hdd zrNeXzcko!qP;KXfK@5At(f0*sfKh*^9NJA5CSEx<3RKs|2=sTh;b=^+ZL;a^zP1!> zJSp>}J5R+rS#Q=`lQGv@v&HO`km4Ix^(E`wS~PI<1;Jm~l1$0!nBar^ zQ4V$=t=9hKoLGGOk*Ka-m}@T&_UhoT4l;h#n!)?yJ_;7KV=U+R!P9)gw&1V*!uK{@ zBm~@QH->WX2825RSLXUX@jbzr$v9F0PC0O`ymIiy*ve^tg(| z;4a1=Q#ly_0OfM9CyoowE})ECy50_V@jQ%wfYuA!V=*o$mxDdw=-|T#pdehdu%Om~ z%grBSxmwC)VGkYk>EI)I<4wjKYx>O>19STUHBh8~9vTtBR#KoEQfP<=Tnv|M5aKm{ zjPqc4Vtep6wA|HUI~rJM-yTL*+Yq4M{%%6R(!E^g_D)pSSXZ6+z2F==xm=?gqfL`5 z+oa%Uf9G=ClQdKwfUN|boHd#tG>cB&p?<{5CMr1rMlR^6r@z}p0QxErUv`t>!_N#p zn%9tTQtDWB_1d*|tuB=6>*14}z0GK0wA-KR>_Y+A!LrZae>3s02ZO%~21aW^yYU@2 zjF$7R-wA2wKP1+D@Ljj|jv5f?EbO6oRP|jK7U;392he5sU4wf^4G6a^T{gU}crlogYw*dCvz4Q9-rbYqm3*Svk@4T*Hk9i(^@}0N; zZfa!dvSC~p{QbLWX$*BIWu94YKlQ+Kuh~ER>8(Gz3T`bLnlUH%6h`_T>w~I#*`+Tj zeREnc+^EN0-Op@{jQN$0==|z=l4p-mqOgo-?^JRD$#XkNcCOb?m-}`JpfdE_`LfEN z4>GtCBGH2*ukmf-`GJ#ycP6^TushPjCY5yd?*~F){27^Zz5*h@Je+6R@|t&YEXu;C1}- zm2$$~m;cRT^K5Oj$2@a3rTOL#aEJrfcX)W>3!IrIjw)w%+#D^*yk|sDxA3&%K0V#Z zQxiyKcHAwb)`OJq_naRD7YQa|9a}xwtJxkQC|K!7pEMl zRW9PyNo9&u>Swuo}+0^AV8uD&MV3u+sQ&|$o8R*4%_!Zp_#{UEdIdi``@ z+ucuen8P_5jpYLnISWX}ok?AeZ5S=fVB{~mk>rx@%c zj>sq2l_J>HBP36c?6_Xh40}BNvZQnL0ywz`B^u5&TG^F(uGWz++wZwA1)ue!0iHR6 zPWW#UR2@C$KqPb&JtEuh;RSyTMnoP*&>M;fIvN?Xo!BgLc`|y!T^aZ8F;Bujm|wl= zsh=Z!G6lo2_|Z1Z?F%l|d}Ah#6v(KZTn{bD^oDuvCFDW@gIjs^C3PSqJnCoPuFTFl z`(;=i?$}wSBGz(5Q8MYdKdP6d(NmeY87Ch$%>GI6xmbd2GeO4QU2kkKF{7FNYG&sQ zS6tx~-M*c;W20kxNrLUp508dzjEWF&u!pDC1)tAyV2ykfoTUnTo2qSJZ&Yp5Vfidu zQ&U@G7tF6(W*08xNYwmgI{LG8*_@J8DlBiZbJ#xH?sYw!)obP0Pwld$oH}di>bLEY z4(v5mS9$|PcYj|x=m~?~b$$*GPOA^Tz&*<84$KRjm0R7`+h#dFl;Y4=J3fV;wiesk z$5qeS^H5m$IW5S+HBJMD&Hbm@wzA$zn_k<{XxH_n%WQ9D(>mMT%8s7*DIGH72w*2D zcQuE7_y|I|F5-TFJ@}$OQ&rd0bBcX`Q%|K`QQ1sul}%>^D{N2!>TP{(wxPZ4ba%E< zj*=*Cn;ZJu@e|@dYQXhj+rx&)M$SZ1w}b;)r@X((_EfH@w6kWNu|ggRjz8hy3T;_a zPgw%{n&3+u*5Za}`q^dIh<=^T^tQjJp)bX$ypqta2Cl^{5RfZL#E2Q_`4YJYr(_kF$qYXTkR0>n72NHc_(~E|to*euGzD>DQy4rA!EDzsr zp$&9w>%!rJkBNURZ6;^WI3U^I*kB`QV0(MZN#?{zrqYps`<`G*vW*QjzOHyo1}Fa}xXgwNmOz(I%sUHf7__c%$r2m3rq|}va({>_h(n8GXN+a&$X_|j zG6c9&=)8JVMn62gfZv{OVh}qPX8B=q6nxo+5ZpF!jLvqa@sIYjtxk)_b+oRGGoodT znU3JK>qI1@(bvkEw}R3My|bg<1QqdeEe}11)zqHBh&cM`oNK}lBf(efTv^y)I34Ia zJsCn-zM4cZX9H_WLs57iqIS2Z8*~tm!=m`Va))Lki(AbN8^;EjMi3ePTo;Nx+FCjp z5{;dFZwc)7;Bt>3rwkcooeoXT5$cF$LnFO){cZz|ex{JDf=wQ)=6=rRa_M@%ZR=SV z27O%tRLdgZPVtV~goiyawLQ3^xHX4w*vPbKTFF7ewho+hy$(J|+crq4W5SGTC(}p$ z0F$uUcJ<4+*#If>c>}W3D++gYwmTwdxWlom2SZc;GWaS@(<%fnY_+Nf{%nESL|;yZ zrb{B^VA@u<;9RY#sj9KfUC(oZ~|F} zGQ+aDaPFE`j#H-*t&RO0-i+Y27KcC+G8g%yNPOw&gHuz%KgFiv2vOVA)7FiML4GkL z#c=`2IwiGjGMzo`!po%-}h zouiM=k%vvpA`YV3o~~{>-^5xpuM2YNGW>&SB6T3xYf=AcX91Zk9aC_Ir5p zzTj(;?aAB;%Rzt6@=$K&&>jC}eA8>YC3ZwNcW55ocCB;rm)t1qPSIBoq8ta=IWVn0 zlCbm@At?q*%^mAJ_(S0EdN4F?WpFifska-3Y2%DBP6*HEnEWLbVBJn; zzirnjhct%(@9(hP%n~ONl{i!m(1M&Har{DWUqh;|zqcezcyaR1;2M3@L1Vv$6X=nX zCE_do>~bY~axyMEZV+f~*xqcL>f~bxohmTPEkmIwqB{CG1R*Fba0PtL#CAdrN;dTN zCa|YX4X(9FYmK#5oP3648qH;;C5(kGJC9DU#=EVV=odtvWr^*PL@6hk1GA-@xyK-_ zb$Bj)X)pN09Wu4^}V)9uVdLW?n{JEWOYx? z|NWFOu8d$3cCh>*1ejK;`)(4dk7+#^e9x=FH^u^}rVn0p>{02YHjlPy?p##h?xyAW zEYs7s+W+<(C1xsmQs10h9RE=8&7wT_GZsNj9nAAANA6d!TpY+B2@Fx$*431+vAgj|!spIy_{gJ2;V2XVlYWEo;ImcdSF#Z2N#SMg_E5{AiB zRTY(U8QCZCqPs=Jtwob6f*Wj8S3{U*);HDxSE1z`=J9MB< zcp=iuRVBq^D~y~D9#b~eI|pLJ9&(U>~hPFES)S;zL*cCdz{ry=jxpd+DY zbRm7&3MTw8?SkNcO20w&ZbKeAlnMC{Jwj!7JHb!n&* z@z0})b)sU@JFWy;Ck3t_nxbp=vJ3AMeVC3dX*x>}wZg?a>5}#o%Z@z_;+I%A2M4FE z4sID6(%O5jLji@jEJ&xjHI7(KXIt=BqjaX%#0qE^>m{HS@h6n~(X8l}8}d*~a5$#@ z!L-icRtCxMKj^MDujW)wR|nNw8``NvBf%Vi^N}jH z3J5@k%V`a5GAb}U7%a8$*2FrFMY~yu5 z&lC{)*_Z3Q&<92rO@neM#G{fNAqn#|F;;GGTwzhrU?C>3DrfCQLsRbv zzNejzGq`AaYRWQk1y&{;0%btFGvGQZrb(w;`?X^WS$K;WPd2W2r`^ zl1jJ7Gbu{u|Ky6`pG9-E%VHI!y)d`jaV24w(_%Glp*Bc~9l`Nmjb=DInJ{c_N9|J; z?ysVI5IRx|PJwW1HH&6@YE^ew5{`8qO!;7NhhVZt>r=~-`t0mHNM`mS{n#@?23!lK zWaTKxL`|{U8hQ!s_EJ*y*;S>Qn?c6kw*|hD^kk0dIer+LczSTBzwWAA`@`%c&H@Xa z;*qaupn=57NL9Wv;@_pn1XxxZv7?lZVQ)C%nP78XNi_=@80>I4Nvv;$*{4}y@=is( zHio>Nl~R?1m##=kqlEZ=PdX#`eh{w4BnM9u#MF|g%9z?L@3IoT4{Ip;jqQryTkRI5 z7+?;FSIW6%Qr0Tm?<%dF+%hE|=03HGLc2{T%b)1ck@>cw%r;WTHe(8jCjr|ox7CuM zu4uMVpQf~oh1r7PnAU?SR|WUPO|l_(G3^zI5oa7|MmTja44}r+z^!&R&8>Eddt|MR z5n!v<252E>E5HxEG=HG>Yr3oPv}7I(PJMrHFH_A|N6JawalSya+u2SKRWgs+ir5lL zgq>tY4=N}`N~(1>bfleaw}PEHZb5Ap^|kV0auq-k#AxjS1KlEQcHHcp@Y9oU});vrgsC6OMCaH3^ zMk$%tvLh#3WPGHV1oo7F2<{Uj$(#duX@RE*6AvwTzNAh08+)6t1;6 zC)Tktgk@>$ZO&$lOTud(xF{UJAVd?4r%72ev~;Y-gJU{&QK!k=*)L<6n@M3=Q_@xw z-UCnb;mI!tKa3l00wVqnOhvhdU7OC<%}7Dxc6#e=)xDw2AyFGWYeETFotA~Qw{N-h zzQ$Fyyq9H^VV`3w!=@hF(S`~f^|rBhjaY-nG!F(R?F$~T-RynE{N=WPR%O4PRmnu0 zQ%SEXu&CHR<)YXW<+6D90+5eu0+7^}_s^OWRMM|j+fIu#h^knrX^vVAbY^7u`nnpW#@z4hrG!B4DrurPU z)7z6;?c43`({J2OVbAF`G~Ua}r1DM?o~JHSoFz2F*GehE=Sr2)oa&--g+42)mrdOX zFHW8jJc!>)Y84=TpCGwwjqOZ1vZkFrQn8~_Lyg_6QKg|BFFT_awa!ja@7R(RwSa-w z4V^>Tse6=5Xg)CcW5JIw5ElByMRK5xUr%|5$DP~7a~!z9Lk zK)a`p+x}NYBvBKBqPMM`WF>1 z{h(MkFUWMaA9`l)UH;S2<35xB^8gq|Q%$h`faL_t!5$j_1(V7aD~UpLg18gEA0 zqvH?+(c$LPr$$GcPZ#5ZPsY+V!7=l;#TwZ9v_eVv`&bIzA?Pcdxn+c!3^B(KLp z@pn^0AUw^1eaO3M>7CatfPLsYum5gp2zEG@J%YyMuy+ILo!8CL<>)5jj)*F}Tggw9 z{JWCfO8!ienxbT`l2euREBSo*oUY`2C0|o=vy!K?u!pDp zh#Q;QI$KdY6s+L4f?Nm8zO11o#j;-F)J}P;6!#-XuF3>GHeeIU7vE+0@CISa-h{1T zK^g2f-8idI=20z;eDceS;K*(DaWyekIRm0PEoA&@4GapE~Kpr+ASjY=1Hes1* z=wzSa>|$+kKhbOz_R-LiR%x~_w1X*+&7zE~L=zCal1INa#HwgJ)6v%M`#pF}1Hp>` zgLG*uu{4HL8&V%|9O#^EC=Fb8uIQn>ayau);uLA%UFTqC8Mw5}IVj_;5CC+XS!PW0 zU~t+`%#q%1gRP$}9fPfn(CAnmun6b3@%1Y90P3a#_U~(8BY6dh%Mq32n(mZ01{b)P z(dp?^Q|2f-*whYL(`y-5g3?e<=~7>~fQ>OjK?u?^6wy{(LiCEAINo$M57pc7JYq_9 zFzeduYk$mTA|J~d^_wZu=>%15Re#{OmY>6`IW ziT!T!j{nE752-fO>_5lvS;_oU%GwWPpU#PMXW9$>(~7I@E%CcBueUiIlOB}V$>6P94mr6dQ#4$&fCDfena`q{@ z*i3kyqtDzOeZcd=cg!eKGxMJ zhS$equO*Hekn|In`qBmFkN(D7AV#rmD0K>!J~TEWcUexuP$rielG-qaJ$&@f%zJ(8 z%7QRlNY)|>EhegYiK|KL**0Cx`D8DoA&Tf=dILW(%%q?za0+n2VYOepxHHM6$2bp$ zrc5v=qDj!n4m>v4oRfj6Tee^!>O#Rt;1xQfka={i5Wy))937e>*0SZ8^hJ`mMS9Y- zjxr%3)x?VRCUhB^xZd!#mst0NZv2c;i+ltqj4sPzU7f9~<0CksdlG^9$vb{08NB1Y z`{|QZU7ZkET3aJ>D|_)mS0;fyFyWhK23It=nu|JYqkq!R<~G7UBMiV;;;|tvt*y07 zT<+5O3*yFH7*e=kJ}it4aA6f1X|+N>d-`OsZBfYU(%Sh@Pwgeu;D(qNkDg*?T9`l> zEv+eNWDO&Vk6BR!J?i{Y^g5uc;Cu`B@Kjr)pS6o^4bW{Z&~0b6VsK@uMkVCD1NQ5s zwsrw#M`|p!^QoA?o_MdBrMHWeKp`68X&K?NG-8`{5~HUr!n^0&kR>zQ22UKy;3sy^ z!g^}}j!&SskNc%O;TI(U7A{C&4<230I!g70-if?;i6eaNLJI+_6~3!b6=}sZ0^JtQ zkDbj41q*2g@}BVf(G0%T^a0uVbbCze!O+A#=A?ul5T1^}OGMxhD5Dd2=^|GUyKZf* z8>0D+*%ok!pn#~w#9?C17a0<|3{AY+oNVc&BXwwD41ui?S7wRR!=9sSbwgu{fND6K zHe$|B>ebq1s<)u#p!E_jY!df1IJM1`Ige^Eml4-Vj~=2r6~Noz?hMPD+~P6$b=aS1 zZ_0YWp2we9aAFtBF)^luD|E9z>0<=lzGgn`+N)3(wjXZeB3GJ|$-`65Fy$#W=aOo^ zO*z{s?4!Ts^JDi>CpIV)L&f5`pm}2Iu-_wvyn{-$kshFdtD;Fkr+!cNX)a9Z=>=Cj zS@3*A(@N*hl1ZQ9wTt88`;{TQMLrK9DXH15??B zniBVWXzF!lu8#ZEti}}IMwe-Xt)OB8X+#S=`!D3ELe3x~WF>GO@#apIU>MLwUEWdW z@arQ?vLIU5@8W`$y+JZytjNT5jcFbXPyGvn;~XiHimJtE5qn2ZL1#|@ID20iEZlYy z;1nU=3rhlPKe6jEDSIJ)%r1hyUyHROa&sI0tiDi}yZJG>jANAT&6r-AWoe*Y=d5hz zq=yuX#7vS>0C9G&%It?J8(BioE5JJns$t|vdtPQ)of}4t4q!%UTTUep`yaW_Htog{ zKq*324hq6WSoKQgBe6sRDKHH>SkaDBEhc?C;2>qX5X6cnZ_Pm61)D5|*Y7S%Uf<6`StF;a9xDJB|o zo2WDAqo2A`T+KYSc?U6413z8riPFXuhYtULM(f`&W}hs{Ug4JmWdD1p1fiiyQEjno`rH0XLQ(QE~)) zQ!0zhMJxCa#L+KAx0PPBBKcCz(f3pQqIz97y_R#y$4u1I3Z6=<*y6I`e&P_Q`U+3M z_}wD#ZJCSsP&`#UT?VGVW|juk-Hg0|S4OXAs6-o|@|CK(H9!olyFXjsxGudW`s~K( z?cAh1;R{@z%+IGv4;={RU9W=KzUOx*GvUJg?m!j~d-%Q2nPv2AoE#3WbCdY&OkU?E z9h)GnECu9kqH-Y8vrfpeh6*|ICL;e zNQd4xV)T4QK3|OcOhUTJiwa5iY?dz^sTA0yc`$tP`?xoO@#mUvGr27XR^-*khbBF% z47k65NnlnhAU$A+zt#?s9%^+COqQd(-~Z8S0=oYr+Ep?&d-Gf@#$2=|yaFYb?ZjDj~1Zn z^!yuhgzsiGG(ovA5?@B~83n|7UN`3JV@^|FP@n%rboo=3E^p-M@>3d|wn#U?lq7W7 zaPoIhR(5BmjZ@Wa2dw(0tE!>6IJv2R+H_TUP#H7y#23X!hdb@0Vw&%8W3r(<bGCwki!?%M_QPAAJW2jb{El$>z0mnZb=m?NcbUL5Th8Q&9q zOHD z)&83j;C@y-{~`X-3CsmTg}g(SMhY%FM0aa^nlN?$i1e2dGSiWN)EX} za7pwFb8J0rA1cYHF&PSHn3d5bCDZ%tZFC@*w^Q7R($(!o!?U#-vC%D=?IybDvO{l> zF3U|c6OL`5x#LRpd5<($9;c-*Po3avQyV8wq%PXde#)v~56o;e?J5+1$tMxG7u)!o zq{qJG$#5g`msS7Re^ueB(V~*cC#zX~aO&7Mv+w4Q^3E;ceX4Opv?${!?)yDhc9_vp zUULo~b~~;#a33D=B$Awgc5bZQ2*YsVHK#F22Jd4=9rHmdcb^C4kNE&sq5XcnXGd4} zI_-_(E*y78+=W(?5_t7{u<{Gc&s`bvzOEg>*Tu+tGXMG}$#KKcc3SiJ(D3o=U3~~h zn^N##O7kR4d3?mv3HsRY@vYI~lB4+Is4_PBCo&eB+1|B!s*e_D4%-s#;HS1S+Gp*(f?2Zf&wP9u^y$d2eJA;hinO!iCq_#Q z8JjYP)%d*=+bUWR=O&#kVp>O+4aePW*aGCUFMXt=zGv#_4t1G#?L2`5Pke-B0(kB* z+fMaEupOFt^5xh*_cSSUd?xn`v=6;G9+T_LDq2Buc;O-qz)uT^o{akO506Pa#nK`t z0K6jM1%<~_G9uxJfwFz32e6I{oOF@EAaYm~`?!;7Vm3|qI9$W^08*ZC7*pW#pMp2C z19AKo6Y_)+nmXZ5C0mp{q-2|t?Mi-0GW`gFcKseYx!UyV)u{kW&~!`suFMJR+;Yv- zK4GIiZKm&;@pPqHC)uLpAtl?CY*+G2lIeUnOYPlaP8i7>h`^LHwyq;F?170dn?64n z*oS18Azw*k%=B*m6q=a|7CXrhb$PPx32fU-QuYQ(#W^IEdN=<*k_DQKb=yhaM@H#+ z7m%EPv=S~PEd3avX{8^NKYeWTU|@QmA$+a$>&~!ZM8@FAlG(4AIYsWR#zo9= zBph1)GaDsXJx4n@t1};!y?x!bl6ts&S8l>o1b-bM$T+;10z#AJl`p_gxX|Jr~irJzYiD$VZjR%!`j4=9g=aQn^ za_)FtxYL3sz9U?XW1+nvcQ*T0bGi=$!1v!tupLerF2!lVi-D(}gVgxm9T}?f?!m{t z+R+gS0tasJcEk~YiED-`L_*^IY$s-KfAV3Q49Bt_3?8%4yq`Eb-Qh0J2rd$N1aN3@ z@XLiG;v{Eea1|t>4B4Z@IuYVRFWvE7ogr=k(+&}>rvsaAGL(2tdT>CvgR%OYQ8Et( zr~R|}07h_`{L_4w$REC%=f_1xaCa&lEEoqzf}$e0p?f&YUa5l!y_K9>?E<1sExU|R zH={McB0ey3o>Ps^iC6`=)03xu%>0F|&3394$2HD~+T588Che2UQZZ0M(%W?>RIidU=Hd&a#&iS%%XN*Rs(+o9qhO(rTcHpfvC-d--^ zPx`B3!d4MclK5eJ=h5i~xg6W(>5FB_3@I9mgH>U0nS<`Ath)y>%#O)%=C6}z;nNYq zT{wO58e5``h>h^~k#P*tx+_q)x=SIcIIM8YG6?imL9ZU4{ApfraI%PL#15|CgH!jJ zGZRkV55WYfNH=tGaub&GSJTBuE~9i4PcFVKwX7;;Q)0B;6r)N4duZBu<}6<0 zwxmy(Uqn9{tW0b&4YoOE6j(`7q@>*%IPqQ{_LC4?%8?lG5g-)-Tyit zw&ly&+)B$%-2XgmZ^6$}?Q_XpVoHwyjl-y$dA!Y`!BcK$5I3M9ar`h)(`lsdxYiw< zqJ|H9rVvhP^7EDc=-P4YArp!;z8yu9{$*hgRo-qstlmDE>uq2T^;VpMzKEItqC-V} zQAS`6i>u5byBMveBDCUu4_4QjkL)*S35r5$XAUWv^+T{9kq?Aewi~{lCt5=D!SILX zZ<3+$H1|Z#^+dx=PaNNg%2M%%7^a!KVNwoGSB7bhl2=M4BIT?o*R2+0C_;jah&4me zhHY8cvj)vM*<+>LvcyU%@vSEPQBzbhHAzjHl!jCpaz7ZwLXS@VG??GWJ2;j--kIXM zR@pYNpB4@ku*WnHHq72&K1$u#0*|gW*fJur?XW3J}-?Kk$hP+`#?;JtEcR@q4JD&54{Vh<3Uq!CBK;=AL zGEE(RyUQS{2^l?Xi=~k%IsCG?^D@VLeMBc_eZOliH^Z`|Tqg6!kn9~JGDuDkjw!at zCx4IJGORGl-DOUGSVgjyEPj&vywBZ~LGDrRAZ!Q{Vu7PP?30c&8}!vzQxBqKx!LA; zY(Zl&{x=m)R!LsQ@__svx#^G{tb9HW$Fe^dI(d~j7Z@I!CT_1j{$e*`c@&DxLS@dF zolk2Cevh1HBJ+{o$jxi9b@7y42sB|Gh7)4rW;`YXC%?y>7qA+{74pau&kVYKcK$R! zV9TSLO_5rv}gRdODnhNM+VdS&G)T+&*%3KL6buY)}_?I`nixzgQsP2Fl@{&eL; z@5(x^%Py-#F|I4an!`=w`xQ*ew4uKHwinpS?$$cHva-9^)}2-vH`u*qE*ZVNBVkeS zu%~vJ3wg1!j*HRDDzO{^uoF0`vdU915P>)so7B~SN;f(O6)S~3S7mgsspGDT?lpGq z0_A2A?X4?ov`yVyFp+JBtF`LpQ-;R46~2z^9USbzseR^?IgIkK;1nPD^kI=$S-z0# zGib?nflv%OhizXzwgR)tp*Q~kZPm`vB-D5hPwg;&@A{b3g6R3R+L}a>N~~N_`2z0G zaK|wrP&~fSfWw6x=72t}7W(vB=tI&<0xgQme4i?U6_5l?WQfb1gd`? zeB?=dnib!XPctMwqT(JGA*I-@Fs94wpO_3@(~7UM09U*joYEbf+l6LaadsALqnjZF z((!I#=Fn|&Yah>bgN52j-&p8Zo)jaqq#=(6Dx%o9&+d($&eYzl=o4bmGN0Xt+A#kL@ST69Z^daF zyE2u-@`U425wN_MwD335L7-( zk49>U-lE}G_0wfI4e2VmLY=a(J420xLeiwF4pF%?h4KYL`4{?mwtnJL+Bp53EbO6* z7tF=NNeWlhN5`N@R;^3?a#gF;){qCHR((5rOx1;29rcwOS}Z8?0as*<`-7pmd(0(~ znuC1#3znM($y`8V0rNi|6mzc}RQ=H_!=Qx%?FJ48imuT<|4Jor^UioohAMwmk>93^+_$#>{&@JpDa5oX%^g_ue#jr6TRflXk~`MCKkP3}LTq+;c( zmyCH%!>@kbQ+-#4C+9lVQ{2&TiC1*k9iw#L78;^a6gUU3E`V!CJA|QOlC#oE z7Y+zEmh0IO@OtMM!4f>YKUfDU=7$Zl|Cjk9%S95Gq27L$EL<3*kr5f5k#Os%i7l-EFXTC(C+6%UB0%>m*FH!KvM-;-^x)c96#Wa#yHw%ZTD8Y{7nq!udLYvpD)-8pEK@ z&m>B7l@Nv3vqC`uRuj61ie{K#= zooFu4Y16o-PWP&CZJze&b{L5Y8f*M&FNIcL!slmDNpTUDSD?x^mD$QQJ*c-?wK@Tu zE0^f#8{S)EuCQ~YdxK5A#hjue8|umth6^y}-yHvPuj0gcqr`qmFa+_|1_qjccfvqR z(U(f+-!88AvKr=Ojv^4wbQ+ECcjcAlt8n1_KPq7R7>0HJTY9P|3<7Wd0B6f@nTa^+ofKYIs$|+uH^E zC2IZbj|tZjFX0rfm=hPQN;r`k6n3Vo=aWUM?oqr6U%ZKVwKR@px=NGl%8`B-o%N!0 zRq>Gt$FxtLv&Z}sw93ZCEkldRZndMg4{7_)ODUd{Y|E(4jdTS~EIp5RMb-<^Wy9PX z%$1bP*)E`#j1>u z&bEE+!P_1c$5>$~Xy@gkb{G`b?}|gs*9!10?zboyBfaR04r!qpYYO=wmVdAaL_xEX z#Jq^f>0l34ebUGz;)ck{-(~Uo?%qi|OUSTX=p*Wp*ejTDi%uC8RCZrx>H#H2$Zy*( z;&H!+Do!(3yZi*iDRT-zd}<6Jvdoc#v#j;NJUhmDu%Tj#x#l3m^WBQaWN~gxVs#;Z zOinpx)Ls;tGz-S0`T--B%Z|yi<~)vf8goLhqA^)4g>^qQQ^OvV2Kx;MBb`9`-Ecf6 z!{z^Eu1i`k8ji&b$H7`3Z6w+bJQ8`-_48o3>N#`0aLwn^1Vhi8v7S^w-hU~^YE;VR zx3lcDJghwIp^9^iBCp;qVt152hReK~l~C3u-}cPL)de^Qwd{W!D=8qa`|e z;kXuxmStUqR_!s-g(isVWbIWLxLa|F6c3DB52oH^ZWNJadR=gy?T)YpE^1iR;1g$| zT%+?lo8# z*T|^JD=fsa$R@g350K+Ih|QL7zqqQ6P3U^E4^t`6KD@@(VVkvBd}UzkJ3a26?`_gE zr!qRDbYigVZcIU?k_0b(zaooQJO`)jGB~OD$@sEa|q4l}4mn+3t3IfXLZJf6!cN&SS!e!dP*WLji8Ae0#se4+&l(L6p_9$4DxE%_B|=YJ znsRHvg@`kTQ5XNAw4ahH9yn)i?roLU?}*o)jLA*ryD1QcW{#Q(%W&WTnp$RrOYkYQ zMO=qRwm0_E+q4*TZi+5vN4>q7%Vr9>kyo&3F*j-s4o^Mb+%l$NPiP5_a&G_?RG6~1 zESa&vqDtK}3E}sfj`>u9iG9BZxtHNq&0bmI^T-lY!HI+Bnr1!&sYKI&37_q}r$xI0 z9&mc(ZHBT`5hD~&?_>@RO>H)t;$0h4$jwqWw8`9Q=klffsMu3X#e-9>fY(5O%=2J@ zxlLS%K#S#DmO?RUA;cQFSisQxYTT#$$|~200SThxj&bL~$c{u$UTK=`L2Tx>kD^#S z4+f|F#N6(9YBcH<$=^Iy1RES(NJ7gTaX1P2#tI~Z!^vlij#Dxw15?j5-&1!+Mex6Y zlw=QEWp&+)!WfI(zzTG{7F}WfIbSY%nVy@=&?w(s#-b6=LDnVp)Gb4!43npUlM`Gz z(zmM8ixEPjD;s0j!&7fGces8ttZroTu^rp0fUji~;4zQ1*siXq(#Ar{jYmtD@AvSD zzcY6dIO^FYSy{B6AkGq5=qgsWbaka7M2j)F&Hq#`bWw|z7lZo!P$LHRb`FXjHryRnD|9vO%?&XgX#xgEK6@1?e zer6S-+L}gwVqG{ud%LpyFi>^3`Ti)aW7>{eKU=MT(6yfEFr2(7jy$X-^3XvvV10=^_*a z-9d4BZZZ$b+Rfb#o&69{s8dl$l?&H8XsDBv>e|}ehTqYkG!6xWI|^XW{HW2Hh!s~C z!-jh-Wc;^F$UW>CT%usUL$OvQr9N^j-=vXGfjHL6MT8~e^uBYXDBv!3OOc=dGZ&kC z<+1cjm*lG!6)l-OI3GTD1IN>%Cx4Znlv(kl>jk)BC(0SkVrS=ySNyx!qf&neW~2Dz z=@{38;gc^mKhWJ2{*>zUi8Sc8Y73U2R=3=)mdS^<0WQ>Nt{` z5^d)vJ2o)X@z(4-7%cmMx!>x31A#3GHjDt={q~Kj6-dE!PH3w;ES*=WZ922F{)Oac z%R`Xot!=t%!h$4QLua9JaCe!8PdbFSMyBNs0r&lW#{3Z5Wy6%Djkc$0vLPMaRN8Wf zGISW&!+OSNe4FaZsLN*j+GS*az7UVwg2dY#qup?pE0XQ^h8fqH2SmJf)&FQxzcoBy zC+wz>o!_k)25856o)`z67jC)GZfa$(zoAux6K(D1_^s?uM4!=EeNO!H8Nv>NdG)T} z!xjH&wrGqQj!$6YZTYmjjfKl+S~dprwgls!461hrAKMtr=9Ho$sTvQ#z}oWZ=*>*S zPlUmR$z?Tq;vN^*hObaq`puwveNeqc&@UL|p!(?}+X;EVEZ0bNF?7bop2JWbA47==i<{>ga`v#I>?}y@xMlRP? zM87pOKs7GLxXAk;&&q4h%j5A_B;3E8l{QTu28W#CIhN9iwI}Y?e|oR3>-XFbnun>9 zUCEGlp4>6TAj7vyOD8euqODniqb6YU$a{DH-}I(b%3EQc$gm3VuEq;{2If0z^6uy#GOSJow;;1hmh2P9xRv^DJrR^58BA}hMAjQ}+?(z9;H>YNCt%O?Mqv9T z2RDJHg^p?KoeXH4phcLm3aGQX*r=F3#2~fY2P-tcqAs{AvmB*-47ey&nawB_aLvKN z6VEc+>GuR(8tv(MORkhMs)nI>`>7R2dAa6) zEBF84lbZ9q$bGgy9kt`fmL_cqXbmH;jycj=vv;s(_Y@%DBX{GV(yWaZhy}2kK_j+0 zVTyL%dv~U{oI6+NR04ZU^I&+&KbxN`$~b41REL_%*u@n0+Sw&#%UGRkbqXn?Pt9fH z3)E5HDa_u*jm7Kal-JBJpk`jXd^7m;{kyq8evz{VaZ<3rIOtG&yC&j!F!j6UDaGlI z+J@}HFhY?H*o`?xDL=fd(y%^@&{}tvRE(8_BGB zv|^#yrP+mhJ8N$|I@BpBvnE=bD-+wTo&AM^J*gg|xZ~n-J-B%=Jbkixnscwt46MQG z>5;XWOH0)djt*67x5S^HLKM2oYsVmeN~*oH$Cb!ucUVv%>60>TdyzM8bxEQfc4s;X zKP>HkKH{d1-*}o2)Gjl+K7)HYuDcY2%h$(|BzxYG$lZ&H*0hinzHb|A(VH$dLi^7V zZC3l=P{O9b^zS8Ejl0V9?`C=6XvR%9v#Z~oIqj3WALTc`?xy;85LYoc_fO_u?c;27 zSW~&e(%me$%ba$pt{eFcI@rjBVAhYM063u6l&;2`W(dyRF)CgoAXhpvi|sn)uGOVR z@wR(mBTuN9@@6ISVff@b&Hu7Qg_I;z?07^p2O%P&&3ipc)gjcWFDyJ#QUfMzvYFS#L}I+fpav zb&O5da(Ye0U8MBa`dKfMJJ`cBzh?-q*42f&tSMVoi|*vVabC5`rN8*8a zOUk56Jm&i&4N`PC4wb!0z22Q^uX4Tfum{V3Z+=zSQR;kir2jP(z18Pqq7vb3I2OHVXm+J}4!ZQ+ zl-HDNMF{DgQ~sp*PS7VtXns-2gul&^Nxb!<@50sU%jNx*dy9 zYLQ{26qs$ff0ql%hz<|Vl?e!*7%CZVsLr*+HW+prT37JWjnlt?C8%R3*{jd=H0LhO=Yv^ysCBY0Q}**R{M1J`>3GAg zOy^bDhDbIkgIm)a?lXVKSa*I$FL&?Sv{~H<9@t>x*FBwZBH-)?)Z02X*eICpvfw?ix_-SI->${yX?zX?}7Obm={MaN+m4SrG0k@!tK#LnUPZ8ko(CJEUqHMJvnw0%DjU)pYnpV z=Om9Yw@05z*L#;l5@-VL`aN*sO-A;ww-s-$;Z3bf;l~g0Qs*TZXSh=P5OWxexr&R8 zb&WGmGxTKjRHdg9JuT8xN>2@0*hAqF=4HK?4{BA1o(|R18G2Ivo{f4c)w_@CX`G(U z*VEy8;=0X4{vX=D1-z=_+JEnTb|lC{G!Q{S4+0V(;f*{LOOkzJ0(p^~fOxO>VsE`y z|JA(IR&TZ4+(HdSDi0A*kf4Cj^7Q?pf})}X1?8!rP(eWhL==oQl>hIyX7)bk1VT^w zJ|o|8_Po}bHEY(aS+i!wXu;4VhFUT-l@bO$W$CWZp@64MWL z_Cvg0S*4Ei`=qjGopD6PLjzb!&Im&?a~cB$8&LqdK=hCRgGYF9Rbt7P824j-!8v;x zrRQBYS}pdGHai<}Ci#)$zw*kT8Al26pG>u9Vu5ibhs2|L2e=94w;4tE`y=3%v*{CR z{CCMSj&X92Xco94w`$DKiBClNh-em)D$12kMLyVU08Md#(#Hmwmo!jE(1a9vYo#u{ zk3<)_*JG1W$Egk-=N9+Fj3t)i5`$CIAsq7h76dU)e`BwxhWfW1Qq}5`WOeC+Ba21P zV<+hw-m!^{FR+}1xEE!wLT;p%*f0>5KpKxgxg_a;<3=%djDqp#MHM|}8Q<{!`73BN zyuvx@7VQRMi#wwu6`zX<<&t|C$xSv)63Yn_@`Cp3BF?Wsu--ie_0TObthCiES7U_t zc|(PqGKYf{iu9MxlB$x=^*9*3!8lHm%vUK8oS#R1LiLaSoUiGpGmCJJl*Q^xsH;<- zPAu84s)`gN$NJ--yz@lkTe7aJS@**6L|ddF1!xp2>t^gR#*Bb)9y8v-@&KaN7;_u4 z%jwK9w^-_2DlUY!tjt2xWbb5~Q%CmeV~4LBUgDW4BA$uLETm5XB) ziZ&~aAMCe(^Y(8V)szHIZxkh;N$%a{QSpVD!%Ik};dECMdW)5@5EtvwQL!(Yg9AJx z?f!knU5_kuM+^_o&~mZeCgblQP-qnFXmskzM3^W1Gw7vSXlJG&I|!X&gV3pgkpogq z9D)Z#yCAi2oIQL1@}RPaJE=Ab6~X#MFmO!siLc_s?^0-9o;=R@k(H(C{>`|K)ebX`npKxQ6zU70HjVYMRXDWt?_kF1Zf;+>I;TE`ZF zxQK{%K1hDjI3+$F0b0;Jt6Y&dRicYvJ*2OuvL$;%CAWaCA*r}pK|4tm5onw!W&uaV z4;9IOH~wK2MU6qAa6YYOr<_rbHen_>}AGjWf#?L$jz_|ed_(o6v@Do zoFIwc6|kkkSu=1`>M&E>!W3Z@?8;=Ul5w%;xoMo!xJI_nb2vs>VfoQuoNW4q$|VGz zPb_SlXXzj%dy*HLX1raM9!n2gtN|-84(<)Zm7}?UFNWd>d=6>w3k3oOq`GSZ#PwxQ zd2)NxqP-ZGB|52N^^hs1&oV~+NIMlGJi<{Jr?5UlB*+GW6rordc~%aQ{*9guP)wxL zs5r+#dAkK>KsF4p7l4~2(Q*t*Ob6T>8QG8X0c26^AT7*J z)ssHT@Dp}Yd3}gCd+B+yBKdNdR^);bZxSn}8#aWKPeetwoCw*ng>3!%aMB9Pqy;1~ zL)j&9V&IK~W@bXvRQk^m5c9kz@8ZNF({>6Ww!kmsnx44wp7UT?atHGQk1kO=4U}(S zFZ93MNL(Yc6qzKW@02- zwoGF3iejVt7v}(?`xlchoTwYkSD-8pAP^5bb)d`-pdZ)~!=ePAn2*r#U_9%C^5mUn zbA3gQN1Oo25|Q=TmqObV7jWOF5y9D8(Fg*CT+s(WU*Lis#Sq~YGnfZ)ua9uJ?vwI% ztIP}8?Xp!A)u<-=UeQ`Mz8vmioe}c)#k^$HEhl0|+WjzAfKPuigz!VVE@lgV?m@29 zk%Ri!i@2Dm%P!wTbu2l{eS^4tA}*@}M4=+Gkc)1W?ic&Ax+0f!cx zx(9+xXmPqHj(C3(M@eMY7Ux`g4HS+WXb%-da9}F#X+jx2xgF<LC%@5_t)6I+7Y3E+a$mVnr5B@|gVz|UXIS8(i z_CQRSnCJvObSRfj7{!BPv66XE&V zdUElExA-ZG=v5()RpH{`1u41MtKRtk)=WZe+_5GHW?To^6gPRjhWty&=lcEKZi?Af z9oA~1IWe70ULEDNdt$DF5`A#$0s|oXJMrtk&Iw`4NI5yC;KQD!l zGj3Xi#{>W}WKe0O zu)KlLhmu6=D&B0&19}mnYN1LcmFA0#>xbhlY3kTfD!hk}-|pnw%nqQ0AP3ox(~TKK zPLD5iE#*2oFbb2NP*g>V!v)FLkmUTS*IyaYZ4nnO>I??ou z1CfQ7Izk9b43DJ($EZ<71TwfR^_KA%bl@#vU#*z4Z>hz?V@AU+O-?X7sfJ?sAqgy} zhK1a+=)iI7>-jz5Njcvl=aSaMz4y{BN}!^yTj%cylgU76)$db zaRhQJL4q|UT1GjJn!1fnIn31N5n zNkBANX$q5DsQLX(xo&?TkGY(Ggt z4D23135X^uje*^>$!tGKLJaI)KM9B?D~*Aj+GMt$B!RHw9tUYZ2?|YC8bg=fO=kN^ z5@KNY`AI-DS!oRHzD;KPNfKgU_xnjeG+Ai`w)HVK1mWorttrT6C!*T2d;)#~gJWw- z;-`1tpDG*RXQ02AFEEfHb>W{MH;7pf9q%~ka<4f+ibU#ij5eF@cG8WiDksC3e4UeN zOs;brW9l9!%UGD=WE)TIa&nAC6P;XR@k>sgu`JigH&*p^ii}lroMPko`<<}y%0_1_ z4tzQ{85{1#qmDRt_5^SFt#hm93UXq*Oqpa3ghvKnsz|Jv%`>HNNO&(HFB2YAlP^Zd zDP*W0;|ds}M;G2NK5A5LN9cy(aEIFT055qiM>REbg$U|%u+hCvoo$o5e3vA4C5>8-)E%2p>Og<@Hk+c z;l+tly>dll7PjBsl#rwEPATnwp?M8ZpNvDg?quAOkeJY%zC;dQz@B_Nd@0}&iiAx# zg$8dL0W#C<^avZf7%p}?4iy%V0FyscwY*}eV&WVnRV`*!UrJRz%`2~NW)5b>@cAZc zF%|2$9d3e+*K-pR@h)qpEp*Dik}h_0=-_e5I_HSHX|Xkw&Kk~ix_KM{TFUnWC}oA< z=K%}}K|6%7^-32_O)-Z69o$S=Yy1)C59oa+RN@%|xCl*2p{L43R1+c#{BZ?BnRy6J zX@yWeSwKQ#__p;!%@J2DsmxcL#niVD%9BtULwWI!gWfI8p{yYf<;F;@n;DY2@HD$( z#fLf|RKT~X9||Ee{fCfRe5YR^x>&phyp{W!J@FueKBF1v^MJlLh( z{$gH-QHetHSZFQ_&1Yx<3)SmFE21iYOtN_SSmg?MEU8DEyV6aH=LasCM`yVaU@hen zhC6kQDU0!W1g}QoPuiU})f}$y$9YS*3{^e&qdp5=Rdo^aUIyoNwhpPh)OHF_yFPe` z%{CYZ?`UJnVaC<^aUe=;EjUbLSa4H9?ssr#!-HMg>l^cWx#wH;x96$c#-4-5t2kUD z*%B-Ph%zGNiIqC{q2c`WJ@X$LuDrx|R6Y20Usxx@=kc?UwJ=42jkgCEA6w; z{29yPWcZ{je@(ufYCj?ErMMuf3L|~V`AY4y|CpaeI7YD4muNgRA0xf$28Ey;Q~_Oh zTQg4YFduP~J}K?}OLK%ebx`X*v^NIMLtF6#J$e^+ro+?QcnCvs0zX-a)G6F57rnyS zlWu<};CZ+XY=ldf>+mym7dors!#t~S6L4;7 z`h+1|$}FKt_7WXO-_EHan|C-f%OqyeA;6&%@l;5MN#Zc9LUboqp;kWZvd)Xm42adK zlfWrtmU{OvufKqkuYYj}o+$@Aw?b@Txz44==b2eMb_cz2;VttE(bcpV=@(v`OW@ud zoJri@BH`hki;(K6C44X$6xgahajr;pp{h-$^q5&2&rcsUrcK7YTyAZfuDY>Zv>8a{vLhBUfY6pT0_uR)=2^d(Jfz?0o=}u*rF4zrA0>s&%KOS*cXGJc!e-i>@^m;LKJL@*1L(NML1pJkbCeJE?lZvh>TgT);z?r~v}G_CM9-f6e%40kuNd#2 z#S$4NvSg<_BNgSK8$$k82|rX^z0J&xnFVHa1Mz00Ql#=U$Fv_9;#rUBP`z-?1x3R> zR%_8sWeQpVQD-lpV5@guf?zXdAjGqzQF$ImvdxTYs@8K+uo92*!r#2D@?U?)m@&`0 zD`omTZ<3mRpQ?x{0jm#3u}Z3Qr-yji4v<^rB0p~TXe-67G)6LLS-mAcVA%HdY9*4T z-IZ7T#>}^O1dRX@u#_^9he$ zPQO_b0@#dJJ&fun+Rzvb-i#KJdllVIn1#rJ6I=@t+f0EJn$a1b-~L)=Ao5KL22j#= zC5^5z{=xg8W_IM6ge~fXpf}gfxP@;qUNoN9WOa0y(;7x%`}u!BXvQ3{+RTn|j)Ti4 znWNe8$gLN029w7<8jE_f%{H7znR%u2RMm{f!ICp>RSm$H6AOSP4T$=Q5=UrYn>DyG z_~bOG=`*`ZpOkm~+ALx#>xq953_P~6xagg?hJJy%A0{J^@H+@UpI?m(T}!bcug|2$6t(#O=OQ}2p!(Aa~65@ zfO|n|_sMg}VQ$`-i%S$W?9$|kW;m)4HoK87E~CC9H=I!DFUj3UxQImjXBu6~D-RUo zNWD{%o(n&sYfZ;Ss2{!Jof11e7hCc;Mn4lQsbN>9JZF|DUX-=KN}4cs7>{n$amH+3 zy&^~MXWok*F}5J#qcrF2w=u7BXRp?0SdSaC?~@ro^oHn2>Ya+_T^=&W$QV=uZ!uRx zb?zfW?Zrw1eI#Vhfud>86TQ=TB+q^f3aLGhsrq;%5AvBtOQiy=e&Xqp0TT(zaG@V!I zP!{mK+^h#wZX9$m`1aa2jO$=s)y0y7th0LH|0Dv?>S3>3hfI*SIOwX+t3Gl{`lKvv zuQ?853ny-n0@{1k@!<2LxLK~MV>1Y>N2j9$aA2NDvyJ8K#sjuq7CbtEs|hX;9$8_} zWk@ek+r9}|J?kFTd9}tP>c~D=QDB$$nq}U^X;B|^t#fBBRIDH&y%>3P0_#}T2v!W3 zc32M>vv`{r%vu`bj_nYKAL1E-LC~t*sZ-5=1M|(ovsOx;BjiD>V0C!d3%tm-S4itX z9Fo&(*`3JqD6c^PNco8cgsL9}UxR&F!%(T(gI#&`ar569&6ag+=fhE-jWA|KxBC^{ z?&HYJz|6yO0(!;Q{UB^F|6bJ{6&s9aeNfir4fEzmd1rz2zwzkiv!J!sM{6y|ZNPp) zn#(550TXcCf`0sD%Z1787u_pt;Xxj@el#TP=Fz1h<#*K3uTtsk*xcU9DOy&=-pvMbu~)Tq*EI4pk^{tlA|Dsyf$G`*eTXxcXkP5`y!oG~ zcDA}gLoFKX+}XnIysB;Hvyy7d+bl@9-5=_&s02@HE?1NShI1KG_ccT~5dArOmhc># zt;RviOmjT3S}2mwqucCdBKd@>>|H7emp>3Sy|VmyezK^7jeXNw&a;y9EEWU%=jU0; zc@`t=xW)nZlmF{Hft+Wt7`pu8JS#cRVll99JO3t%b z4D8#^vy$^HM%ZzWgWJy&$axlvq09d}&q~g-SPbl6o@XWJSu6(j9p_oec@~R-edl>r za-PL}*yR_OnWgbog1bcKjmO52EMI2h9%TfSoDt>)W-?cQ3kFe%qTdhLK* zd>v0)d4&TA;3z^dk898mQo$~3e}!2Q$s|=+!Jr_Jjni$T&W?bbfKw+KxEM`x=Wmnt zD%%kD&18pk-UO?+L#297;{0vUqUWbO^APgdU3vM}W+n8c1=FGB;ZAQZfvnVOYiPN; zU^z{cyNwrUEy$V3U0b|Y9k%-PrP>FbsinRgNh^YzCWXgAqkQ5Prg>&!KP|TqOQ0o*^a9k@t zB%`{}>Qk)_I#i1Dx?6o?T=PLi=iTN#vPZ?@U9I2A9ZqQXjm{LK`sc&| z_9M4?zN$Tqa4|%x3mLgYlB4W5Y@^obPmWm7Lo&)6j9ldMG4TZ@4E?9pRj*1je}!uj z7L20@L~ncNQmkjY%*0JkxT#}7IwNg~1nd~XJnBq0s4HliZUyMd*O|zx=^n5c08w={Ji|W`|oq~s! zwR6UT?Z|j`e+<6&hkr=d{up*kK#WKR%@0;L^WI2gqfnAt9k*y{RJ7^Olp-yA%37>8 z?_<6mcHiPqrX4OQ3c}iyS7=`w%p3>D<9xgwQZ%fm-Lq%Upq(AUQQct-A#d0&K!VlN zMhlyUL<%=bWfbKeb@2afl=c&U5_DYSpuB5KQ(f60T`0mvthgNo!x-0~g+tN7yHCJj zBFyc+r(mv1C@6xgc~YC05xJ22(ncGGPT22GGTKTUR+gJ^ACns}oCV6FEVj$Oj(I<> zLc!f5-p0a2d;3yDE)A=~w%SvV@Dq0{@@h6bLI-;?E)Dl?z^Y2L)cqp3PmQ;i=x2Ma z3<^!;gu4xXzU0q-{v5>O^{Gd^KDoN3`2a2KZRiGJsteWX+=YAXIsB|O7VcLG+S0x7 z8?l9R1ZZ)(IvQLB`%6b==zeP=I&|&O| zK}P#uJvqp!H#S~JXn2~1K3SxgPasVeL3|N0t#hBeS)ozyKDis-PVgLB<(}Tf@e5P5 zJd~c;@IM~x@;)z`zXP%Gmh2Aq$!!p=8?WOmguB+)H7unbLWiWow;&Z+yi^dLsq+)@ zq+_l7VT@>(S1aX4w!Vg10>cQ{W%a)b44Kxwg z3H!Z(aRnp0dRN{(mB3G+%Qh~D7ZWG1qtKXE8JLbPDC5S$U2kA+B@=AN6Y%kkgR&k) zrda=I$$e@N>O1`mI`*ld4E@Omek(|VSLMaI0{Kdq3O5_$DcT-Sw_fHOE2OmDij9N3fHawg*@GJ;jM#%XF$qpoWmh;~Cg~ z=_l0DeZ(bF; zIL2=P+Qd;~Q3zZ6IRzN&@aK~qjCy0y0Kmq6V8kF*=PqjJJXM7RJ!LGC{h_)>VH9Ah$^)u~diUdd9BjrkID?Io4{5rj{Fhlp z?WZfqZ~-nd7BZZP3i0q!d4dqYUxa}7i2My}2;aOS^wHCF|0|+EmQW!*UY0`fO2}p0 zQvYqX9)B>IGnalaOP@zb=D4MF8O)^{;j&H$6-$}J2o-QtEFFqaj)PILWVDqgPy8U* z!Fiq&614nU3TAYjfvIT;8M@A0(vP3*Ib8+4F<5!^v*sV|9qWX;hi|clj-c#1;Vv0O z*{{aB&{TQg`c>V^SI(i=`FcXoP{B)p8n|ghnpe>`dd_iW;AfZOU5J6!N2BFZS@6M0~LzZlxVyLym$a ztY67{5`4hL>hhExgQZu0X+ETzx;v_=?Jvw(q5&NuB$2 zjx8H+wFof*x9xH^f0_z|#L1o1y@i(O{2X3c4X%lE9F+G;FsEWU{PaZZv*YJg{?r;z z=i#%eBi-CO^QW&yjP8TVV~`GTkx0Dk!fUP(nJQf_gjZc187W%gJUvU(r6T2B^G{&s z80mwac$%J8U}X`)5ESsN^JPC!!@d!DOmqfG9c(~ayvhk4V~QRY@8xK*GLUp%D#pl+vK34dS%4S=tG3&aDyn3IJb% zhWC_l%pd=MFyRZznT_IDb32-n5^1PzfF{{ezIx-4$zQfGdt}+N6c3aig}ju&A7skqiy)qn^2AwNVF zbqvr}!-day!$L$%PGItF#0l&9pGcr^zQA!cz0%~50dZi-%ts!iB6p49bzgqA@? zaLvc*x0ita`AY>8e#?aYNWiHLCRml}B%GJ*GWiETImxQb@RB{)-F`G@p{A=IL)Jg{ zU_)dFtUd4<)7IWOLNJFahz&z1v99$F;k1vc2!(?OSU3lTnGy8xAp#*EA~POh#s@su zSGO=9Z5kprrdbihI3OnKismF>!dE_z-uO#DhF(Ev8N7cdUHKtGf5uRlbmc~-HfQK{ zK=?~HzummUcG>PmZ3AeTi%Pq_Z_ZJqtu_99xKS=I0kD7seXRt(F&+@$1C6)@zeF2u zkaEvkxj#=7X5>~oXl9~m@{kyaGLWF-(u>Nw-eb;nwz*YZ{kE7~Uere@I$yqt!$f;N zL6J4I|CtXJRp9b(c!vdaWfOqTyDrwr9*4CgcJlNR=X~nP6}>()A5(j%XclL;zihU8 zZ(*N+%$wORA;(sN#Y^1A-|-|LmqL{jtV%3}3X#(rYb)yo1N_XWCK?vez;)Xip^j(+ zW-`vR3U+0Wz8G6@bA@jsR_5MAQgD9fx;?TK=j=8F3Tf4Kk%c;@&#!Kixx`e8!rv zpNX&A@^>Lmy~RIrsa31!We{3mz8%JL9LB+mc?@ksyPHv4_7-Pe_qGusXv3)yeg^mf ztyv6G51gcEUVc?i^9lCu3f4oJ1zYUOb*N0OwyJ16R@k?(SB)^>L!bEI_u@N5b)$uK zS0YOz5=SP84>>~toC@gs&`#Sdjy9XFrU z50v7%Y7sEn0S9CRnVWYDzHQ*?VdrB+UDIShxX?{`m zlr|5UPn|6TxKW+nc^w?O@`$JiXUq4m#}Tv||2>{F7e&e|1BKT7R;2?0PxJE*Cd#60 z6>KlGzqC;;IKwnO0ik90wIxA1roay$R2-f(yp91o2(EP2(L8 z_ce`iM{>h>ppDUS)L1Py*K_SEAz8bw#vTpUp}J2}hL}r`yk;CDxnO-J4Ix>auHgv{ zS-L*c4IwdDJUbMj5Es7Bvg*(nhIpo940Wn!*CHf~;b#dXll48+qsOO) zo%*i%G~=NhB^2=--g7w!<*}ychEq@D*}vzZ86@1uxaYeuA5ZB$w+x{y$u}P?Bj-Xd z*au2zGpIA4I+02u)nc^PSj|-`ROj9z zK8~wztcV+#O|&g@O%F$}VHnC5+X+JT#sv#yN#nJXa z=`H=&nU${28%6SuZ4ZSZ4yk1s#NnL8~B0=UFqH_u5R=6;B@7U+twWMSB z!MIiLKGQtX4~Vl zxSAhI2M;n=Mle;2O>f!n!l3r-Kz1ZA(}#@H-Tchfs6hieqP8CD_CL#~RK&QCkk9-e z`ZM1Mwt%e1|J9q!RfsynJ{Tc9thfGwCw~F^EY<+go0(=SY#sOo`^n|l zGw_Vils!-x@F(`-UiX-*m0Z`>hG$CzJ0BlyTokLLtl>em5lGcanBr_PZ&UvZU@~Bz z>r9dP;91&!|F!v`vg;0WO{4CNnGdiJ5@26oRYC&?U=BGeVj8E%nNw$qLhMKcF#)FN z(tV@(3=*^*JqD}*^XUnGmUH&cHL}u>YtLzgCn~qa;H&$jEOmw{4;1OS?YVKtrRQbL zcU$j|(3s`X6zVHBJZudgnF&aU*JK1drg{8OI%uc)Tm&g7kvQ0nO^_7ol)W$n0yrj5 zn@2L};%t4&D zI1tQzEJX^F;>-e6b*DYg)6p^x`nED(K+-vBrX~n3$dJ>Mg~AQ8)uFrVd7cH6EnTA+ zBkTFaFc;$q2V5C238aJ3vetNh4d(4as2;(1=7aKH_nI%Vru7g4RjGQ!!91!hp~L|7 z8QILUozPk;XaKaIfFyy3{HmglW^)OH=}s5s5z`kESa_fm)^sVm`U>+UVEh6%rbFC~ zeW5c#vIqNu47oOFtxt2hO2|%^nwWrN0~a2h9f%JDQWPT6GoC`Ncbl;=_!kSzAeb0d zRjyY&eyB*j*L*pOpLQBhP<9$Gyyom2(Xia=DuSlgePO<;U3cjVlThc`yHVXNf@E%n z5g|4{LQaLM=7;Y0nXf3k1gwyWh=GbYpsooLzKH}m2!h;1<@m*PwkbP85M4J;UH>97 zX0w&B)D4f?5oW`M7gIZ!udJeM zBFsrjv3*JQTJnkc?HYDzuQldt)EKcTZM?V^Im6tQd1(SdqME);))m$CWvDg@g}k8R zmB|R2~q-tE_prTKEb8TcIV;91{ z;5N*`G8GDs?*A8eH%XhA`BeJ8^%kX|;GCrFz;dCA;@%D{O{l6*O4GWUfA!23FAV~5 zUg{T>Q4aQLqXtsZIm)Af{E&!GZ-5Lo5?iY7X99&%YotadqnB=FS!y#Mr4h97Lut1Q z%-0*ugJ(2FujD3!B>vQ-to@kq(TB2h(nS&XkbZd zn&hchTOW_bsmmHPNY?Bx!|0*@L=V2=u=$2Wocl+SnB6=cREpJ!^nCF0dZc*M_hT{B zH_Jpi|KB3kMg)-pwK|C(1WOnR6R!8Oa z;qyaj+CFmw4Nq;H1+)NykO5js_z>(Xd18W7)+d@f6~UJ*rKELVxrGwtgm-%86&{kp zVdkfmk!Tuq)#(d;MXnHdX=?hgD|)pv-y(PagY+&`_;L)XeK=15ywZrfxz`lS-H6cq z%+772hR!zQ^)@s*!Y_w9wC=oD4yrL&mim9@+bHMtBSiZB4i`WE7<0HFU&}>)4j1{a z&X+|#Lz55+Q3k&@3n4KnyjH;w<>YHWASBLB5)#YATBeQ>1A&?kHk
sn?NG5goi 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
& z+QqMYMC<_-X?wPV$2=hP5yT~z$9+WX0hNpP6CMiq2;!psYabDNK;@$S8xIA11aZ-x z<0E1Zs7Twh9nAHB&_@uLT;}ny}(Dr9#FYxFZ58rM-Uh7Cw)Zh z0TpR`wu7fUAoLN$C6`4$BKCmFMSHP_0zQJcXg}>EVh^ZXw4d=%z()`l?Ik`U_JE4C zJ=?)j4+wn(amnRb9}#;%<)ZzZhXOu=xM(l)5wQnUF51gI6z~zmMfwHA)0hNpPdJhGB1aZ+W_YtuNRHW_M4k|n#^by1* zmlu6R>;aXF_DdcL_z2>n{d*q~dqCx){Ra;Pd<1dPe%VLF9#E0CXFJ&70ill|F1fto zBVrGzT(tk_p@5GdF4`M?MC<{Ti}ofD1$+c?(SFrO#2!$Qwr4x|lLv%8g1F@JnvaM* zpmNcE-9rH%L0q)|>?2|is9d!F;-P?#ATHXKJ|gyjinKl3!5bbB`Uv8Z%U^v&>;aXF z_TM}d@DapC`%NDadqCx)z1c$nA3P|%9}#;%<)XdaLjfN_T(o!ih}Z)v()Mfz?|VS#BZx~bJAFj#0hNpPE)NBK1aZ-> z_7SlMR4&>z9t!vf;-bCVN5mdbk+x?$*y91Ak036&eBdKu52#$U|LLKCk037EdwoRg z0hNpPJ`V+a1aZ;+myd`&pdxM0cJQGGgg%0}_JQVN|#6|n4kBB{>a?$?GLjfN_ zT(pn*h}Z)v()Mfz$2}nQ5yT~z&wWJf0hNpP7aj`u2;!psrH_a`pmNbZ;h}(!ATHV` zeMIa56={36gReXw^by1*mwF!&dqCx)eab@tA3~2F zfQqy|+rf7p5c&w>lFRo#BKCmFMZ3X60UtraY3rJgh&`Zk(bhc_@DapCTlk3B11i$? zY6p6Z2ZTO?xa4B^h}Z)v7wuRN1$+c?(LTpV#2!$&XrJq$fR7+9+HpQ2_JE4CJ=;Me z4+wn(amnR89}#;%<)VGQhXOu=xM(-_5wQnUF4|2z6z~zmMf(CD5qm&I+Mey8sRx8U zg1F?;%tyo?P`PMd=%Ij*ATHV$`H0v9Di`hM9t!vf;-Y=AkBB{>B5luh(82>kA3
LX$gs7Twh9klU)&_@uLT-y4G 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%0A`ks6!WOUKgG;+SO(Pc?%@S{ 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 anS)i!R&uPz|=7I*P`^z)&ki)kv3J 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 z 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

jk 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[TD;z}hxg zZqCk>n}mn^G_ev}x2v#g3zV{qja^q(Qig5T`utOz8ztPj^Q#A7!&dK{wCZWeL6ug4 zX0$eh2|LI5?c$#NU!ocPqC9N2p?c-AqoMY8?$)MUgHLPCC z4P|AUO#UAMZGug6?nEafh-gEV+5JESj+Usc@{)6$1_u$SGF+rVZk4MB)s{=V%C?1# z3h+y{iz5U}T`svIlW22rcTWDfNJ_B0UREWrferjb15!YQs{7g8Wrs>2ISJhdT|JN? zY95v$M6ImUV-oLuWz`Qlb2q{6hm1qcVz?{-StNlgT|Pt;)JHsh+<;D;j6l0I@qW49 zUM?z1)3+LVA>>gtx~hm-k50o=1xreC-WJ`7H3n_EO{Uj~Rc!il93!B#FNPkpTNHE9 z>2w!)WX?eUQ+M69-|clWIG zh4NJV-q9ZM(ZYS|^pDdF(UVLhVB%?6Wo0@G^p{1u_lSdg?q|gsco#2J9;`Xbs!V7z z8`)=H>z1jvFulWq$G)pXJ7#caVO8y_lltL5`K-+OSI1~fgsj6X-C!S16_(luQiY4; z-qb%<+q?VbwcCH}EnK8=_sqWx4wVn}73N^QYnI%#M@TGuoOReN?q^}(hlkb!PP9Qs zSu)GFK<3nmbu>SxYvgbCpLM%pfm5;G!b-TVey3Owjmao@^D{$)%#EhGvC1sDn0U!$ ziPw{06m9`=f2*8%n%rHf$eh_Auct-*x|n&d+_48)K>q|s9(v~O73*26yX}{H3vK(2 z)Xe3m{mlEx%5#}>iv8cch`qEIGZ&Pef`*uRnf-^}LOj`XlUI8k1q%3@$4o-*faOjC zCYTf2nd#Nk%xlf?CFZ1lH0jKHl`MA7{gv2YPD(NT6%ZFB&mXblvKXY81x8|B9M|GX8Og8FzpV=%fbQtQgNmKZ za;>;XGJ6&Qrn9pICPszl+AmR3(cAD7^;MN-t4lN7hnma(-h-&}r_4-KDATy7fG(@b z0GqPWC+`p+V3PEbr2Jzo#9hJsJyAdl1ctW*|M>MVFTlGE>5DFxfq?>Rgv zMUKYZ3H#uKW)I!o+g}m0`pob%j6TFJ{p4sA1ji_vin za*L=md!94#4p`BB4wS2?#IbUlnsp=%6$DIZDS`B3c}xlBO89ltv6i^SaoD+op{bM6 zqJD*1hdw>=H7%0QsVGF_n(a>qAgzA%N7PKs$od`K|aF1XGw$jC@ruGIhaG z#I9v*em`QZjLl9Vb~a-(D&5%BJvx=ht!(;1$HcFR56h|nfKl+PzQq`ER$YWZ(NVRG zG16AGkTKF*RmT|XQ1uzcSg)#|F@~DU=%niq6f=fL$z)YIgRKlM)@;#ynQ}l}>U>u@ zu%e=J$STH|Q&v66K&2kp{-*QoAKo`V#?-16O!%jp8lBXSpZw;<6n6H(j;XJU%bdKR zNmhB~bzXk+V>BDW7&&QURDR^O(l^fw>(xGTg*z!@u$_d>6f zF5ib#{f#m8O+kt$$aXYf~3B= zFddm!-!h=+Z-j>!|FY``YKu(C_gi$;mfFssc&al?l%=v-z?#N zQ!)Lm&!vb-RZKyj)$e`tW6Y<@x+TCCM=y?j zRCLPdoOU;diYZ8Q1->c%tC;#WKjnVQx7?UY1+Ssk{1Sag)!!IXP*hobQ-7)t<}`^e zXtb1@L%~#~{Fs8NX!r4`RP~Kz2`}5g$BlE9-Px9UfAR%z_q;zavxP$3+4TePWn;Eb z-=BN|zGU8ce1A|33nhSi)3Dh_Bq4zN6C;9RSfByiR}7nNL=pnHKRF^Oh6PI8S@(l0 zhXpet2?4%r9uXA70`+irp85&#FT-Zj%cgqCzO2kyB~;7!8OwJ_r0>DmxW6=Vc!q);z}-7kj*ONm1E?-1#n+Ga(IS<9Ke0uP&r2K8*yjd53V0M zI);KA;L8m|w%WGEayY#Z=U-=6i^_bvR#YbKxTt*G$9>9e z;_G(3h-|YPMD=seG-%g6U8FrhfOFNQw!i4&`F+aHJguxvbfB^1q z99Pj3&P?1{_k){H7~OFJ2=Ha3FG6Kd7QlT=M&bzn4B-Ce2qVh?AHaQUM&bzn4B)

u?{5&jv#{jCv3 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

wIa2C7a0b8g? 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�!gBclc%%)}NVa$u z!|YHS24Pm4(!stN9~8Y94#(PMTO-1!hdXhS1;JMkC!nJfJCBzmXzz`W3NKtA@0rlZ@rfd)D^y<>%DgF&vDIC z&30CqJJj{9W89+<05=M6;Zq%-K5tz6L)^8AeQkxS(H>CjO|%Mlx&wFKK_-3io^$dbiiTNK1zO5^;dA1rCAZ;IRnYn>`-BlOpVI?r=|NxqL~(5@ut5N; zP5_qr{W;PRRCrQ8T@vJ{%CSBz`3*l|4@Z%}t~c7IzS$k(V_@ZcD&qWGQ$dYqew?1c zac}uc_KK?0sLf^*o@xLe@nx7_GSMb-Hvw&vr@CQiAJZYEXz`Vk3 z2E=vP4g!_^f~&IUK&A9Jj*sNRTBv@!s{>kGw44Iu;}huKj^Ap_k$% z9OxNQIvGW`!b}%EtLnXW;eFyC!4avhd9={i7kwPtaKwKy%a3{f=(s9tZ4~vq2EM$U z_rvMm(3!V6P7C2#UlHOzd7Jvh)@MZh?X0YVx1aF-%Y!!pQFM4-@LvM=%c0)M&`0!d zM{Rit&x|x!i*SIKfIqDOLqUwGLvSa`%Z=K@RIxi)?O%g7e!{!c65&P?oaj-(TFdnG zpl9|P@o@>0mPr#okx!5#N(MJ)LCK3(^K};YPHo`VCML~H+UYv+Qd5-J$}LwTc5#dR z z)3;efuSmB^&%CYT|5@0*bdcqlEc^xNM1g00xQ_HSyZ9w`NKMw@P{qw?;`qMHx-asz zfgjfE5BjwM`JT5$P(EwJxXmAC1D&)N>c^tbrE^{l{If z>Obe4{@OX?#iuoI?_XaPGv=v7XeaH3X%R^7ARM__-qSa>rSyzmW0xhiYz<16z))$!zt zp{f^qNpOu!B-7E>NuPPoI;8Yr5Rc|w_+n~C0446VbBDwYabD>{F8|s6FZ>DGWZ|dy z^b70=U3e0$gAKmQiaV64?jYKhYJ}i82^`(5e+X3z%tEp98`P0gmQuKT3aZ78x_XJa z-Vv869?OGF^@YhoB~uh9xwQ$_=A<21jh>PYTLW6US_Hb|q`9V1QB~SvZOatzVToH^ z+-v8Z5jPR!V{$8uDW9J3o}6*%v+yOT%}sD?O7F9d+ohYBY;{dziBIm^4%GelDj$O1 zLkzFU{su%o=szxme3qvMPYC?>FWVD*(O&aOakI6E=L0yvHTu2@`)=(Q`B%unZWKG# z;5MoCJ3H_y_D+^=f$vxP0Qb}4w)lp?gezKt2tEjXoS*RKrrAl83&TKMgCQ2o^A)O{to?TWRod9d!3JsTkC+q#pLRJ+2$?LzXdgV-s~l$;6IBVm#HN7a0>Z))5D%-m@l% zTh%W)cIgJ)rk>2`*XQvL{H3oLeT}-k&YT8^_(&$f#?~GO3T(lyvP+*y>YZyjD^bd% zYzlN0GCBaMFg|LkdapH~5T7H<_Cq!ZycY4dli;!|P;kp&0TX)t+HWe5s9hNkCa`w& z*j#6!4UJG10lSpj0MBSZRJ?56Ddt?ks+sBNLEp@8h}+CPlE&Oi~8n0B>tJ-uQ&RXzw0!9@G8~##+nUe3Yv-~5d$sG0`#Y@n$ieYr66+gE6ag5U_G)cfoyP`xMve6;U-;Q_H zCcWlW0-9u3T);2F@`j!A6g!|7(UHk5?E7BiG0lB81`daAQFFl+5$nE8c#IR3w7zJ< znV++fXgB~u*a<0ME-F4mb4asVaW#98i4e-F7=BUmFxe;IOWGBE9PdxGj>Tad0V1#f zm3SLL1yZW`KY0aeg?rtkp9#eJz~5OD3(-NeS9;bgDIZ`0Dt?NID;y=?2e#vtJmYVy zMUGu*D%@-Hg}5iB=viL@1f#&0MI~J{TR?pPeZ;QBM7>?v0>)N83mcf3NtIGoj+Uq9 z7+)K}!Akl^dOT>RqX#|n4hcj;$gVk{K?D9SMM5(6XNmpu3N$lw8~{4{?eTs(gFc9G zZ05Wi$SI4xQ@&5l8JQ}EamfBe?_l|}NPyTDh`9sF!A(SH46Qa5}xnQ$b@Dk!G#;8OM&VaRygreFC z_u7kpBH}%-I_t?p!;K?$eI$=xO&)_ za}%T!L<9xmWnpk4p;wDDAVG_M&0jP1ubCRbAan}Ylz(vHJn;al;inmy%DS>SWE-DM zOyAYaHm;?`XC8W5HJs{Jd2nv``5Vz0G9$lc@auf_6^TZvC%S7Up&=3C;e-G+beA>m zb%kFR+vOqq494DK@kBXr2%nz21?Qz-7mE&{J6oK^*8pE}<_@pq#Vgj)JvGhNn_|&R z(CS5xTgQrOno|)jvi5BN6Hkx_N9@IlGl~ZwNXug0=fn=p4b4A4`NuXelm)`^K=A*h zz4$hQ_LzzvYCT++_*nTMBb1TjiO<#pnN`bKTutn&h&CS~aD}^P*8dR?LRuH!K5m^x- zwW6g!ZKk6Ky?NzgrwrpBOKhKXFR!dE51TSriEAvD)l{j=D~rMsH&i0F*J{Mjz4P4X|4k*HWr`N)W~u!C@V~ z^iBP;c!=ROmPy=DiI}d8k%Jp5EyORw^21}N-EiFM1HY;l2UipO}o$>B?X)doRz}1FP>C^FfWTlCa?6_YvqUB-g zkHo_a8r>?}TNvY*ane_WqKF}l>l;97>ZKe}6XEy~G}x>+b-i_{a}$3E5QIcM;i9fa zS+Ww21YTPZN&8Z8TX6=7D~s!LYsGGaRZjqf{BAB>j*w&5I`Tl5(!!vo-Tsm%e)rhELl~(*X1k{d&rU~g2N|W{H0>IdrgW99W)}` zd(h5^!0HRb7`OAT5$BeOpo+!Mgz?!aDXJDGu3L1X=^+3g8zMbD$XzQQQ8mLhW!#>D zyIEC;KQ@mU!F|byU>N7q=r)RAJyZob)KoAMy}CKAF&+`h3GwF=iY%@kOxrH@Iu~XK ziF+la(p-uVGR<8vB@f(2ZI(mu@d*L%mttcuK2a(mIaU<}iHC|6@7&jtdbJxOTKUm{u7;qwc`FaZ z4RI4GjGi2lLGdO*1FFjs9Nw6wgFEX}VxQNFRAzH|$~ALj;VG9rd{TiE*qW z&C)949T6pnP8NaDg~G*fBR8(Y^26?c?s)D?Bdb@!-XKp0H52j7B5C#qebes}g9c(- zD#3>$;*J-@KsVj+VvITIUghdU*~HDy#13?n&E$-bBZoMc30#81s^}}Dafi4UGSjii zJ=1Z-9)L=%`L^v}QYZL7A?o_4ZsvGVZOpPH#Ls7~N0)U#0Fn{W96XmLkMvumq(?UZX5d#B}y$5k*jnmiQ8)w9kOy6*Kd0PbEIR=+4{N?auz zlekLwa{qhPEql(zT^d~Wd2-yDcv&he85H@(YFD(7_*sQvLwRC@reO7v-ul? zY;rUp-*RX=Be&y;fAB?r{QhaH#1rybyeZvC2qmx1qb;##-z1mV1vg2BtDq7H1pv!4 zHcF_V@}}zT(4R;jp)llpr7fSzvFnFk!}D4GuHP=Ur+(rZ8vpozzZdg5U&p*|>aaMc zX|k58s_&9mUZm^z6JuUCNdj`A*bWrK#9;2USkeR(auYDnPhabwsjBPXLwMM4`N;yG~nstd=Pc< z*}u>z>R<{%kR?gKfChO~qJ-frW>y?=S4& ztvEs0bKEtEz7BWfx_s%$y%}3N^xa=YD{&=uD}2XDXE9t`(+n~J5JYs=H)$&m+(d+B zi9pp6qXT!aq2J}j59qUTHq~rIUj|o>os0@kt-w?e3_MZx;S9S6u22u*SMr)$E)huXV;6W{gLhb}lu<{cw)Ahbu!`JK+*)+<6_? zGzd0jL3pH}-{aFAD@q(Njr!;({@1w2=Zo zP2Z?D@5hLFjh0TNr8A6cE8*slmk7V@L`YW*E3YQQ;t|Jj|50ZM!Mw+m(sHylq?Bz5 z`FEqycCK{z(lhy0F&RS<4q}&Lz>Hh$l^&tG<%>&XWx1Ie1RU&U=K~)2gAcN)qe_R~Ztw}KS!Bor3(e5m{9|9#W4?pV-HXGWX5{UXA6hVSZ+OX@V@BR~ z;?W}KX{?VRX~<>*zrwML1s}(@tkdJV`E3KAw)1I#$zx2OVDcoBA$}d&faEY=5A$i5 zPbZncZ`i}m>}HX11(UBad6~&6EZPWfXHv~%qSksae;4*otJ$vs8#Yq;(t zCSiqziL5`oY;E0>`GobxPzH8Ca$aj-54iZ8-Y${RZ*48gkjR4M4Ljp*Ozjrjg|Y=) zvJ4h!ZsRG_h=*Pr@78-kxtNM|VKDGTAxD@T=lYwEPu#mQ?rtR2U!|a%0OtgU=F`W( z@{B{eY(hTX-Gi^(mJ4~9NZ%~^*gvanrZZ=>_R<1uh*pLFuy^lX`Hd7^kVJ&YMj zM7G|XS&iLE*fxl{yYV=Ja7%~!@V58CbU#?!V>*74wRycR5!4@0R=BIU<1gf{mjw9kIu^ zSX+;e-$3}wtxbG-vtc~ewzJ3G!Nq<~jJg7X@bg?pZBUcBoa(K+m#+;-f}Fvu+vwo# znR=6$Zipy{7?dC_xD-6(%6tmR`JZI+vSo@147feNPXtiV@PtwGXb5MIqzZ8&E!TVUt~f6xqc>dnY3CWKlc+vZKkCMxtECx zEK!vE0?YjYPkAfwl((MAs{lA{9+N)H$egy#@?}oLWgA7)r!#?$a;K=s%qRKz?`3iu zlOZOjkX$gI32Sq~SCGt@!~_Fn{HgK5MIRP3_|sk{Zy=eul*wnA`~=CY1x#*c@?9hs zmNBuJ96=k5XB=E*J+Q09337dY5ti{VYY(x1$=W02)5ub~8c8J&$5ekcj=N|YPEw#V zSMjlrGp2K3%%T8tAO#4EG0>?Ba(#Z)*@`iG;@G$gI|b(_%T=W82I9u1<1xriz@06h zV0{$KPsQs)C@MeW`YTRV14z!gK{OQjG=93G-IVUqn)&AJ(xXCn2;v~ zxdwAycsJ%`XDmM(BNPvigso0Zg@aZ_Fg~9d3~c zqb{h43NbtZ%h^uROT5gNsCf~UIiWfH0H7O&IP_Du_r%}SAN9X?&hui9&fx@nt~X(U6O1ZNSs*0pw5Cz$rHI{N%2($#+|^8oQTt`I=-#wrqJ;r3tp)^85!v3 z{xA{P74E_YQGlIN$TVV4cpARVgdMEPEfzWr?%A1ueMe%#+whf^2nIEO!pJ#HtS9gz zs;he(wH|ywUmJ`vepX-54b`e%i8}`s#M<==n1g%Wj21Ch@y#Q@F;!j=)|m&}RC7(N z!jo#CiBC&02gEmMtcBr=Sn^Axr&LCC@a7x#U#C3LIGg)H10`niuoGtfQ_OEa!s|+t@nGh-XvPh z%3maKeGJ_4{L%DCikv0Hq#{i+F*39~W*70tdiPvhDiS~PcOX-Oy_j9wq>n+8#R!-< z>1TYkUE9r?Wh1gQr5hzmHp9B$bx=$?DK~b5?Wo29eTfcE*-je5GJWZgS{3(j&pIxO zahXo(N$pNzd)_M^?nVM`!Ru(N%ksPl&X*u3nthYSq>%(YM7(M&kc%^4!wUTpiCvIO zP-MRR#!nB0NN!JpsiDK;PsOXdoUfja)h$CS zP3CT+$)B55yPY}b+n*|n*7aOYJj3uODsdfY{=BNs91l?r_o zKq#q|0bG2I@IsZ?_D~z})upEgJ$X|^xgS8~3IJt{s-+0grIG-GLIJ2`ur5sA)Yck- zI-`B1tVd1;?5dX4_+!FQS}OxGhMcktIsLVPIt29srB39p5dNe}K3s9%Lf0U{SvphN{rDAGn3W0)DLmV@QEugt%evnIP3U_brO`^($G)Co{Lte=-7}^{~J3D}z zThGCCmj?(;rJ1h$qP!wejeCpF(XJ^KKxC>E$x0L#EdZ1PB`%0)HAZ`S^}b9ja%9&N zh>((95Hxm8APAI7PtwZ~x-76#qk$Ac6y*ERieLy?r3Bw04

oS$ZY(3|rBVqU8_ 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 z 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 dmv|O{o9? literal 0 HcmV?d00001 diff --git a/SEL32/tests/sel32_test.ini b/SEL32/tests/sel32_test.ini new file mode 100644 index 00000000..7e2976e7 --- /dev/null +++ b/SEL32/tests/sel32_test.ini @@ -0,0 +1,226 @@ +cd %~p0 +;====================================================== +; SEL32 System Engineering Labs 32 bit computer +; MPX/UTX CPU diagnostic hardware configuration +; CPU - 32/67 4M Sel32 Concept/32 +; IOP - 7e00 Model 8001 IOP Processor Controller +; DMA - 0800 2311/2314 Disk Processor II (N/U) +; dma0 - N/U +; dma0 <-> detached +; LPR - 7ef8/7ef9 Model 924X High Speed Line Printer +; COM - 7ec0 8512 8-line async communications (N/U) +; CON - 7efc/7efd Console Terminal +; RTC - 7f06 60 HZ Real-Time clock +; ITM - 7f04 38.4MS Interval timer +; MT - 1000 8051 Buffered Tape Processor +; mta0 <- diag.tap +; EC - 0e00 Model 8516 Ethernet (not supported) +;====================================================== +; Set hostname +set env HOST=sel32 +; Set local IP address +; set env IP=192.168.1.5 (N/U) +;====================================================== +; +; Set run limit of 2 minutes +set runlimit 2 minutes +set on +on error ignore +on runtime echof "\r\n*** FAILED - SEL32 Test Runtime Limit %SIM_RUNLIMIT% %SIM_RUNLIMIT_UNITS% Exceeded ***\n"; exit 1 +; +if not exist "diag.tap" echo "\n*** FAILURE diag.tap file missing ***\n"; exit 1 +; +; Set debug output +;set debug -n sel.log +;set debug stderr +; +; CPU type and memory +;set CPU 32/27 2M +;set CPU 32/27 4M +;set CPU 32/87 4M +set CPU 32/67 4M +;set CPU 32/97 4M +;set CPU V6 4M +;set CPU V6 8M +;set CPU V9 4M +;set CPU V9 8M +; +; CPU debug options +;set cpu debug=cmd;exp;inst;detail;trap;xio;irq +; Set instruction trace history size +;;set cpu history=10000 +; useful options +;set cpu debug=exp +;set cpu debug=cmd;exp;irq;trap;xio +;set cpu debug=cmd;irq;trap;exp +;set cpu debug=irq;trap;exp;xio +;set cpu debug=irq;xio +;set cpu debug=irq;exp;trap +; +; RTC realtime clock +set RTC 50 +;set RTC 60 +set RTC enable +; RTC debug options +;set RTC debug=cmd +; +; ITM interval timer +;set ITM debug=cmd +; +; IOP at channel 7e00 +; useful options +;set iop debug=cmd;exp +;set iop debug=cmd +; make iop online +set iop enable +; set iop channel address +set iop0 dev=7e00 +; +; MFP at channel 7e00 +; useful options +;set mfp debug=cmd;exp +; make mfp online +;set mfp enable +; set mfp channel address +;set mfp0 dev=7e00 +;set mfp0 dev=7600 +; +; COM 8-Line +;set com debug=cmd; +;set coml0 enable +;set coml1 enable +;set coml2 enable +;set coml3 enable +;set coml4 enable +;set coml5 enable +;set coml6 enable +;set coml7 enable +; +; Enable telnet sessions on port 4747 +;set comc enable +;at comc 4747 +; +; LPR +;set lpr debug=cmd;detail +;set lpr enable +; LPR output file +;at lpr lprout +; +; CON Console +;set con debug=cmd;exp;detail +; useful options +; enable console +set con enable +; set console address +; set con0 enable +set con0 dev=7efc +; set con1 enable +set con1 dev=7efd +;set con debug=cmd;exp +; +; MTA Buffered tape processor +;set mta debug=cmd;exp;detail;data +; useful options +; +; enable MTA to change channel +set mta enable +; set mta channel +set mta0 dev=1000 +; +; Attach in/out tape files +set mta0 locked +at mta0 diag.tap +;at mta1 temptape.tap +;at mta2 output.tap +; +; DMA disk processor II/UDP +; enable DMA to change channel +;set dma enable +; set disk chan to 0800 +;set dma0 dev=800 +; set disk type to MPX MH300 +;set dma0 type=MH300 +; set disk type to UTX 9346 +;set dma0 type=9346 +;set dma0 type=8155 +;set dma0 type=8887 +;set dma0 type=8148 +; +; Attach diskfile +;at dma0 utx0disk +;at dma0 utx1disk +;at dma0 sim32disk +;at dma debug=cmd;exp;detail;data +;at dma0 diagdisk +; useful options +;set dma debug=cmd;exp +;set dma debug=exp;cmd;detail +; +; SDA SCFI disk processor +;set sda debug=cmd;exp;data;detail +; Attach diskfiles +;at sda0 diskfile4 +;at sda1 diskfile5 +; +; DPA high speed disk processor +; enable the HSDP to change channel +;set dpa enable +; set channel addr +;set dpa dev=800 +; set disk type to UTX 8887 +;set dpa0 type=8887 +; +; Attach diskfiles +;at utxdsk.dsk +;at dpa0 utx0hsdp +;at dpa1 utx1hsdp +; +;set dpa debug=cmd;detail;exp +; useful options +;set dpa debug=cmd;exp +; +; set console switches +deposit CSW 0 +; +;UTX boot tape options +;set GPR 7 to 0x00 to boot in multi-user mode +;set GPR 7 to 0x01 to prompt for unix filename +;set GPR 7 to 0x02 to boot in single user mode +;set GPR 7 to 0x10 to disable swapping and paging +;set GPR 7 to 0x20 to boot from device specified in GPR6 +;set GPR 7 to 0x40 to allow progress messages on boot +;deposit BOOTR[7] 40 +;deposit BOOTR[7] 52 +;deposit BOOTR[7] 42 +;deposit BOOTR[7] 2 +;deposit BOOTR[6] 800 +;deposit BOOTR[0] ffffffff +; +; Set register content at boot for SEL diagnostics +; uncomment next line to get diag loader prompt +;deposit bootr[0] ffffffff +deposit bootr[1] 0 +deposit bootr[2] 0 +; +; allow cpu idle +set cpu idle +; Set expect script for auto time entry on MPX at OPCOM prompt +;expect haltafter=20000 +; wait for expected output from simulator, then enter this text +;expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r"; GO +; +; Boot from disk +;bo dpa0 +;bo dma0 +; +; Go to simh on completion of script +expect "DOL>" echof "\r\n*** PASSED - SEL32 Autobatch Diagnostic Successfully Completed\n"; exit 0 +; Boot from mag tape +bo mta0 +;det all +;rm temptape.tap +;rm output.tap +expect "[][]" echof "\r\n*** FAILED - SEL32 Autobatch Diagnostic Failed to Complete\n"; exit 1 +echof "\r\n*** FAILED - SEL32 Autobatch Diagnostic Failed to Complete\n" +exit 1 +;quit diff --git a/Visual Studio Projects/SEL32.vcproj b/Visual Studio Projects/SEL32.vcproj new file mode 100755 index 00000000..077355f1 --- /dev/null +++ b/Visual Studio Projects/SEL32.vcproj @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Visual Studio Projects/Simh.sln b/Visual Studio Projects/Simh.sln old mode 100644 new mode 100755 index dc0e7674..3a213c5a --- a/Visual Studio Projects/Simh.sln +++ b/Visual Studio Projects/Simh.sln @@ -383,6 +383,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PDP10-KS", "PDP10-KS.vcproj {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SEL32", "SEL32.vcproj", "{9B214A06-3727-44D4-99B7-2C3E44B86B32}" + ProjectSection(ProjectDependencies) = postProject + {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -697,6 +702,10 @@ Global {7F4EB115-2027-4582-A6EB-6A7DD9BA6F11}.Debug|Win32.Build.0 = Debug|Win32 {7F4EB115-2027-4582-A6EB-6A7DD9BA6F11}.Release|Win32.ActiveCfg = Release|Win32 {7F4EB115-2027-4582-A6EB-6A7DD9BA6F11}.Release|Win32.Build.0 = Release|Win32 + {9B214A06-3727-44D4-99B7-2C3E44B86B32}.Debug|Win32.ActiveCfg = Debug|Win32 + {9B214A06-3727-44D4-99B7-2C3E44B86B32}.Debug|Win32.Build.0 = Debug|Win32 + {9B214A06-3727-44D4-99B7-2C3E44B86B32}.Release|Win32.ActiveCfg = Release|Win32 + {9B214A06-3727-44D4-99B7-2C3E44B86B32}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/doc/sel32_doc.doc b/doc/sel32_doc.doc new file mode 100644 index 0000000000000000000000000000000000000000..b3d4c440974330219efef9f6d5dddb38afd9795d GIT binary patch literal 96256 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