From 4ffd3be79034dbbcca48008a371c2c1e07f904f4 Mon Sep 17 00:00:00 2001 From: Bob Supnik Date: Wed, 25 Jun 2003 09:20:00 -0700 Subject: [PATCH] Notes For V3.0-0 Because some key files have changed, V3.0 should be unzipped to a clean directory. 1. New Features in 3.0-0 1.1 SCP and Libraries - Added ASSIGN/DEASSIGN (logical name) commands. - Changed RESTORE to unconditionally detach files. - Added E11 and TPC format support to magtape library. - Fixed bug in SHOW CONNECTIONS. - Added USE_ADDR64 support 1.2 All magtapes - Magtapes support SIMH format, E11 format, and TPC format (read only). - SET FORMAT=format sets the specified tape unit's format. - SHOW FORMAT displays the specified tape unit's format. - Tape format can also be set as part of the ATTACH command, using the -F switch. 1.3 VAX - VAX can be compiled without USE_INT64. - If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support files > 2GB. - VAX ROM has speed control (SET ROM DELAY/NODELAY). 2. Bugs Fixed in 3.01-0 2.1 VAX - Fixed CVTfi bug: integer overflow not set if exponent out of range - Fixed EMODx bugs: o First and second operands reversed o Separated fraction received wrong exponent o Overflow calculation on separated integer incorrect o Fraction not set to zero if exponent out of range - Fixed interval timer and ROM access to pass power-up self-test even on very fast host processors (fixes from Mark Pizzolato). 2.2 1401 - Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS. - Fixed MCE bug, BS off by 1 if zero suppress. - Fixed chaining bug, D lost if return to SCP. - Fixed H branch, branch occurs after continue. - Added check for invalid 8 character MCW, LCA. - Fixed magtape load-mode end of record response. 2.3 Nova - Fixed DSK variable size interaction with restore. 2.4 PDP-1 - Fixed DT variable size interaction with restore. 2.5 PDP-11 - Fixed DT variable size interaction with restore. - Fixed bug in MMR1 update (found by Tim Stark). - Added XQ features and fixed bugs: o Corrected XQ interrupts on IE state transition (code by Tom Evans). o Added XQ interrupt clear on soft reset. o Removed XQ interrupt when setting XL or RL (multiple people). o Added SET/SHOW XQ STATS. o Added SHOW XQ FILTERS. o Added ability to split received packet into multiple buffers. o Added explicit runt and giant packet processing. 2.6 PDP-18B - Fixed DT, RF variable size interaction with restore. - Fixed MT bug in MTTR. 2.7 PDP-8 - Fixed DT, DF, RF, RX variable size interaction with restore. - Fixed MT bug in SKTR. 2.8 HP2100 - Fixed bug in DP (13210A controller only), DQ read status. - Fixed bug in DP, DQ seek complete. 2.9 GRI - Fixed bug in SC queue pointer management. 3. New Features in 3.0 vs prior releases N/A 4. Bugs Fixed in 3.0 vs prior releases N/A 5. General Notes WARNING: The RESTORE command has changed. RESTORE will now detach an attached file on a unit, if that unit did not have an attached file in the saved configuration. This is required to assure that the unit flags and the file state are consistent. WARNING: The compilation scheme for the PDP-10, PDP-11, and VAX has changed. Use one of the supplied build files, or read the documentation carefully, before compiling any of these simulators. --- 0readme_210.txt | 305 -- 0readme_30.txt | 110 + 0readme_ethernet.txt | 311 +- ALTAIR/altair_cpu.c | 20 +- ALTAIR/altair_defs.h | 8 +- ALTAIR/altair_dsk.c | 4 +- ALTAIR/altair_sio.c | 11 +- ALTAIR/altair_sys.c | 5 +- AltairZ80/altairZ80.txt | 296 +- AltairZ80/altairZ80_cpu.c | 6320 +++++++++++++++++++++--------------- AltairZ80/altairZ80_defs.h | 53 +- AltairZ80/altairZ80_dsk.c | 347 +- AltairZ80/altairZ80_sio.c | 685 ++-- AltairZ80/altairZ80_sys.c | 194 +- AltairZ80/altairz80_hdsk.c | 118 +- GRI/gri_cpu.c | 14 +- GRI/gri_defs.h | 5 +- GRI/gri_doc.txt | 14 +- GRI/gri_stddev.c | 31 +- GRI/gri_sys.c | 7 +- H316/h316_cpu.c | 53 +- H316/h316_defs.h | 10 +- H316/h316_doc.txt | 4 +- H316/h316_lp.c | 67 +- H316/h316_stddev.c | 11 +- H316/h316_sys.c | 2 +- HP2100/hp2100_cpu.c | 9 +- HP2100/hp2100_defs.h | 5 +- HP2100/hp2100_dp.c | 47 +- HP2100/hp2100_dq.c | 43 +- HP2100/hp2100_dr.c | 4 +- HP2100/hp2100_fp.c | 2 +- HP2100/hp2100_ipl.c | 5 +- HP2100/hp2100_lps.c | 7 +- HP2100/hp2100_lpt.c | 5 +- HP2100/hp2100_ms.c | 9 +- HP2100/hp2100_mt.c | 6 +- HP2100/hp2100_mux.c | 5 +- HP2100/hp2100_stddev.c | 13 +- HP2100/hp2100_sys.c | 2 +- I1401/i1401_cd.c | 15 +- I1401/i1401_cpu.c | 77 +- I1401/i1401_dat.h | 25 + I1401/i1401_defs.h | 9 +- I1401/i1401_doc.txt | 46 +- I1401/i1401_dp.c | 2 +- I1401/i1401_iq.c | 2 +- I1401/i1401_lp.c | 5 +- I1401/i1401_mt.c | 28 +- I1401/i1401_sys.c | 5 +- I1620/i1620_cd.c | 8 +- I1620/i1620_cpu.c | 45 +- I1620/i1620_defs.h | 2 +- I1620/i1620_doc.txt | 38 +- I1620/i1620_dp.c | 4 +- I1620/i1620_fp.c | 2 +- I1620/i1620_lp.c | 6 +- I1620/i1620_pt.c | 16 +- I1620/i1620_sys.c | 2 +- I1620/i1620_tty.c | 2 +- Ibm1130/ibm1130_cpu.c | 17 +- Ibm1130/ibm1130_cr.c | 26 +- Ibm1130/ibm1130_defs.h | 2 +- Ibm1130/ibm1130_stddev.c | 8 +- Ibm1130/readme_update.txt | 9 + Interdata/id16_cpu.c | 6 +- Interdata/id16_dboot.c | 2 +- Interdata/id32_cpu.c | 2 +- Interdata/id_defs.h | 12 +- Interdata/id_doc.txt | 15 +- Interdata/id_dp.c | 10 +- Interdata/id_fd.c | 5 +- Interdata/id_fp.c | 2 +- Interdata/id_idc.c | 8 +- Interdata/id_io.c | 8 +- Interdata/id_lp.c | 6 +- Interdata/id_mt.c | 6 +- Interdata/id_pas.c | 4 +- Interdata/id_pt.c | 14 +- Interdata/id_tt.c | 5 +- Interdata/id_ttp.c | 6 +- Interdata/id_uvc.c | 2 +- NOVA/eclipse_cpu.c | 12 +- NOVA/eclipse_tt.c | 7 +- NOVA/nova_cpu.c | 10 +- NOVA/nova_defs.h | 2 +- NOVA/nova_dkp.c | 23 +- NOVA/nova_dsk.c | 18 +- NOVA/nova_lp.c | 7 +- NOVA/nova_mta.c | 6 +- NOVA/nova_plt.c | 5 +- NOVA/nova_pt.c | 7 +- NOVA/nova_sys.c | 4 +- NOVA/nova_tt.c | 5 +- NOVA/nova_tt1.c | 3 +- PDP1/pdp1_cpu.c | 4 +- PDP1/pdp1_defs.h | 4 +- PDP1/pdp1_drm.c | 2 +- PDP1/pdp1_dt.c | 51 +- PDP1/pdp1_lp.c | 5 +- PDP1/pdp1_stddev.c | 11 +- PDP1/pdp1_sys.c | 2 +- PDP10/pdp10_cpu.c | 2 +- PDP10/pdp10_defs.h | 15 +- PDP10/pdp10_doc.txt | 16 +- PDP10/pdp10_dz.c | 33 - PDP10/pdp10_fe.c | 7 +- PDP10/pdp10_ksio.c | 27 +- PDP10/pdp10_lp20.c | 5 +- PDP10/pdp10_mdfp.c | 2 +- PDP10/pdp10_pag.c | 2 +- PDP10/pdp10_pt.c | 38 - PDP10/pdp10_rp.c | 5 +- PDP10/pdp10_tim.c | 2 +- PDP10/pdp10_tu.c | 6 +- PDP10/pdp10_xtnd.c | 2 +- PDP11/pdp11_cis.c | 2 +- PDP11/pdp11_cpu.c | 12 +- PDP11/pdp11_defs.h | 20 +- PDP11/pdp11_doc.txt | 19 +- PDP11/pdp11_dz.c | 612 +++- PDP11/pdp11_hk.c | 47 +- PDP11/pdp11_io.c | 29 +- PDP11/pdp11_lp.c | 35 +- PDP11/pdp11_pclk.c | 2 +- PDP11/pdp11_pt.c | 304 +- PDP11/pdp11_rk.c | 4 +- PDP11/pdp11_rl.c | 58 +- PDP11/pdp11_rp.c | 90 +- PDP11/pdp11_rq.c | 211 +- PDP11/pdp11_rx.c | 4 +- PDP11/pdp11_ry.c | 23 +- PDP11/pdp11_stddev.c | 5 +- PDP11/pdp11_sys.c | 7 +- PDP11/pdp11_tc.c | 49 +- PDP11/pdp11_tm.c | 8 +- PDP11/pdp11_tq.c | 91 +- PDP11/pdp11_ts.c | 86 +- PDP11/pdp11_uqssp.h | 6 +- PDP11/pdp11_xq.c | 1380 +++++--- PDP11/pdp11_xq.h | 73 +- PDP11/pdp11_xq_bootrom.h | 312 ++ PDP11/pdp11_xu.c | 12 +- PDP18B/pdp18b_cpu.c | 14 +- PDP18B/pdp18b_defs.h | 3 +- PDP18B/pdp18b_drm.c | 4 +- PDP18B/pdp18b_dt.c | 55 +- PDP18B/pdp18b_lp.c | 9 +- PDP18B/pdp18b_mt.c | 23 +- PDP18B/pdp18b_rf.c | 21 +- PDP18B/pdp18b_rp.c | 2 +- PDP18B/pdp18b_stddev.c | 12 +- PDP18B/pdp18b_tt1.c | 5 +- PDP8/pdp8_cpu.c | 31 +- PDP8/pdp8_defs.h | 4 +- PDP8/pdp8_df.c | 22 +- PDP8/pdp8_dt.c | 54 +- PDP8/pdp8_lp.c | 7 +- PDP8/pdp8_mt.c | 17 +- PDP8/pdp8_pt.c | 7 +- PDP8/pdp8_rf.c | 24 +- PDP8/pdp8_rk.c | 3 +- PDP8/pdp8_rl.c | 21 +- PDP8/pdp8_rx.c | 15 +- PDP8/pdp8_sys.c | 5 +- PDP8/pdp8_tt.c | 5 +- PDP8/pdp8_ttx.c | 6 +- S3/s3_cd.c | 7 +- S3/s3_cpu.c | 4 +- S3/s3_defs.h | 4 +- S3/s3_disk.c | 5 +- S3/s3_lp.c | 7 +- S3/s3_pkb.c | 3 +- S3/s3_sys.c | 4 +- SDS/sds_cpu.c | 13 +- SDS/sds_defs.h | 6 +- SDS/sds_drm.c | 2 +- SDS/sds_dsk.c | 2 +- SDS/sds_io.c | 2 +- SDS/sds_lp.c | 8 +- SDS/sds_mt.c | 6 +- SDS/sds_mux.c | 6 +- SDS/sds_rad.c | 6 +- SDS/sds_stddev.c | 12 +- SDS/sds_sys.c | 2 +- VAX/vax_cpu.c | 44 +- VAX/vax_cpu1.c | 16 +- VAX/vax_defs.h | 12 +- VAX/vax_doc.txt | 33 +- VAX/vax_fpa.c | 1250 +++++-- VAX/vax_io.c | 152 +- VAX/vax_mmu.c | 56 +- VAX/vax_stddev.c | 5 +- VAX/vax_sys.c | 50 +- VAX/vax_sysdev.c | 150 +- VAX/vaxmod_defs.h | 36 +- dec_dz.h | 627 ---- dec_pt.h | 303 -- descrip.mms | 2029 ++++++------ makefile | 10 +- scp.c | 609 ++-- scp_tty.c | 145 +- sim_defs.h | 178 +- sim_ether.c | 48 +- sim_ether.h | 11 +- sim_rev.h | 107 +- sim_sock.c | 16 +- sim_sock.h | 7 +- sim_tape.c | 291 +- sim_tape.h | 22 +- sim_tmxr.c | 6 +- sim_tmxr.h | 2 +- simh_doc.txt | 641 ++-- simh_faq.txt | 603 ++++ simh_swre.txt | 17 +- 215 files changed, 12913 insertions(+), 8563 deletions(-) delete mode 100644 0readme_210.txt create mode 100644 0readme_30.txt delete mode 100644 PDP10/pdp10_dz.c delete mode 100644 PDP10/pdp10_pt.c create mode 100644 PDP11/pdp11_xq_bootrom.h delete mode 100644 dec_dz.h delete mode 100644 dec_pt.h create mode 100644 simh_faq.txt diff --git a/0readme_210.txt b/0readme_210.txt deleted file mode 100644 index 797b369f..00000000 --- a/0readme_210.txt +++ /dev/null @@ -1,305 +0,0 @@ -Notes For V2.10-4 - -1. New Features in 2.10-4 - -1.1 SCP and Libraries - -- Added .ini startup file capability (suggested by Hans Pufal). -- Added multiple switch evaluation points (suggested by Hans Pufal). -- Added multiple command per action. -- Added new library, sim_tape.c, for magtape emulation. - -1.2 PDP-11 - -- Added user-defined disk capacity to RQ. -- Addec choice of controllers to TQ. -- Added user-defined tape capacity to TQ. - -1.3 Interdata - -- Added SHOW SELCH n command to display selector channel state. - -1.4 Line Frequency Clocks (H316, Interdata, Nova, PDP-8, PDP-11, - PDP-18B, SDS) - -- Added SET {50HZ/60HZ}, to set the line frequency. - -1.5 DEC Console Input (PDP-8, PDP-11, PDP-18B, VAX) - -- Added SET TTI CTRL-C, to generate ^C from SIMH prompt (^C - crashes simulators compiled with Windows Visual C++). - -1.6 Magtapes - -- Revised to use magtape library for consistency. - -2. Bugs Fixed in 2.10-4 - -- SCP: fixed bug in multiword deposits to files -- Interdata disks: fixed bug in cylinder overflow on writes -- Interdata tape: fixed bug, read error did not stop selector - channel -- Interdata precision clock: improved autocalibrate algorithm - for UNIX V7. -- Nova fixed head disk: fixed autosize algorithm. -- PDP-11 RQ and TQ: fixed bugs in queue process and in vector - calculation for VAXen. -- PDP-11 TQ: fixed overly strict implementation of illegal - modifiers check. -- PDP-11 RY: fixed autosize algorithm. -- PDP-18B CPU: fixed three EAE bugs (found by Hans Pufal). -- PDP-18B MT: fixed bugs in interrupt handling, BOT error handling. -- PDP-18B RF: removed extra bit from disk address, fixed autosize - algorithm. -- PDP-18B SYS: fixed bug in FMTASC usage (found by Hans Pufal). -- PDP-8 MT: fixed bug in BOT error handling. -- PDP-8 DF, RF, RX: fixed autosize algorithm. - -3. New Features in 2.10 vs prior releases - -3.1 SCP and Libraries - -- The VT emulation package has been replaced by the capability - to remote the console to a Telnet session. Telnet clients - typically have more complete and robust VT100 emulation. -- Simulated devices may now have statically allocated buffers, - in addition to dynamically allocated buffers or disk-based - data stores. -- The DO command now takes substitutable arguments (max 9). - In command files, %n represents substitutable argument n. -- The initial command line is now interpreted as the command - name and substitutable arguments for a DO command. This is - backward compatible to prior versions. -- The initial command line parses switches. -Q is interpreted - as quiet mode; informational messages are suppressed. -- The HELP command now takes an optional argument. HELP - types help on the specified command. -- Hooks have been added for implementing GUI-based consoles, - as well as simulator-specific command extensions. A few - internal data structures and definitions have changed. -- Two new routines (tmxr_open_master, tmxr_close_master) have - been added to sim_tmxr.c. The calling sequence for - sim_accept_conn has been changed in sim_sock.c. -- The calling sequence for the VM boot routine has been modified - to add an additional parameter. -- SAVE now saves, and GET now restores, controller and unit flags. -- Library sim_ether.c has been added for Ethernet support. -- The EVAL command will evaluate a symbolic type-in and display - it in numeric form. -- The ! command (with no arguments) will launch the host operating - system command shell. The ! command (with an argument) executes - the argument as a host operating system command. (Code from - Mark Pizzolato) -- Telnet sessions now recognize BREAK. How a BREAK is transmitted - dependent on the particular Telnet client. (Code from Mark - Pizzolato) -- The sockets library includes code for active connections as - well as listening connections. -- The RESTORE command will restore saved memory size, if the - simulator supports dynamic memory resizing. -- Added dynamic extension of the breakpoint table. -- Added breakpoint actions. -- Added VMS support for ! (from Mark Pizzolato). - -3.2 VAX - -- Non-volatile RAM (NVR) can behave either like a memory or like - a disk-based peripheral. If unattached, it behaves like memory - and is saved and restored by SAVE and RESTORE, respectively. - If attached, its contents are loaded from disk by ATTACH and - written back to disk at DETACH and EXIT. -- SHOW VECTOR displays the device's interrupt vector. - A few devices allow the vector to be changed with SET - VECTOR=nnn. -- SHOW CPU IOSPACE displays the I/O space address map. -- The TK50 (TMSCP tape) has been added. -- The DEQNA/DELQA (Qbus Ethernet controllers) have been added. -- Autoconfiguration support has been added. -- The paper tape reader has been removed from vax_stddev.c and - now references a common implementation file, dec_pt.h. -- Examine and deposit switches now work on all devices, not just - the CPU. -- Device address conflicts are not detected until simulation starts. -- If the VAX console is attached to a Telnet session, BREAK is - interpreted as console halt. -- The SET/SHOW HISTORY commands enable and display a history of - the most recently executed instructions. (Code from Mark - Pizzolato) - -3.3 PDP-11 - -- SHOW VECTOR displays the device's interrupt vector. - Most devices allow the vector to be changed with SET - VECTOR=nnn. -- SHOW CPU IOSPACE displays the I/O space address map. -- The TK50 (TMSCP tape), RK611/RK06/RK07 (cartridge disk), - RX211 (double density floppy), and KW11P programmable clock - have been added. -- The DEQNA/DELQA (Qbus Ethernet controllers) have been added. -- Autoconfiguration support has been added. -- The paper tape reader has been removed from pdp11_stddev.c and - now references a common implementation file, dec_pt.h. -- Device bootstraps now use the actual CSR specified by the - SET ADDRESS command, rather than just the default CSR. Note - that PDP-11 operating systems may NOT support booting with - non-standard addresses. -- Specifying more than 256KB of memory, or changing the bus - configuration, causes all peripherals that are not compatible - with the current bus configuration to be disabled. -- Device address conflicts are not detected until simulation starts. -- The PDP-11 implements a stub DEUNA/DELUA (XU). The real XU - module will be included in a later release. - -3.4 PDP-10 - -- SHOW VECTOR displays the device's interrupt vector. - A few devices allow the vector to be changed with SET - VECTOR=nnn. -- SHOW CPU IOSPACE displays the I/O space address map. -- The RX211 (double density floppy) has been added; it is off - by default. -- The paper tape now references a common implementation file, - dec_pt.h. -- Device address conflicts are not detected until simulation starts. -- The PDP-10 implements a stub DEUNA/DELUA (XU). The real XU - module will be included in a later release. - -3.5 PDP-1 - -- DECtape (then known as MicroTape) support has been added. -- The line printer and DECtape can be disabled and enabled. -- The PDP-1 supports the Type 24 serial drum (based on recently - discovered documents). - -3.6 18b PDP's - -- The PDP-4 supports the Type 24 serial drum (based on recently - discovered documents). -- Added RB09 fixed head disk for the PDP-9. -- Added LP09 line printer for the PDP-9 and PDP-15. -- Added variable size support and autosizing to the RF15/RF09. - -3.7 PDP-8 - -- The RX28 (double density floppy) has been added as an option to - the existing RX8E controller. -- SHOW DEVNO displays the device's device number. Most - devices allow the device number to be changed with SET - DEVNO=nnn. -- Device number conflicts are not detected until simulation starts. -- Added variable size support and autosizing to the DF32 and RF08. - -3.8 Nova - -- Added variable size support and autosizing to the Novadisk. - -3.9 AltairZ80 - -- A hard drive has been added for increased storage. -- Several bugs have been fixed. - -3.10 HP 2100 - -- The 12845A has been added and made the default line printer (LPT). - The 12653A has been renamed LPS and is off by default. It also - supports the diagnostic functions needed to run the DCPC and DMS - diagnostics. -- The 12557A/13210A disk defaults to the 13210A (7900/7901). -- The 12559A magtape is off by default. -- New CPU options (EAU/NOEAU) enable/disable the extended arithmetic - instructions for the 2116. These instructions are standard on - the 2100 and 21MX. -- New CPU options (MPR/NOMPR) enable/disable memory protect for the - 2100 and 21MX. -- New CPU options (DMS/NODMS) enable/disable the dynamic mapping - instructions for the 21MX. -- The 12539 timebase generator autocalibrates. -- The IOP microinstruction set is supported for the 21MX as well - as the 2100. -- The HP2100 supports the Access Interprocessor Link (IPL). - -3.11 Simulated Magtapes - -- Simulated magtapes recognize end of file and the marker - 0xFFFFFFFF as end of medium. Only the TMSCP tape simulator - can generate an end of medium marker. -- The error handling in simulated magtapes was overhauled to be - consistent through all simulators. - -3.12 Simulated DECtapes - -- Added support for RT11 image file format (256 x 16b) to DECtapes. - -3.13 Terminals Multiplexors - -- BREAK detection was added to the HP, DEC, and Interdata terminal - multiplexors. - -4. Bugs Fixed in 2.10 vs prior releases - -- TS11/TSV05 was not simulating the XS0_MOT bit, causing failures - under VMS. In addition, two of the CTL options were coded - interchanged. -- IBM 1401 tape was not setting a word mark under group mark for - load mode reads. This caused the diagnostics to crash. -- SCP bugs in ssh_break and set_logon were fixed (found by Dave - Hittner). -- Numerous bugs in the HP 2100 extended arithmetic, floating point, - 21MX, DMS, and IOP instructions were fixed. Bugs were also fixed - in the memory protect and DMS functions. The moving head disks - (DP, DQ) were revised to simulate the hardware more accurately. - Missing functions in DQ (address skip, read address) were added. -- PDP-10 tape wouldn't boot, and then wouldn't read (reported by - Michael Thompson and Harris Newman, respectively) -- PDP-1 typewriter is half duplex, with only one shift state for - both input and output (found by Derek Peschel) -- PDP-11 console must default to 7b for early UNIX compatibility. -- PDP-11/VAX TMSCP emulator was using the wrong packet length for - read/write end packets. -- Telnet IAC+IAC processing was fixed, both for input and output - (found by Mark Pizzolato). -- PDP-11/VAX Ethernet setting flag bits wrong for chained - descriptors (found by Mark Pizzolato). -- 18b PDP RF15/RF09: fixed IOT decoding and address wraparound - logic (found by Hans Pufal). -- 18b PDP RP15: fixed IOT decoding and command initiation. -- HP2100 IPL: changed to full duplex (found by Mike Gemeny). -- HP2100 CPU: fixed last cycle bug in DMA outpout (found by Mike - Gemeny). -- Interdata 16b CPU: fixed bug in SETM, SETMR (found by Mark - Pizzolato). - - -5. General Notes - -WARNING: The build procedures have changed. There is only one UNIX -makefile. To compile without Ethernet support, simply type - - gmake {target|all} - -To compile with Ethernet support, type - - gmake USE_NETWORK=1 {target|all} - -The Mingw batch files require Mingw release 2 and invoke the Unix -makefile. There are still separate batch files for compilation -with or without Ethernet support. - -WARNING: V2.10 has reorganized and renamed some of the definition -files for the PDP-10, PDP-11, and VAX. Be sure to delete all -previous source files before you unpack the Zip archive, or -unpack it into a new directory structure. - -WARNING: V2.10 has a new, more comprehensive save file format. -Restoring save files from previous releases will cause 'invalid -register' errors and loss of CPU option flags, device enable/ -disable flags, unit online/offline flags, and unit writelock -flags. - -WARNING: If you are using Visual Studio .NET through the IDE, -be sure to turn off the /Wp64 flag in the project settings, or -dozens of spurious errors will be generated. - -WARNING: Compiling Ethernet support under Windows requires -extra steps; see the Ethernet readme file. Ethernet support is -currently available only for Windows, Linux, NetBSD, and OpenBSD. diff --git a/0readme_30.txt b/0readme_30.txt new file mode 100644 index 00000000..70551e2d --- /dev/null +++ b/0readme_30.txt @@ -0,0 +1,110 @@ +Notes For V3.0-0 + +Because some key files have changed, V3.0 should be unzipped to a +clean directory. + +1. New Features in 3.0-0 + +1.1 SCP and Libraries + +- Added ASSIGN/DEASSIGN (logical name) commands. +- Changed RESTORE to unconditionally detach files. +- Added E11 and TPC format support to magtape library. +- Fixed bug in SHOW CONNECTIONS. +- Added USE_ADDR64 support + +1.2 All magtapes + +- Magtapes support SIMH format, E11 format, and TPC format (read only). +- SET FORMAT=format sets the specified tape unit's format. +- SHOW FORMAT displays the specified tape unit's format. +- Tape format can also be set as part of the ATTACH command, using + the -F switch. + +1.3 VAX + +- VAX can be compiled without USE_INT64. +- If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support + files > 2GB. +- VAX ROM has speed control (SET ROM DELAY/NODELAY). + +2. Bugs Fixed in 3.01-0 + +2.1 VAX + +- Fixed CVTfi bug: integer overflow not set if exponent out of range +- Fixed EMODx bugs: + o First and second operands reversed + o Separated fraction received wrong exponent + o Overflow calculation on separated integer incorrect + o Fraction not set to zero if exponent out of range +- Fixed interval timer and ROM access to pass power-up self-test even on very + fast host processors (fixes from Mark Pizzolato). + +2.2 1401 + +- Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS. +- Fixed MCE bug, BS off by 1 if zero suppress. +- Fixed chaining bug, D lost if return to SCP. +- Fixed H branch, branch occurs after continue. +- Added check for invalid 8 character MCW, LCA. +- Fixed magtape load-mode end of record response. + +2.3 Nova + +- Fixed DSK variable size interaction with restore. + +2.4 PDP-1 + +- Fixed DT variable size interaction with restore. + +2.5 PDP-11 + +- Fixed DT variable size interaction with restore. +- Fixed bug in MMR1 update (found by Tim Stark). +- Added XQ features and fixed bugs: + o Corrected XQ interrupts on IE state transition (code by Tom Evans). + o Added XQ interrupt clear on soft reset. + o Removed XQ interrupt when setting XL or RL (multiple people). + o Added SET/SHOW XQ STATS. + o Added SHOW XQ FILTERS. + o Added ability to split received packet into multiple buffers. + o Added explicit runt and giant packet processing. + +2.6 PDP-18B + +- Fixed DT, RF variable size interaction with restore. +- Fixed MT bug in MTTR. + +2.7 PDP-8 + +- Fixed DT, DF, RF, RX variable size interaction with restore. +- Fixed MT bug in SKTR. + +2.8 HP2100 + +- Fixed bug in DP (13210A controller only), DQ read status. +- Fixed bug in DP, DQ seek complete. + +2.9 GRI + +- Fixed bug in SC queue pointer management. + +3. New Features in 3.0 vs prior releases + +N/A + +4. Bugs Fixed in 3.0 vs prior releases + +N/A + +5. General Notes + +WARNING: The RESTORE command has changed. RESTORE will now +detach an attached file on a unit, if that unit did not have +an attached file in the saved configuration. This is required +to assure that the unit flags and the file state are consistent. + +WARNING: The compilation scheme for the PDP-10, PDP-11, and VAX +has changed. Use one of the supplied build files, or read the +documentation carefully, before compiling any of these simulators. diff --git a/0readme_ethernet.txt b/0readme_ethernet.txt index 9fc56ea2..938fcf71 100644 --- a/0readme_ethernet.txt +++ b/0readme_ethernet.txt @@ -2,6 +2,147 @@ This file contains information about the XQ/SIM_ETHER package. ------------------------------------------------------------------------------- +The XQ emulator is a host-independant software emulation of Digital's +DELQA (M7516) and DEQNA (M7504) Q-bus ethernet cards for the SIMH emulator. + +The XQ emulator uses the Sim_Ether module to execute host-specific ethernet +packet reads and writes, since all operating systems talk to real ethernet +cards/controllers differently. The host-dependant Sim_Ether module currently +supports Windows, Linux, NetBSD, and OpenBSD. + +Currently, the Sim_Ether module sets the selected ethernet card into +promiscuous mode to gather all packets, then filters out the packets that it +doesn't want. In Windows, packets having the same source MAC address as the +controller are ignored for WinPCAP compatibility (see Windows notes below). + +If your ethernet card is plugged into a switch, the promiscuous mode setting +should not cause much of a problem, since the switch will still filter out +most of the undesirable traffic. You will only see "excessive" traffic if you +are on a direct or hub(repeater) segment. + +------------------------------------------------------------------------------- + +Windows notes: + 1. The Windows-specific code uses the WinPCAP 3.0 package from + http://winpcap.polito.it. This package for windows simulates the libpcap + package that is freely available for unix systems. + 2. You must *install* the WinPCAP runtime package. + 3. The first time the WinPCAP driver is used, it will be dynamically loaded, + and the user must be an Administrator on the machine to do so. If you need + to run as an unprivileged user, you must set the service to autostart. See + the WinPCAP documentation for details on the static load workaround. + 4. WinPCAP loops packet writes back into the read queue. This causes problems + since the XQ controller is not expecting to read it's own packet. A fix + to the packet read filter was added to reject packets from the current MAC, + but this defeats DECNET's duplicate node number detection scheme. A more + correct fix for WinPCAP will be explored as time allows. + +Building on Windows: + 1. Install WinPCAP 3.0. + 2. Put the required .h files (bittypes,devioctl,ip6_misc,packet32,pcap, + pcap-stdinc).h from the WinPCAP 3.0 developer's kit in the compiler's path + 3. Put the required .lib files (packet,wpcap).lib from the WinPCAP 3.0 + developer's kit in the linker's path + 4. If you're using Borland C++, use COFF2OMF to convert the .lib files into + a format that can be used by the compiler. + 5. Define USE_NETWORK if you want the network functionality. + 6. Build it! + +------------------------------------------------------------------------------- + +Linux, NetBSD, and OpenBSD notes: + 1. You must run SIMH(scp) as root so that the ethernet card can be set into + promiscuous mode by the driver. Alternative methods for avoiding the + 'run as root' requirement will be welcomed. + +Building on Linux, NetBSD, and OpenBSD: + 1. Get/install the libpcap package for your unix version. http://rpmfind.net + might be a useful site for finding the linux variants. + 2. Use Make USE_NETWORK=1 if you want the network functionality. + 3. Build it! + +------------------------------------------------------------------------------- + +VAX simulator support: + +An OpenVMS VAX v7.2 system with DECNET Phase IV, MultiNet 4.4a, and LAT 5.3 has +been successfully run. Other testers have reported success booting NetBSD also. + + +PDP11 simulator support: + +An RT-11 v5.3 system with a freeware TCP/IP stack has been successfully run. +Other testers have reported that RSX with DECNET and the NetBSD operating +systems also work. RSTS/E v10.1 has preliminary support - RSTS/E boots and +enables the XH (XQ) device - DECNET and LAT software have not been tested. + +------------------------------------------------------------------------------- + +Things planned for future releases: + 1. PDP-11 bootstrap/bootrom + 2. Full MOP implementation + 3. DESQA support (if someone can get me the user manuals) + 4. DETQA support [DELQA-Turbo] (I have the manual) + 5. DEUNA/DELUA support + +------------------------------------------------------------------------------- + +Things which I need help with: + 1. Porting Sim_Ether packet driver to other host platforms, especially VMS. + 2. Information about Remote MOP processing + 3. VAX/PDP-11 hardware diagnotics image files and docs, to test XQ thoroughly. + 4. Feedback on operation with other VAX/PDP-11 OS's. + +------------------------------------------------------------------------------- + +Please send all patches, questions, feedback, clarifications, and help to: + dhittner AT northropgrumman DOT com + +Thanks, and Enjoy!! +Dave + + +=============================================================================== + Change Log +=============================================================================== + +05-Jun-03 Release: + 1. Added SET/SHOW XQ STATS + 2. Added SHOW XQ FILTERS + 3. Added ability to split received packet into multiple buffers + 4. Added explicit runt & giant packet processing + +------------------------------------------------------------------------------- + +30-May-03 Release: + 1. Corrected bug in xq_setmac introduced in v3.0 (multiple people) + 2. Made XQ receive buffer allocation dynamic to reduce scp executable size + 3. Optimized some structs, removed legacy variables (Mark Pizzolato) + 4. Changed #ifdef WIN32 to _WIN32 for consistancy + +------------------------------------------------------------------------------- + +06-May-03 Release: + 1. Added second XQ controller + 2. Added SIMH v3.0 compatibility + 3. Removed SET ADDRESS functionality + +------------------------------------------------------------------------------- + +10-Apr-03 Release: + 1. Added preliminary support for RSTS/E + 2. Added PDP-11 bootrom load via CSR flags + 3. Support for SPARC linux (thanks to Mark Pizzolato) + +------------------------------------------------------------------------------- + +11-Mar-03 Release: + 1. Added support for RT-11 TCP/IP + 2. Corrected interrupts (thanks to Tom Evans and Bob Supnik) + 3. Moved change log to the bottom of the readme file, cleaned up document + +------------------------------------------------------------------------------- + 16-Jan-03 Release: 1. Added VMScluster support (thanks to Mark Pizzolato) 2. Verified VAX remote boot functionality (>>>B XQA0) @@ -12,176 +153,10 @@ This file contains information about the XQ/SIM_ETHER package. ------------------------------------------------------------------------------- -GOLD Changes: (08-Nov-02) +08-Nov-02 Release: 1. Added USE_NETWORK conditional to Sim_Ether 2. Fixed behaviour of SHOW XQ ETH if no devices exist 3. Added OpenBSD support to Sim_Ether (courtesy of Federico Schwindt) 4. Added ethX detection simplification (from Megan Gentry) -------------------------------------------------------------------------------- - -BETA 5 Changes: (23-Oct-02) - 1. Added all_multicast and promiscuous mode support - 2. Finished DEQNA emulation - 3. Verified LAT functionality - 4. Added NXM (Non-eXistant Memory) protection (suggested by Robert Supnik) - 5. Added NetBSD support to Sim_Ether (courtesy of Jason Thorpe) - 6. Fixed write buffer overflow bug (discovered by Jason Thorpe) - 7. Fixed unattached device behavior (discovered by Patrick Caulfield) - 8. Extensive rewrite of this README - 9. Debugged sanity timer - -------------------------------------------------------------------------------- - -BETA 4 Changes: (16-Oct-02) - 1. Added stub support for all_multicast and promiscuous modes - 2. Integrated with SIMH v2.10-0b1 - 3. Added VAX network bootstrap support - 4. Added SET/SHOW XQ TYPE and SANITY commands - 5. Added stub support for DEQNA mode - -------------------------------------------------------------------------------- - -BETA 3 Changes: (10-Oct-02) - 1. Fixed off-by-one bug in setup address processing - 2. Added rejection of multicast addresses to SET XQ MAC - 3. Added linux support to Sim_Ether (courtesy of Patrick Caulfield) - -------------------------------------------------------------------------------- - -BETA 2 Changes: (08-Oct-02) - 1. Integrated with SIMH v2.10-0p4 - 2. Added floating vectors; this also fixes pdp11 emulation problem - 3. Cleaned up codebase; 100% of packet driver code moved to Sim_Ether - 4. Verified TCP/IP functionality - 5. Added Copyrights - -------------------------------------------------------------------------------- - -BETA 1 Changes: (03-Oct-02) - 1. Moved most of packet driver functionality from XQ to Sim_Ether - 2. Verified DECNET functionality - 3. Added SET/SHOW MAC command - 4. Added SHOW ETH command - -------------------------------------------------------------------------------- - -The XQ emulator is a host-independant software emulation of Digital's -DELQA (M7516) and DEQNA (M7504) Q-bus ethernet cards for the SIMH emulator. - -See the last section of this document for XQ usage instructions. - -The XQ emulator uses the Sim_Ether module to execute host-specific ethernet -packet reads and writes, since all operating systems talk to real ethernet -cards/controllers differently. The host-dependant Sim_Ether module currently -supports Windows, Linux, and NetBSD. - -Currently, the Sim_Ether module sets the selected ethernet card into -promiscuous mode to gather all packets, then filters out the packets that it -doesn't want. In Windows, Packets having the same source MAC address as the -controller are ignored for WinPCAP compatibility (see Windows notes below). - -If your ethernet card is plugged into a switch, the promiscuous mode setting -should not cause much of a problem, since the switch will still filter out -most of the undesirable traffic. You will only see "excessive" traffic if you -are on a direct or hub(repeater) segment. - -------------------------------------------------------------------------------- - -Windows notes: - 1. The Windows-specific code uses the WinPCAP 3.0 (or 2.3) package from - http://winpcap.polito.it. This package for windows simulates the libpcap - package that is freely available for unix systems. - 2. You must *install* WinPCAP. - 3. Note that WinPCAP DOES NOT support dual CPU environments. - 4. WinPCAP loops packet writes back into the read queue. This causes problems - since the XQ controller is not expecting to read it's own packet. A fix - to the packet read filter was added to reject packets from the current MAC, - but this defeats DECNET's duplicate node number detection scheme. A more - correct fix for WinPCAP will be explored as time allows. - 5. The first time the WinPCAP driver is used, it will be dynamically loaded, - and the user must be an Administrator on the machine to do so. If you need - to run as an unprivileged user, you must set the service to autostart. See - the WinPCAP documentation for details on the static load workaround. - -Building on Windows: - 1. Install WinPCAP 3.0. - 2. Get the required .h files (bittypes.h, devioctl.h, ip6_misc.h, packet32.h, - pcap.h, pcap-stdinc.h) from the WinPCAP 3.0 developer's kit - 3. Get the required .lib files (packet.lib, wpcap.lib) from the WinPCAP 3.0 - developer's kit. If you're using Borland C++, use COFF2OMF to convert - the .lib files into a format that can be used by the compiler. - 4. Define USE_NETWORK if you want the network functionality. - 5. Build it! - -------------------------------------------------------------------------------- - -Linux, NetBSD, and OpenBSD notes: - - 1. You must run SIMH(scp) as root so that the ethernet card can be set into - promiscuous mode by the driver. Alternative suggestions will be welcomed. - -Building on Linux, NetBSD, and OpenBSD: - 1. Define USE_NETWORK if you want the network functionality. - -------------------------------------------------------------------------------- - -THE XQ/SIM_ETHER modules have been successfully tested on a Windows 2000 host, -emulating an OpenVMS 7.2 VAX system with DECNET Phase IV, MultiNet 4.4a, and -LAT 5.3. - -Regression test criteria: - 1. VAX shows device correctly (passed) - 2. VMS boots successfully with new device emulation (passed) - 3. VMS initializes device correctly (passed) - 4. DECNET loads successfully (passed) - 5. DECNET line stays up (passed) - 6. SET HOST x.y:: works from SIMH to real DECNET machine (passed) - 7. SET HOST x.y:: works from real DECNET machine to SIMH (passed) - 8. DECNET copy works from SIMH to real DECNET machine (passed) - 9. DECNET copy works from real DECNET machine to SIMH (passed) -10. MultiNet TCP/IP loads successfully (passed) -11. Multinet TCP/IP initializes device successfully (passed) -12. SET HOST/TELNET x.y.z.w works from SIMH to real VAX IP machine (passed) -13. SET HOST/TELNET x.y.z.w works from real VAX IP machine to SIMH (passed) -14. FTP GET from a real VAX IP machine (passed) -15. LAT loads sucessfully (passed) -16. SET HOST/LAT works from SIMH to real VAX LAT machine (passed) -17. SET HOST/LAT works from real VAX LAT machine to SIMH (passed) -18. SIMH node joins VMSCluster (passed) -19. SIMH node mounts other VMSCluster disks (passed) -20. SIMH node MSCP serves disks to other nodes (passed) -21. SIMH node remote boots into VMScluster (>>>B XQAO) (passed) - -The following are known to NOT work: - 1. PDP-11 using RSTS/E v10.1 (fails to enable device - needs bootrom support) - -I have reports that the following work: - 1. PDP-11 using RSX - 2. VAX remote booting of NetBSD (via >>> B XQA0) - -------------------------------------------------------------------------------- - -Things planned for future releases: - 1. Full MOP implementation - 2. PDP-11 bootstrap/bootrom - 3. DESQA support (if someone can get me the user manuals) - 4. DETQA support [DELQA-Turbo] (I have the manual) - -------------------------------------------------------------------------------- - -Things which I need help with: - 1. Porting Sim_Ether packet driver to other platforms, especially VMS. - 2. Information about Remote MOP processing - 3. PDP-11 bootstrap code. - 4. VAX hardware diagnotics image file and docs, to test XQ thoroughly. - 5. Feedback on operation with other VAX OS's. - 6. Feedback on operation with PDP-11 OS's. - -------------------------------------------------------------------------------- - -Please send all patches, questions, feedback, clarifications, and help to: - dhittner AT northropgrumman DOT com - -Thanks, and Enjoy!! -Dave +=============================================================================== diff --git a/ALTAIR/altair_cpu.c b/ALTAIR/altair_cpu.c index fc7f0475..1977d0e2 100644 --- a/ALTAIR/altair_cpu.c +++ b/ALTAIR/altair_cpu.c @@ -1,6 +1,6 @@ /* altair_cpu.c: MITS Altair Intel 8080 CPU simulator - Copyright (c) 1997, Charles E. Owen + Copyright (c) 1997-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -58,7 +58,7 @@ HALT instruction I/O error in I/O simulator - Invalid OP code (If ITRAP is set on CPU) + Invalid OP code (if ITRAP is set on CPU) 2. Interrupts. There are 8 possible levels of interrupt, and in effect they @@ -82,14 +82,14 @@ #include "altair_defs.h" #define UNIT_V_OPSTOP (UNIT_V_UF) /* Stop on Invalid OP? */ -#define UNIT_OPSTOP (1 << UNIT_V_OPSTOP) -#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 */ -#define UNIT_CHIP (1 << UNIT_V_CHIP) -#define UNIT_V_MSIZE (UNIT_V_UF+2) /* Memory Size */ -#define UNIT_MSIZE (1 << UNIT_V_MSIZE) +#define UNIT_OPSTOP (1 << UNIT_V_OPSTOP) +#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 */ +#define UNIT_CHIP (1 << UNIT_V_CHIP) +#define UNIT_V_MSIZE (UNIT_V_UF+2) /* Memory Size */ +#define UNIT_MSIZE (1 << UNIT_V_MSIZE) -unsigned char M[MAXMEMSIZE]; /* memory */ -int32 A = 0; /* accumulator */ +unsigned char M[MAXMEMSIZE]; /* memory */ +int32 A = 0; /* accumulator */ int32 BC = 0; /* BC register pair */ int32 DE = 0; /* DE register pair */ int32 HL = 0; /* HL register pair */ @@ -1168,7 +1168,7 @@ t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) return SCPE_ARG; diff --git a/ALTAIR/altair_defs.h b/ALTAIR/altair_defs.h index 7c43d563..5786247e 100644 --- a/ALTAIR/altair_defs.h +++ b/ALTAIR/altair_defs.h @@ -1,6 +1,6 @@ /* altair_defs.h: MITS Altair simulator definitions - Copyright (c) 1997, Charles E. Owen + Copyright (c) 1997-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -31,12 +31,12 @@ #define MAXMEMSIZE 65536 /* max memory size */ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ #define ADDRMASK (MAXMEMSIZE - 1) /* address mask */ -#define MEM_ADDR_OK(x) (x < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) /* Simulator stop codes */ #define STOP_RSRV 1 /* must be 1 */ -#define STOP_HALT 2 /* HALT */ +#define STOP_HALT 2 /* HALT */ #define STOP_IBKPT 3 /* breakpoint */ -#define STOP_OPCODE 4 +#define STOP_OPCODE 4 diff --git a/ALTAIR/altair_dsk.c b/ALTAIR/altair_dsk.c index 57008803..5ae54cf5 100644 --- a/ALTAIR/altair_dsk.c +++ b/ALTAIR/altair_dsk.c @@ -1,6 +1,6 @@ /* altair_dsk.c: MITS Altair 88-DISK Simulator - Copyright (c) 1997, Charles E. Owen + Copyright (c) 1997-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -124,8 +124,6 @@ t_stat dsk_svc (UNIT *uptr); t_stat dsk_reset (DEVICE *dptr); void writebuf(); -extern int32 sim_activate (UNIT *uptr, int32 interval); -extern int32 sim_cancel (UNIT *uptr); extern int32 PCX; /* Global data on status */ diff --git a/ALTAIR/altair_sio.c b/ALTAIR/altair_sio.c index aa2c45a0..9c212160 100644 --- a/ALTAIR/altair_sio.c +++ b/ALTAIR/altair_sio.c @@ -1,6 +1,6 @@ /* altair_sio: MITS Altair serial I/O card - Copyright (c) 1997, Charles E. Owen + Copyright (c) 1997-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -63,11 +63,6 @@ t_stat ptp_reset (DEVICE *dptr); int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */ -extern t_stat sim_activate (UNIT *uptr, int32 interval); -extern t_stat sim_cancel (UNIT *uptr); -extern t_stat sim_poll_kbd (void); -extern t_stat sim_putchar (int32 out); - /* 2SIO Standard I/O Data Structures */ UNIT sio_unit = { UDATA (&sio_svc, 0, 0), @@ -95,7 +90,7 @@ UNIT ptr_unit = { UDATA (&ptr_svc, UNIT_SEQ + UNIT_ATTABLE, 0), REG ptr_reg[] = { { ORDATA (DATA, ptr_unit.buf, 8) }, { ORDATA (STAT, ptr_unit.u3, 8) }, - { ORDATA (POS, ptr_unit.pos, 32) }, + { ORDATA (POS, ptr_unit.pos, T_ADDR_W) }, { NULL } }; DEVICE ptr_dev = { @@ -110,7 +105,7 @@ UNIT ptp_unit = { UDATA (&ptp_svc, UNIT_SEQ + UNIT_ATTABLE, 0), REG ptp_reg[] = { { ORDATA (DATA, ptp_unit.buf, 8) }, { ORDATA (STAT, ptp_unit.u3, 8) }, - { ORDATA (POS, ptp_unit.pos, 32) }, + { ORDATA (POS, ptp_unit.pos, T_ADDR_W) }, { NULL } }; DEVICE ptp_dev = { diff --git a/ALTAIR/altair_sys.c b/ALTAIR/altair_sys.c index 94d4926a..cf558d41 100644 --- a/ALTAIR/altair_sys.c +++ b/ALTAIR/altair_sys.c @@ -1,6 +1,6 @@ /* altair_sys.c: MITS Altair system interface - Copyright (c) 1997, Charles E. Owen + Copyright (c) 1997-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -37,9 +37,6 @@ extern DEVICE ptp_dev; extern DEVICE lpt_dev; extern unsigned char M[]; extern int32 saved_PC; -extern char *get_glyph (char *cptr, char *gbuf, char term); -extern unsigned int32 get_uint (char *cptr, int32 radix, unsigned int32 max, - int32 *status); /* SCP data structures diff --git a/AltairZ80/altairZ80.txt b/AltairZ80/altairZ80.txt index 7705451b..48f83a1e 100644 --- a/AltairZ80/altairZ80.txt +++ b/AltairZ80/altairZ80.txt @@ -3,31 +3,34 @@ Altair 8800 Simulator with Z80 support 0. Revision History -Original version of this document written by Charles E Owen -- 9-Oct-2002, Peter Schorn (added support for simulated hard disk) +- 25-Feb-2003, Peter Schorn (added support for real time simulation) +- 9-Oct-2002, Peter Schorn (added support for simulated hard disk) - 28-Sep-2002, Peter Schorn (number of tracks per disk can be configured) - 19-Sep-2002, Peter Schorn (added WARNROM feature) -- 31-Aug-2002, Peter Schorn (added extended ROM features suggested by Scott LaBombard) -- 4-May-2002, Peter Schorn (added description of MP/M II sample software) +- 31-Aug-2002, Peter Schorn (added extended ROM features suggested + by Scott LaBombard) +- 4-May-2002, Peter Schorn (added description of MP/M II sample software) - 28-Apr-2002, Peter Schorn (added periodic timer interrupts and three - additional consoles) + additional consoles) - 15-Apr-2002, Peter Schorn (added memory breakpoint) -- 7-Apr-2002, Peter Schorn (added ROM / NOROM switch) +- 7-Apr-2002, Peter Schorn (added ROM / NOROM switch) +Original version of this document written by Charles E Owen 1. Background. - The MITS (Micro Instrumentation and Telemetry Systems) Altair 8800 -was announced on the January 1975 cover of Popular Electronics, which -boasted you could buy and build this powerful computer kit for only $397. -The kit consisted at that time of only the parts to build a case, power -supply, card cage (18 slots), CPU card, and memory card with 256 *bytes* of -memory. Still, thousands were ordered within the first few months after the -announcement, starting the personal computer revolution as we know it today. + The MITS (Micro Instrumentation and Telemetry Systems) Altair 8800 was +announced on the January 1975 cover of Popular Electronics, which boasted +you could buy and build this powerful computer kit for only $397. The kit +consisted at that time of only the parts to build a case, power supply, +card cage (18 slots), CPU card, and memory card with 256 *bytes* of memory. +Still, thousands were ordered within the first few months after the +announcement, starting the personal computer revolution as we know it +today. - Many laugh at the small size of the that first kit, noting there -were no peripherals and the 256 byte memory size. But the computer was an -open system, and by 1977 MITS and many other small startups had added many + Many laugh at the small size of the that first kit, noting there were no +peripherals and the 256 byte memory size. But the computer was an open +system, and by 1977 MITS and many other small startups had added many expansion cards to make the Altair quite a respectable little computer. The "Altair Bus" that made this possible was soon called the S-100 Bus, later adopted as an industry standard, and eventually became the IEE-696 Bus. @@ -35,8 +38,8 @@ adopted as an industry standard, and eventually became the IEE-696 Bus. 2. Hardware - We are simulating a fairly "loaded" Altair 8800 from about 1977, -with the following configuration: + We are simulating a fairly "loaded" Altair 8800 from about 1977, with the +following configuration: device simulates name(s) @@ -52,13 +55,13 @@ with the following configuration: DSK MITS 88-DISK Floppy Disk controller with up to eight drives. + 2.1 CPU - We have 2 CPU options that were not present on the original -machine but are useful in the simulator. We also allow you to select -memory sizes, but be aware that some sample software requires the full -64K (i.e. CP/M) and the MITS Disk Basic and Altair DOS require about -a minimum of 24K. + We have 2 CPU options that were not present on the original machine but +are useful in the simulator. We also allow you to select memory sizes, but +be aware that some sample software requires the full 64K (i.e. CP/M) and +the MITS Disk Basic and Altair DOS require about a minimum of 24K. SET CPU 8080 Simulates the 8080 CPU (normal) SET CPU Z80 Simulates the Z80 CPU. Note that some software (e.g. most @@ -76,10 +79,8 @@ a minimum of 24K. SET CPU 8K SET CPU 12K SET CPU 16K - ...... + ...... (in 4K steps) SET CPU 64K All these set various CPU memory configurations. - The 2K EPROM at the high end of memory is always - present and will always boot. SET CPU BANKED Enables the banked memory support. The simulated memory has eight banks with address range 0..'common' (see registers below) @@ -110,15 +111,16 @@ a minimum of 24K. some software tries on purpose to write to ROM in order to detect the available RAM. -The BOOT EPROM card starts at address 0FF00 if it has been enabled by 'SET -CPU ALTAIRROM'. Jumping to this address will boot drive 0 of the floppy -controller (CPU must be set to ROM or equivalent code must be present). If -no valid bootable software is present there the machine crashes. This is -historically accurate behavior. + The BOOT EPROM card starts at address 0FF00 if it has been enabled by +'SET CPU ALTAIRROM'. Jumping to this address will boot drive 0 of the +floppy controller (CPU must be set to ROM or equivalent code must be +present). If no valid bootable software is present there the machine +crashes. This is historically accurate behavior. -The real 8080, on receiving a HLT (Halt) instruction, freezes the processor -and only an interrupt or CPU hardware reset will restore it. The simulator -is alot nicer, it will halt but send you back to the simulator command line. + The real 8080, on receiving a HLT (Halt) instruction, freezes the +processor and only an interrupt or CPU hardware reset will restore it. The +simulator is alot nicer, it will halt but send you back to the simulator +command line. CPU Registers include the following: @@ -135,20 +137,20 @@ CPU Registers include the following: - = not used (undefined) N = Internal sign flag C = Carry flag. - BC 16 The BC register pair. Register B is the high 8 bits, - C is the lower 8 bits - DE 16 The DE register pair. Register D is the high 8 bits, - E is the lower 8 bits. - HL 16 The HL register pair. Register H is the high 8 bits, - L is the lower 8 bits. - AF1 16 The alternate AF register (only on Z80) - BC1 16 The alternate BC register (only on Z80) - DE1 16 The alternate DE register (only on Z80) - HL1 16 The alternate HL register (only on Z80) - IX 16 The IX index register (only on Z80) - IY 16 The IY index register (only on Z80) - IFF 8 Interrupt flag (only on Z80, no effect) - INT 8 Interrupt register (only on Z80, no effect) + BC 16 The BC register pair. + Register B is the high 8 bits, C is the lower 8 bits + DE 16 The DE register pair. + Register D is the high 8 bits, E is the lower 8 bits. + HL 16 The HL register pair. + Register H is the high 8 bits, L is the lower 8 bits. + AF1 16 The alternate AF register (on Z80 only) + BC1 16 The alternate BC register (on Z80 only) + DE1 16 The alternate DE register (on Z80 only) + HL1 16 The alternate HL register (on Z80 only) + IX 16 The IX index register (on Z80 only) + IY 16 The IY index register (on Z80 only) + IFF 8 Interrupt flag (on Z80 only) + INT 8 Interrupt register (on Z80 only) SR 16 The front panel switches (use D SR 8 for 4k Basic). WRU 8 The interrupt character. This starts as 5 @@ -163,19 +165,24 @@ CPU Registers include the following: value supplied to GENCPM for CP/M 3 system generation) ROMLOW 16 The starting address of the ROM. Default is 0FF00. ROMHIGH 16 The final address of the ROM. Default is 0FFFF. + CLOCK 32 The clock speed of the simulated CPU in kHz or 0 to run + at maximum speed. To set the clock speed for a typical + 4 MHz Z80 CPU, use D CLOCK 4000. The CP/M utility SPEED + measures the clock speed of the simulated CPU. + 2.2 The Serial I/O Card (2SIO) - This simple programmed I/O device provides 2 serial ports to the -outside world, which could be hardware jumpered to support RS-232 plugs or a -TTY current loop interface. The standard I/O addresses assigned by MITS -was 10-11 (hex) for the first port, and 12-13 (hex) for the second. -We follow this standard in the Simulator. + This simple programmed I/O device provides 2 serial ports to the outside +world, which could be hardware jumpered to support RS-232 plugs or a TTY +current loop interface. The standard I/O addresses assigned by MITS was +10-11 (hex) for the first port, and 12-13 (hex) for the second. We follow +this standard in the Simulator. The simulator directs I/O to/from the first port to the screen. The -second port reads from an attachable "tape reader" file on input, and writes -to an attachable "punch file" on output. These files are considered a -simple stream of 8-bit bytes. +second port reads from an attachable "tape reader" file on input, and +writes to an attachable "punch file" on output. These files are considered +a simple stream of 8-bit bytes. The SIO can be configured in SIMH with the following commands: @@ -199,11 +206,13 @@ simple stream of 8-bit bytes. ATTACH SIO 23 Console IO goes via a Telnet connection on port 23 DETACH SIO Console IO goes via the regular SIMH console + 2.3 The SIMH pseudo device - The SIMH pseudo device facilitates the communication between the simulated -ALTAIR and the simulator environment. This device defines a number of (most R/O) -registers (see source code) which are primarily useful for debugging purposes. + The SIMH pseudo device facilitates the communication between the +simulated ALTAIR and the simulator environment. This device defines a +number of (most R/O) registers (see source code) which are primarily useful +for debugging purposes. The SIMH pseudo device can be configured with @@ -220,23 +229,23 @@ registers (see source code) which are primarily useful for debugging purposes. TIMH This is the address of the interrupt handler to call for a timer interrupt. + 2.4 The 88-DISK controller. - The MITS 88-DISK is a simple programmed I/O interface to the MITS -8-inch floppy drive, which was basically a Pertec FD-400 with a power -supply and buffer board builtin. The controller supports neither interrupts -nor DMA, so floppy access required the sustained attention of the CPU. -The standard I/O addresses were 8, 9, and 0A (hex), and we follow the -standard. Details on controlling this hardware are in the altair_dsk.c -source file. + The MITS 88-DISK is a simple programmed I/O interface to the MITS 8-inch +floppy drive, which was basically a Pertec FD-400 with a power supply and +buffer board builtin. The controller supports neither interrupts nor DMA, +so floppy access required the sustained attention of the CPU. The standard +I/O addresses were 8, 9, and 0A (hex), and we follow the standard. Details +on controlling this hardware are in the altair_dsk.c source file. The only difference is that the simulated disks may be larger than the original ones: The original disk had 77 tracks while the simulated disks support up to 254 tracks (only relevant for CP/M). You can change the number of tracks per disk by setting the appropriate value in TRACKS[..]. -For example "D TRACKS[0] 77" sets the number of tracks for disk 0 to -the original number of 77. The command "D TRACKS[0-7] 77" changes the -highest track number for all disks to 77. +For example "D TRACKS[0] 77" sets the number of tracks for disk 0 to the +original number of 77. The command "D TRACKS[0-7] 77" changes the highest +track number for all disks to 77. For debugging purposes you can set the trace level of some disk I/O functions. To do so the following bits in TRACE (a register of the disk) @@ -287,43 +296,46 @@ command "D HDTRACE 1". The default for "HDTRACE" is 0 (no trace). 3. Sample Software - Running an Altair in 1977 you would be running either MITS Disk -Extended BASIC, or the brand new and sexy CP/M Operating System from Digital + Running an Altair in 1977 you would be running either MITS Disk Extended +BASIC, or the brand new and sexy CP/M Operating System from Digital Research. Or possibly, you ordered Altair DOS back when it was promised in 1975, and are still waiting for it to be delivered in early 1977. - We have samples of all three for you to check out. We can't go into -the details of how they work, but we'll give you a few hints. + We have samples of all three for you to check out. We can't go into the +details of how they work, but we'll give you a few hints. 3.1 CP/M Version 2.2 - This version is my own port of the standard CP/M to the Altair. -There were some "official" versions but I don't have them. None were -endorsed or sold by MITS to my knowledge, however. + This version is my own port of the standard CP/M to the Altair. There +were some "official" versions but I don't have them. None were endorsed or +sold by MITS to my knowledge, however. + To boot CP/M: sim> attach dsk cpm2.dsk sim> boot dsk - CP/M feels like DOS, sort of. DIR will work. I have included all -the standard CP/M utilities, plus a few common public-domain ones. I also + CP/M feels like DOS, sort of. DIR will work. I have included all the +standard CP/M utilities, plus a few common public-domain ones. I also include the sources to the customized BIOS and some other small programs. -TYPE will print an ASCII file. DUMP will dump a binary one. LS is a better -DIR than DIR. ASM will assemble .ASM files to Hex, LOAD will "load" them to -binary format (.COM). ED is a simple editor, #A command will bring the -source file to the buffer, T command will "type" lines, L will move lines, -E exits the editor. 20L20T will move down 20 lines, and type 20. Very -DECish. DDT is the debugger, DO is a batch-type command processor. -A sample batch file that will assemble and write out the bootable CP/M -image (on drive A) is "SYSCPM2.SUB". To run it, type "DO SYSCPM2". +TYPE will print an ASCII file. DUMP will dump a binary one. LS is a +better DIR than DIR. ASM will assemble .ASM files to Hex, LOAD will "load" +them to binary format (.COM). ED is a simple editor, #A command will bring +the source file to the buffer, T command will "type" lines, L will move +lines, E exits the editor. 20L20T will move down 20 lines, and type 20. +Very DECish. DDT is the debugger, DO is a batch-type command processor. A +sample batch file that will assemble and write out the bootable CP/M image +(on drive A) is "SYSCPM2.SUB". To run it, type "DO SYSCPM2". In order to efficiently transfer files into the CP/M environment use the -included program R . If you have a file named foo.ext in -the current directory (i.e. the directory where SIMH is), executing -R FOO.EXT under CP/M will transfer the file onto the CP/M disk. -Transferring a file from the CP/M environment to the SIMH environment is -accomplished by W . +included program R . If you have a file named foo.ext in the +current directory (i.e. the directory where SIMH is), executing R FOO.EXT +under CP/M will transfer the file onto the CP/M disk. Transferring a file +from the CP/M environment to the SIMH environment is accomplished by +W for text files or by W B for binary files. +The simplest way for transferring multiple files is to create a ".SUB" +batch file which contains the necessary R resp. W commands. If you need more storage space you can use a simulated hard disk on drives I: and J:. To use do "attach HDSK0 hdi.dsk" and issue the @@ -341,6 +353,8 @@ CBIOSX .MAC 48K ; CP/M 2 BIOS source for Altair CCP .MAC 26K ; Console Command Processor assembler source code COPY .COM 2K ; copy disks CPMBOOT .COM 12K ; CP/M operating system +CPU .COM 2K ; get and set the CPU type (8080 or Z80) +CPU .MAC 2K ; source for CPU.COM CREF80 .COM 4K ; cross reference utility DDT .COM 6K ; 8080 debugger DDTZ .COM 10K ; Z80 debugger @@ -349,13 +363,12 @@ DO .COM 2K ; batch processing DSKBOOT .MAC 8K ; source for boot ROM DUMP .COM 2K ; hex dump a file ED .COM 8K ; line editor -ELIZA .BAS 10K ; Elisa game in Basic -EX8080 .COM 10K ; exercise 8080 instruction set -EX8080 .MAC 48K ; source for EX8080.COM -EX8080 .SUB 2K ; benchmark execution of EX8080.COM -EXZ80 .COM 10K ; exercise Z80 instruction set -EXZ80 .MAC 48K ; source for EXZ80.COM -EXZ80 .SUB 2K ; benchmark execution of EXZ80.COM +ELIZA .BAS 10K ; Eliza game in Basic +EX8080 .COM 12K ; exercise 8080 instruction set +EXZ80N .COM 12K ; exercise Z80 instruction set, No undefined status bits +EXZ80U .COM 12K ; exercise Z80 instruction set, Undefined status bits +EXZ80 .MAC 54K ; source for EX8080.COM, EXZ80N.COM, EXZ80U.COM +EX .SUB 2K ; benchmark execution of EX8080.COM, EXZ80N.COM, EXZ80U.COM FORMAT .COM 2K ; format disks GO .COM 0K ; start the currently loaded program at 100H HDSKBOOT.MAC 6K ; boot code for hard disk @@ -375,18 +388,21 @@ MEMCFG .LIB 2K ; defines the memory configuration MOVER .MAC 2K ; moves operating system in place OTHELLO .COM 12K ; Othello (Reversi) game PIP .COM 8K ; Peripheral Interchange Program +PRELIM .COM 2K ; preliminary CPU tests +PRELIM .MAC 6K ; source code for PRELIM.COM R .COM 4K ; read files from SIMH environment RSETSIMH.COM 2K ; reset SIMH interface RSETSIMH.MAC 2K ; assembler source for RSETSIMH.COM SHOWSEC .COM 3K ; show sectors on a disk SID .COM 8K ; debugger for 8080 +SPEED .COM 2K ; utility to measure the clock speed of the simulated CPU STAT .COM 6K ; provide information about currently logged disks SURVEY .COM 2K ; system survey SURVEY .MAC 16K ; assembler source for SURVEY.COM SYSCOPY .COM 2K ; copy system tracks between disks SYSCPM2 .SUB 2K ; create CP/M 2 on drive A: TIMER .COM 2K ; perform various timer operations -TIMER .MAC 2K ; source code for TIMER.COM +TIMER .MAC 2K ; source code for TIMER.COM UNCR .COM 8K ; un-crunch utility UNERA .COM 2K ; un-erase a file UNERA .MAC 16K ; source for UNERA.COM @@ -397,15 +413,17 @@ WM .HLP 3K ; help file for WM.COM WORM .COM 4K ; worm game for VT100 terminal XFORMAT .COM 2K ; initialise a drive (floppy or hard disk) XSUB .COM 2K ; support for DO.COM +ZAP .COM 10K ; SuperZap 5.2 disk editor configured for VT100 ZSID .COM 10K ; debugger for Z80 ZTRAN4 .COM 4K ; translate 8080 mnemonics into Z80 equivalents 3.2 CP/M Version 3 with banked memory - CP/M 3 is the successor to CP/M 2.2. A customised BIOS (BIOS3.MAC) -is included to facilitate modification if so desired. The defaults supplied in -GENCPM.DAT for system generation can be used. BOOTGEN.COM is used to -place the CP/M loader (LDR.COM) on the boot tracks of a disk. + + CP/M 3 is the successor to CP/M 2.2. A customised BIOS (BIOS3.MAC) is +included to facilitate modification if so desired. The defaults supplied in +GENCPM.DAT for system generation can be used. BOOTGEN.COM is used to place +the CP/M loader (LDR.COM) on the boot tracks of a disk. Running CP/M 3 with banked memory: sim> attach dsk cpm3.dsk @@ -414,9 +432,9 @@ place the CP/M loader (LDR.COM) on the boot tracks of a disk. sim> set cpu itrap sim> boot dsk -Executing "DO SYSCPM3" will re-generate the banked version of CP/M 3. -You can boot CP/M 3 with or without a Z80 CPU. The Z80 CPU is needed for -both sysgens due to the use of BOOTGEN.COM which requires it. + Executing "DO SYSCPM3" will re-generate the banked version of CP/M 3. You +can boot CP/M 3 with or without a Z80 CPU. The Z80 CPU is needed for both +sysgens due to the use of BOOTGEN.COM which requires it. The disk "cpm3.dsk" contains the following files: ASM .COM 8K ; CP/M assembler @@ -507,11 +525,10 @@ version supports four terminals available via Telnet. To boot: sim> d common b000 sim> boot dsk -Now connect a Telnet session to the simulator and type "MPM" at the "A>" -prompt. Now you can connect up to three additional terminals via Telnet -to the Altair running MP/M II. To re-generate the system perform -"DO SYSMPM" in the CP/M environment (not possible under MP/M since XSUB -is needed). + Now connect a Telnet session to the simulator and type "MPM" at the "A>" +prompt. Now you can connect up to three additional terminals via Telnet to +the Altair running MP/M II. To re-generate the system perform "DO SYSMPM" +in the CP/M environment (not possible under MP/M since XSUB is needed). The disk "mpm.dsk" contains the following files: Name Ext Size Comment @@ -595,10 +612,10 @@ XREF .COM 16K ; cross reference utility XSUB .COM 2K ; for CP/M DO -3.5 CP/M application software +3.4 CP/M application software - There is also a small collection of sample application software containing -the following items: + There is also a small collection of sample application software +containing the following items: - SPL: a Small Programming Language with a suite of sample programs - PROLOGZ: a Prolog interpreter written in SPL with sources @@ -616,16 +633,16 @@ Name Ext Size Comment BOOTGEN .COM 2K BOOTGEN .SPL 6K ; SPL source for BOOTGEN.COM C .SUB 2K ; batch file for compiling an SPL source file -CALC .PRO 4K ; Prolog demo program calculator +CALC .PRO 4K ; Prolog demo program: Calculator CC .SUB 2K ; compile an SPL source which is on the underlying file system DECLARAT. 12K ; common include file, SPL source DIF .COM 4K DIF .SPL 10K ; SPL source for DIF.COM EDIT .SPL 10K ; screen editor for PROLOGZ, SPL source -FAMILY .PRO 4K ; Prolog demo program family relations -INTEGER .PRO 2K ; Prolog demo program integer arithmetic -KNAKE .PRO 2K ; Prolog demo program logic puzzle +FAMILY .PRO 4K ; Prolog demo program: Family relations +INTEGER .PRO 2K ; Prolog demo program: Integer arithmetic +KNAKE .PRO 2K ; Prolog demo program: Logic puzzle LINKMT .COM 12K ; Pascal MT+ 5.5 linker MAIN .SPL 14K ; main module for PROLOGZ, SPL source MOVE .MAC 4K ; helper functions for PROLOGZ in assembler @@ -652,18 +669,21 @@ PROVE .SPL 16K ; backtrack theorem prover for PROLOGZ, SPL source PZCLEAN .SUB 2K ; PROLOGZ: remove all created ".rel" and ".lst" files PZLINK .SUB 2K ; PROLOGZ: create PINST, PROLOGZ and personalise the serial number -PZMAKE .SUB 2K ; compiles the sources (you can ignore any compiler - errors) -QUEEN .PRO 2K ; Prolog demo program n-queens problem +PZMAKE .SUB 2K ; PROLOGZ: compiles the sources (you can ignore + any compiler errors) +QUEEN .PRO 2K ; Prolog demo program: N-queens problem READ .COM 4K READ .SPL 10K ; SPL source for R.COM SHOWSEC .COM 4K SHOWSEC .SPL 6K ; SPL source for SHOWSEC.COM +SPEED .COM 2K ; utility to measure the clock speed of the simulated CPU +SPEED .SPL 2K ; SPL source for SPEED.COM, requires SWLIB.MAC SPL .COM 38K ; the SPL compiler itself SPL .TXT 56K ; SPL language and compiler documentation in German SPLERROR.DAT 12K ; error messages of the compiler (in German) SPLIB .REL 6K ; SPL runtime library STDIO . 2K ; include file for SPL programs +SWLIB .MAC 2K ; assembler utility routines needed by SPEED.SPL SYSCOPY .COM 2K SYSCOPY .SPL 6K ; SPL source for SYSCOPY.COM TERMBDOS.SPL 2K ; terminal interface to CP/M for PROLOGZ, SPL source @@ -674,7 +694,7 @@ XFORMAT .COM 2K XFORMAT .SPL 6K ; SPL source for XFORMAT.COM -3.6 MITS Disk Extended BASIC Version 4.1 +3.5 MITS Disk Extended BASIC Version 4.1 This was the commonly used software for serious users of the Altair computer. It is a powerful (but slow) BASIC with some extended commands to @@ -702,11 +722,11 @@ ran under. To boot: [FILES] -3.7 Altair DOS Version 1.0 +3.6 Altair DOS Version 1.0 - This was long promised but not delivered until it was almost -irrelevant. A short attempted tour will reveal it to be a dog, far inferior -to CP/M. To boot: + This was long promised but not delivered until it was almost irrelevant. +A short attempted tour will reveal it to be a dog, far inferior to CP/M. To +boot: sim> d tracks[0-7] 77 ;set to Altair settings sim> set cpu altairrom @@ -728,9 +748,10 @@ to CP/M. To boot: .[DIR 0] -3.8 Altair Basic 3.2 (4k) - In order to run the famous 4k Basic, use the following commands (the trick -is to get the Switch Register right). +3.7 Altair Basic 3.2 (4k) + + In order to run the famous 4k Basic, use the following commands (the +trick is to get the Switch Register right). sim> set cpu 8080 ;note 4k Basic will not run on a Z80 CPU sim> set sio upper ;4k Basic does not like lower case letters as input @@ -750,7 +771,7 @@ is to get the Switch Register right). OK -3.9 Altair 8k Basic +3.8 Altair 8k Basic Running 8k Basic follows the procedure for 4k Basic. sim> set cpu 8080 ;note 8k Basic will not run on a Z80 CPU @@ -774,7 +795,8 @@ is to get the Switch Register right). OK -3.10 Altair Basic 4.0 +3.9 Altair Basic 4.0 + Execute the following commands to run Altair Extended Basic: sim> set sio upper ;Extended Basic does not like lower case letters as input @@ -794,9 +816,10 @@ is to get the Switch Register right). OK -3.11 Altair Disk Extended Basic Version 300-5-C +3.10 Altair Disk Extended Basic Version 300-5-C + This version of Basic was provided by Scott LaBombard. To execute use the - following commands: +following commands: sim> d tracks[0-7] 77 ;set to Altair settings sim> at dsk extbas5.dsk @@ -818,6 +841,7 @@ is to get the Switch Register right). 4. Special simulator features + In addition to the regular SIMH features such as PC queue, breakpoints etc., this simulator supports memory access breakpoints. A memory access breakpoint is triggered when a pre-defined memory location is accessed @@ -825,10 +849,10 @@ breakpoint is triggered when a pre-defined memory location is accessed sim> break -m -Execution will stop whenever an operation accesses . Note that + Execution will stop whenever an operation accesses . Note that a memory access breakpoint is not triggered by fetching code from memory -(this is the job of regular breakpoints). This feature has been -implemented by using the typing facility of the SIMH breakpoints. +(this is the job of regular breakpoints). This feature has been implemented +by using the typing facility of the SIMH breakpoints. 5. Brief summary of all major changes to the original Altair simulator diff --git a/AltairZ80/altairZ80_cpu.c b/AltairZ80/altairZ80_cpu.c index 2bae2eff..0b119432 100644 --- a/AltairZ80/altairZ80_cpu.c +++ b/AltairZ80/altairZ80_cpu.c @@ -1,67 +1,67 @@ /* altairz80_cpu.c: MITS Altair CPU (8080 and Z80) - Copyright (c) 2002, Peter Schorn + Copyright (c) 2002-2003, Peter Schorn - 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: + 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 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 - ROBERT M SUPNIK 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. + 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 + PETER SCHORN 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. - Except as contained in this notice, the name of Peter Schorn shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Peter Schorn. + Except as contained in this notice, the name of Peter Schorn shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Peter Schorn. - Based on work by Charles E Owen (c) 1997 - Code for Z80 CPU from Frank D. Cringle ((c) 1995 under GNU license) + Based on work by Charles E Owen (c) 1997 + Code for Z80 CPU from Frank D. Cringle ((c) 1995 under GNU license) */ -#include #include "altairz80_defs.h" #define PCQ_SIZE 64 /* must be 2**n */ +#define PCQ_SIZE_LOG2 6 /* log2 of PCQ_SIZE */ #define PCQ_MASK (PCQ_SIZE - 1) #define PCQ_ENTRY(PC) pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = PC -/* Simulator stop codes */ -#define STOP_HALT 2 /* HALT */ -#define STOP_IBKPT 3 /* breakpoint (program counter) */ -#define STOP_MEM 4 /* breakpoint (memory access) */ -#define STOP_OPCODE 5 /* unknown 8080 or Z80 instruction */ +/* simulator stop codes */ +#define STOP_HALT 0 /* HALT */ +#define STOP_IBKPT 1 /* breakpoint (program counter) */ +#define STOP_MEM 2 /* breakpoint (memory access) */ +#define STOP_OPCODE 3 /* unknown 8080 or Z80 instruction */ /*-------------------------------- definitions for memory space --------------------*/ -uint8 M[MAXMEMSIZE][MAXBANKS]; /* RAM which is present */ +static uint8 M[MAXMEMSIZE][MAXBANKS]; /* RAM which is present */ /* two sets of accumulator / flags */ -uint16 af[2]; -int af_sel; +static uint16 af[2]; +static int af_sel; /* two sets of 16-bit registers */ -struct ddregs { +static struct ddregs { uint16 bc; uint16 de; uint16 hl; } regs[2]; -int regs_sel; +static int regs_sel; -uint16 ir; -uint16 ix; -uint16 iy; -uint16 sp; -uint16 pc; -uint16 IFF; +static uint16 ir; +static uint16 ix; +static uint16 iy; +static uint16 sp; +static uint16 pc; +static uint16 IFF; #define FLAG_C 1 #define FLAG_N 2 @@ -81,15 +81,17 @@ uint16 IFF; #define Setlreg(x, v) x = (((x) & 0xff00) | ((v) & 0xff)) #define Sethreg(x, v) x = (((x) & 0xff) | (((v) & 0xff) << 8)) +#define parity(x) parityTable[(x) & 0xff] /* SetPV and SetPV2 are used to provide correct parity flag semantics for the 8080 in cases where the Z80 uses the overflow flag */ -#define SetPV ((cpu_unit.flags & UNIT_CHIP) ? (((cbits >> 6) ^ (cbits >> 5)) & 4) : (parity(sum))) +#define SetPVS(s) ((cpu_unit.flags & UNIT_CHIP) ? (((cbits >> 6) ^ (cbits >> 5)) & 4) : (parity(s))) +#define SetPV (SetPVS(sum)) #define SetPV2(x) ((cpu_unit.flags & UNIT_CHIP) ? (((temp == (x)) << 2)) : (parity(temp))) /* checkCPU8080 must be invoked whenever a Z80 only instruction is executed */ #define checkCPU8080 \ - if (((cpu_unit.flags & UNIT_CHIP) == 0) && (cpu_unit.flags & UNIT_OPSTOP)) { \ + if (((cpu_unit.flags & UNIT_CHIP) == 0) && (cpu_unit.flags & UNIT_OPSTOP)) {\ reason = STOP_OPCODE; \ goto end_decode; \ } @@ -101,33 +103,13 @@ uint16 IFF; goto end_decode; \ } -static const uint8 partab[256] = { - 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, - 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, - 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, - 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, - 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, - 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, - 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, - 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, - 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, - 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, - 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, - 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, - 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, - 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, - 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, - 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, -}; - -#define parity(x) partab[(x) & 0xff] - #define POP(x) do { \ register uint32 y = RAM_pp(SP); \ x = y + (RAM_pp(SP) << 8); \ } while (0) #define JPC(cond) { \ + tStates += 10; \ if (cond) { \ PCQ_ENTRY(PC - 1); \ PC = GetWORD(PC); \ @@ -144,34 +126,28 @@ static const uint8 partab[256] = { PUSH(PC + 2); \ PCQ_ENTRY(PC - 1); \ PC = adrr; \ + tStates += 17; \ } \ else { \ sim_brk_pend = FALSE; \ PC += 2; \ + tStates += 10; \ } \ } -int32 saved_PC = 0; /* program counter */ -int32 SR = 0; /* switch register */ -int32 PCX; /* External view of PC */ -int32 bankSelect = 0; /* determines selected memory bank */ -uint32 common = 0xc000; /* addresses >= 'common' are in common memory */ -uint32 ROMLow = defaultROMLow; /* lowest address of ROM */ -uint32 ROMHigh = defaultROMHigh; /* highest address of ROM */ - extern int32 sim_int_char; extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ -extern int32 sio0s (int32 port, int32 io, int32 data); -extern int32 sio0d (int32 port, int32 io, int32 data); -extern int32 sio1s (int32 port, int32 io, int32 data); -extern int32 sio1d (int32 port, int32 io, int32 data); -extern int32 dsk10 (int32 port, int32 io, int32 data); -extern int32 dsk11 (int32 port, int32 io, int32 data); -extern int32 dsk12 (int32 port, int32 io, int32 data); -extern int32 nulldev (int32 port, int32 io, int32 data); -extern int32 hdsk_io (int32 port, int32 io, int32 data); -extern int32 simh_dev (int32 port, int32 io, int32 data); -extern int32 sr_dev (int32 port, int32 io, int32 data); +extern int32 sio0s (const int32 port, const int32 io, const int32 data); +extern int32 sio0d (const int32 port, const int32 io, const int32 data); +extern int32 sio1s (const int32 port, const int32 io, const int32 data); +extern int32 sio1d (const int32 port, const int32 io, const int32 data); +extern int32 dsk10 (const int32 port, const int32 io, const int32 data); +extern int32 dsk11 (const int32 port, const int32 io, const int32 data); +extern int32 dsk12 (const int32 port, const int32 io, const int32 data); +extern int32 nulldev (const int32 port, const int32 io, const int32 data); +extern int32 hdsk_io (const int32 port, const int32 io, const int32 data); +extern int32 simh_dev (const int32 port, const int32 io, const int32 data); +extern int32 sr_dev (const int32 port, const int32 io, const int32 data); extern int32 bootrom[bootrom_size]; extern char memoryAccessMessage[]; extern char messageBuffer[]; @@ -181,31 +157,34 @@ extern void printMessage(void); 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, char *cptr, void *desc); -t_stat cpu_set_banked(UNIT *uptr, int32 value, char *cptr, void *desc); -t_stat cpu_set_rom(UNIT *uptr, int32 value, char *cptr, void *desc); -t_stat cpu_set_norom(UNIT *uptr, int32 value, char *cptr, void *desc); -t_stat cpu_set_altairrom(UNIT *uptr, int32 value, char *cptr, void *desc); -uint32 in(uint32 Port); -void out(uint32 Port, uint32 Value); +static t_stat cpu_set_rom (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat cpu_set_norom (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat cpu_set_altairrom (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat cpu_set_warnrom (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat cpu_set_size (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat cpu_set_banked (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat cpu_set_nonbanked (UNIT *uptr, int32 value, char *cptr, void *desc); +static void prepareMemoryAccessMessage(t_addr loc); +static void checkROMBoundaries(void); +static void warnUnsuccessfulWriteAttempt(const uint32 Addr); +static uint8 warnUnsuccessfulReadAttempt(const uint32 Addr); +static void reset_memory(void); +static uint32 in(const uint32 Port); +static void out(const uint32 Port, const uint32 Value); uint8 GetBYTE(register uint32 Addr); +void PutBYTEBasic(const uint32 Addr, const uint32 Bank, const uint32 Value); void PutBYTE(register uint32 Addr, register uint32 Value); void PutBYTEForced(register uint32 Addr, register uint32 Value); -int32 addressIsInROM(uint32 Addr); -int32 addressExists(uint32 Addr); -uint16 GetWORD(register uint32 a); -void PutWORD(register uint32 a, register uint32 v); +int32 addressIsInROM(const uint32 Addr); +int32 addressExists(const uint32 Addr); +static uint16 GetWORD(register uint32 a); +static void PutWORD(register uint32 a, register uint32 v); int32 sim_instr(void); int32 install_bootrom(void); -void reset_memory(void); -t_bool sim_brk_lookup (t_addr bloc, int32 btyp); -void prepareMemoryAccessMessage(t_addr loc); -void checkROMBoundaries(void); -void warnUnsuccessfulWriteAttempt(uint32 Addr); -uint8 warnUnsuccessfulReadAttempt(uint32 Addr); -t_stat cpu_set_warnrom(UNIT *uptr, int32 value, char *cptr, void *desc); -void protect(int32 l, int32 h); -void resetCell(int32 address, int32 bank); +static t_bool sim_brk_lookup (const t_addr bloc, const int32 btyp); +void protect(const int32 l, const int32 h); +static void resetCell(const int32 address, const int32 bank); +void printROMMessage(const uint32 cntROM); #ifndef NO_INLINE /* in case of using inline we need to ensure that the GetBYTE and PutBYTE @@ -223,58 +202,75 @@ void PutBYTEWrapper(register uint32 Addr, register uint32 Value); UNIT cpu_unit = { UDATA (NULL, UNIT_FIX + UNIT_BINK + UNIT_ROM + UNIT_ALTAIRROM, MAXMEMSIZE) }; -int32 AF_S; -int32 BC_S; -int32 DE_S; -int32 HL_S; -int32 IX_S; -int32 IY_S; -int32 SP_S; -int32 AF1_S; -int32 BC1_S; -int32 DE1_S; -int32 HL1_S; -int32 IFF_S; -int32 INT_S; -uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */ -int32 pcq_p = 0; /* PC queue ptr */ -REG *pcq_r = NULL; /* PC queue reg ptr */ + int32 PCX; /* external view of PC */ + int32 saved_PC = 0; /* program counter */ +static int32 AF_S; /* AF register */ +static int32 BC_S; /* BC register */ +static int32 DE_S; /* DE register */ +static int32 HL_S; /* HL register */ +static int32 IX_S; /* IX register */ +static int32 IY_S; /* IY register */ +static int32 SP_S; /* SP register */ +static int32 AF1_S; /* alternate AF register */ +static int32 BC1_S; /* alternate BC register */ +static int32 DE1_S; /* alternate DE register */ +static int32 HL1_S; /* alternate HL register */ +static int32 IFF_S; /* interrupt Flip Flop */ +static int32 IR_S; /* interrupt (upper)/refresh (lower) register */ + int32 SR = 0; /* switch register */ + int32 bankSelect = 0; /* determines selected memory bank */ + uint32 common = 0xc000; /* addresses >= 'common' are in common memory */ +static uint32 ROMLow = defaultROMLow; /* lowest address of ROM */ +static uint32 ROMHigh = defaultROMHigh; /* highest address of ROM */ +static uint32 previousCapacity= 0; /* safe for previous memory capacity */ +static uint32 clockFrequency = 0; /* in kHz, 0 means as fast as possible */ +static uint32 sliceLength = 10; /* length of time-slice for CPU speed */ + /* adjustment in milliseonds */ +static uint32 executedTStates = 0; /* executed t-states */ +static uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */ +static int32 pcq_p = 0; /* PC queue ptr */ +static REG *pcq_r = NULL; /* PC queue reg ptr */ + REG cpu_reg[] = { - { HRDATA (PC, saved_PC, 16) }, - { HRDATA (AF, AF_S, 16) }, - { HRDATA (BC, BC_S, 16) }, - { HRDATA (DE, DE_S, 16) }, - { HRDATA (HL, HL_S, 16) }, - { HRDATA (IX, IX_S, 16) }, - { HRDATA (IY, IY_S, 16) }, - { HRDATA (SP, SP_S, 16) }, - { HRDATA (AF1, AF1_S, 16) }, - { HRDATA (BC1, BC1_S, 16) }, - { HRDATA (DE1, DE1_S, 16) }, - { HRDATA (HL1, HL1_S, 16) }, - { GRDATA (IFF, IFF_S, 2, 2, 0) }, - { FLDATA (INT, INT_S, 8) }, - { FLDATA (Z80, cpu_unit.flags, UNIT_V_CHIP), REG_HRO }, - { FLDATA (OPSTOP, cpu_unit.flags, UNIT_V_OPSTOP), REG_HRO }, - { HRDATA (SR, SR, 8) }, - { HRDATA (BANK, bankSelect, MAXBANKSLOG2) }, - { HRDATA (COMMON, common, 16) }, - { HRDATA (ROMLOW, ROMLow, 16) }, - { HRDATA (ROMHIGH, ROMHigh, 16) }, - { HRDATA (CAPACITY, cpu_unit.capac, 17), REG_RO }, - { BRDATA (PCQ, pcq, 16, 16, PCQ_SIZE), REG_RO + REG_CIRC }, - { DRDATA (PCQP, pcq_p, 6), REG_HRO }, - { HRDATA (WRU, sim_int_char, 8) }, + { HRDATA (PC, saved_PC, 16) }, + { HRDATA (AF, AF_S, 16) }, + { HRDATA (BC, BC_S, 16) }, + { HRDATA (DE, DE_S, 16) }, + { HRDATA (HL, HL_S, 16) }, + { HRDATA (IX, IX_S, 16) }, + { HRDATA (IY, IY_S, 16) }, + { HRDATA (SP, SP_S, 16) }, + { HRDATA (AF1, AF1_S, 16) }, + { HRDATA (BC1, BC1_S, 16) }, + { HRDATA (DE1, DE1_S, 16) }, + { HRDATA (HL1, HL1_S, 16) }, + { GRDATA (IFF, IFF_S, 2, 2, 0) }, + { FLDATA (IR, IR_S, 8) }, + { FLDATA (Z80, cpu_unit.flags, UNIT_V_CHIP), REG_HRO }, + { FLDATA (OPSTOP, cpu_unit.flags, UNIT_V_OPSTOP), REG_HRO }, + { HRDATA (SR, SR, 8) }, + { HRDATA (BANK, bankSelect, MAXBANKSLOG2) }, + { HRDATA (COMMON, common, 16) }, + { HRDATA (ROMLOW, ROMLow, 16) }, + { HRDATA (ROMHIGH, ROMHigh, 16) }, + { DRDATA (CLOCK, clockFrequency, 32) }, + { DRDATA (SLICE, sliceLength, 16) }, + { DRDATA (TSTATES, executedTStates, 32), REG_RO }, + { HRDATA (CAPACITY, cpu_unit.capac, 32), REG_RO }, + { HRDATA (PREVCAP, previousCapacity, 32), REG_RO }, + { BRDATA (PCQ, pcq, 16, 16, PCQ_SIZE), REG_RO + REG_CIRC }, + { DRDATA (PCQP, pcq_p, PCQ_SIZE_LOG2), REG_HRO }, + { HRDATA (WRU, sim_int_char, 8) }, { NULL } }; -MTAB cpu_mod[] = { +static MTAB cpu_mod[] = { { UNIT_CHIP, UNIT_CHIP, "Z80", "Z80", NULL }, { UNIT_CHIP, 0, "8080", "8080", NULL }, { UNIT_OPSTOP, UNIT_OPSTOP, "ITRAP", "ITRAP", NULL }, { UNIT_OPSTOP, 0, "NOITRAP", "NOITRAP", NULL }, { UNIT_BANKED, UNIT_BANKED, "BANKED", "BANKED", &cpu_set_banked }, - { UNIT_BANKED, 0, "NONBANKED", "NONBANKED", NULL }, + { UNIT_BANKED, 0, "NONBANKED", "NONBANKED", &cpu_set_nonbanked }, { UNIT_ROM, UNIT_ROM, "ROM", "ROM", &cpu_set_rom }, { UNIT_ROM, 0, "NOROM", "NOROM", &cpu_set_norom }, { UNIT_ALTAIRROM, UNIT_ALTAIRROM, "ALTAIRROM", "ALTAIRROM", &cpu_set_altairrom }, @@ -303,92 +299,1163 @@ DEVICE cpu_dev = { "CPU", &cpu_unit, cpu_reg, cpu_mod, 1, 16, 16, 1, 16, 8, &cpu_ex, &cpu_dep, &cpu_reset, - NULL, NULL, NULL, NULL, 0 }; + NULL, NULL, NULL, NULL, 0, NULL, NULL }; /* data structure for IN/OUT instructions */ struct idev { - int32 (*routine)(int32, int32, int32); + int32 (*routine)(const int32, const int32, const int32); }; /* This is the I/O configuration table. There are 255 possible device addresses, if a device is plugged to a port it's routine address is here, 'nulldev' means no device is available */ -struct idev dev_table[256] = { -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04 */ -{&dsk10}, {&dsk11}, {&dsk12}, {&nulldev}, /* 08 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C */ -{&sio0s}, {&sio0d}, {&sio1s}, {&sio1d}, /* 10 */ -{&sio0s}, {&sio0d}, {&sio0s}, {&sio0d}, /* 14 */ -{&sio0s}, {&sio0d}, {&nulldev}, {&nulldev}, /* 18 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 20 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 24 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 28 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 30 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 34 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 38 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 40 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 44 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 48 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 4C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 50 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 54 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 58 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 5C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 60 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 64 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 68 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 6C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 70 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 74 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 78 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 7C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 80 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 84 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 88 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 8C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 90 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 94 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 98 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 9C */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A0 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A4 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A8 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* AC */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B0 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B4 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B8 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* BC */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C0 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C4 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C8 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* CC */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D0 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D4 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D8 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* DC */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D0 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E4 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E8 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* EC */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F0 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F4 */ -{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F8 */ -{&nulldev}, {&hdsk_io}, {&simh_dev}, {&sr_dev} }; /* FC */ +static const struct idev dev_table[256] = { + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04 */ + {&dsk10}, {&dsk11}, {&dsk12}, {&nulldev}, /* 08 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C */ + {&sio0s}, {&sio0d}, {&sio1s}, {&sio1d}, /* 10 */ + {&sio0s}, {&sio0d}, {&sio0s}, {&sio0d}, /* 14 */ + {&sio0s}, {&sio0d}, {&nulldev}, {&nulldev}, /* 18 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 20 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 24 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 28 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 30 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 34 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 38 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 40 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 44 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 48 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 4C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 50 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 54 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 58 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 5C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 60 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 64 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 68 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 6C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 70 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 74 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 78 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 7C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 80 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 84 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 88 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 8C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 90 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 94 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 98 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 9C */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A0 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A4 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* A8 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* AC */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B0 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B4 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* B8 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* BC */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C0 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C4 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* C8 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* CC */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D0 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D4 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D8 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* DC */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* D0 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E4 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* E8 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* EC */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F0 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F4 */ + {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* F8 */ + {&nulldev}, {&hdsk_io}, {&simh_dev}, {&sr_dev} /* FC */ +}; -INLINE void out(uint32 Port, uint32 Value) { +static INLINE void out(const uint32 Port, const uint32 Value) { dev_table[Port].routine(Port, 1, Value); } -INLINE uint32 in(uint32 Port) { +static INLINE uint32 in(const uint32 Port) { return dev_table[Port].routine(Port, 0, 0); } -void warnUnsuccessfulWriteAttempt(uint32 Addr) { +/* the following tables precompute some common subexpressions + parityTable[i] 0..255 (number of 1's in i is odd) ? 0 : 4 + incTable[i] 0..256! (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4) + decTable[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2 + cbitsTable[i] 0..511 (i & 0x10) | ((i >> 8) & 1) + cbitsDup8Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) | + (((i & 0xff) == 0) << 6) + cbitsDup16Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | (i & 0x28) + cbits2Table[i] 0..511 (i & 0x10) | ((i >> 8) & 1) | 2 + rrcaTable[i] 0..255 ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1) + rraTable[i] 0..255 ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1) + addTable[i] 0..511 ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) + subTable[i] 0..255 ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2 + andTable[i] 0..255 (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i] + xororTable[i] 0..255 (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i] + rotateShiftTable[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff] + incZ80Table[i] 0..256! (i & 0xa8) | (((i & 0xff) == 0) << 6) | + (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2) + decZ80Table[i] 0..255 (i & 0xa8) | (((i & 0xff) == 0) << 6) | + (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2 + cbitsZ80Table[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) + cbitsZ80DupTable[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | + ((i >> 8) & 1) | (i & 0xa8) + cbits2Z80Table[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 + cbits2Z80DupTable[i] 0..511 (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 | + (i & 0xa8) + negTable[i] 0..255 (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0) + rrdrldTable[i] 0..255 (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i] + cpTable[i] 0..255 (i & 0x80) | (((i & 0xff) == 0) << 6) +*/ + +/* parityTable[i] = (number of 1's in i is odd) ? 0 : 4, i = 0..255 */ +static const uint8 parityTable[256] = { + 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, + 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, + 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, + 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, + 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, + 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, + 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, + 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, + 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, + 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, + 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, + 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, + 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, + 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, + 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0, + 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4, +}; + +/* incTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4), i = 0..256 */ +static const uint8 incTable[257] = { + 80, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136, + 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136, + 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, + 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, + 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136, + 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136, + 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, + 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80 +}; + +/* decTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2, i = 0..255 */ +static const uint8 decTable[256] = { + 66, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26, + 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58, + 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26, + 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58, + 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154, + 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154, + 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186, + 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186, + 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154, + 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154, + 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186, + 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186, +}; + +/* cbitsTable[i] = (i & 0x10) | ((i >> 8) & 1), i = 0..511 */ +static const uint8 cbitsTable[512] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, +}; + +/* cbitsDup8Table[i] = (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) | + (((i & 0xff) == 0) << 6), i = 0..511 */ +static const uint16 cbitsDup8Table[512] = { + 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700, + 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08, + 0x1010,0x1110,0x1210,0x1310,0x1410,0x1510,0x1610,0x1710, + 0x1818,0x1918,0x1a18,0x1b18,0x1c18,0x1d18,0x1e18,0x1f18, + 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720, + 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28, + 0x3030,0x3130,0x3230,0x3330,0x3430,0x3530,0x3630,0x3730, + 0x3838,0x3938,0x3a38,0x3b38,0x3c38,0x3d38,0x3e38,0x3f38, + 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700, + 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08, + 0x5010,0x5110,0x5210,0x5310,0x5410,0x5510,0x5610,0x5710, + 0x5818,0x5918,0x5a18,0x5b18,0x5c18,0x5d18,0x5e18,0x5f18, + 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720, + 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28, + 0x7030,0x7130,0x7230,0x7330,0x7430,0x7530,0x7630,0x7730, + 0x7838,0x7938,0x7a38,0x7b38,0x7c38,0x7d38,0x7e38,0x7f38, + 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780, + 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88, + 0x9090,0x9190,0x9290,0x9390,0x9490,0x9590,0x9690,0x9790, + 0x9898,0x9998,0x9a98,0x9b98,0x9c98,0x9d98,0x9e98,0x9f98, + 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0, + 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8, + 0xb0b0,0xb1b0,0xb2b0,0xb3b0,0xb4b0,0xb5b0,0xb6b0,0xb7b0, + 0xb8b8,0xb9b8,0xbab8,0xbbb8,0xbcb8,0xbdb8,0xbeb8,0xbfb8, + 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780, + 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88, + 0xd090,0xd190,0xd290,0xd390,0xd490,0xd590,0xd690,0xd790, + 0xd898,0xd998,0xda98,0xdb98,0xdc98,0xdd98,0xde98,0xdf98, + 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0, + 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8, + 0xf0b0,0xf1b0,0xf2b0,0xf3b0,0xf4b0,0xf5b0,0xf6b0,0xf7b0, + 0xf8b8,0xf9b8,0xfab8,0xfbb8,0xfcb8,0xfdb8,0xfeb8,0xffb8, + 0x0041,0x0101,0x0201,0x0301,0x0401,0x0501,0x0601,0x0701, + 0x0809,0x0909,0x0a09,0x0b09,0x0c09,0x0d09,0x0e09,0x0f09, + 0x1011,0x1111,0x1211,0x1311,0x1411,0x1511,0x1611,0x1711, + 0x1819,0x1919,0x1a19,0x1b19,0x1c19,0x1d19,0x1e19,0x1f19, + 0x2021,0x2121,0x2221,0x2321,0x2421,0x2521,0x2621,0x2721, + 0x2829,0x2929,0x2a29,0x2b29,0x2c29,0x2d29,0x2e29,0x2f29, + 0x3031,0x3131,0x3231,0x3331,0x3431,0x3531,0x3631,0x3731, + 0x3839,0x3939,0x3a39,0x3b39,0x3c39,0x3d39,0x3e39,0x3f39, + 0x4001,0x4101,0x4201,0x4301,0x4401,0x4501,0x4601,0x4701, + 0x4809,0x4909,0x4a09,0x4b09,0x4c09,0x4d09,0x4e09,0x4f09, + 0x5011,0x5111,0x5211,0x5311,0x5411,0x5511,0x5611,0x5711, + 0x5819,0x5919,0x5a19,0x5b19,0x5c19,0x5d19,0x5e19,0x5f19, + 0x6021,0x6121,0x6221,0x6321,0x6421,0x6521,0x6621,0x6721, + 0x6829,0x6929,0x6a29,0x6b29,0x6c29,0x6d29,0x6e29,0x6f29, + 0x7031,0x7131,0x7231,0x7331,0x7431,0x7531,0x7631,0x7731, + 0x7839,0x7939,0x7a39,0x7b39,0x7c39,0x7d39,0x7e39,0x7f39, + 0x8081,0x8181,0x8281,0x8381,0x8481,0x8581,0x8681,0x8781, + 0x8889,0x8989,0x8a89,0x8b89,0x8c89,0x8d89,0x8e89,0x8f89, + 0x9091,0x9191,0x9291,0x9391,0x9491,0x9591,0x9691,0x9791, + 0x9899,0x9999,0x9a99,0x9b99,0x9c99,0x9d99,0x9e99,0x9f99, + 0xa0a1,0xa1a1,0xa2a1,0xa3a1,0xa4a1,0xa5a1,0xa6a1,0xa7a1, + 0xa8a9,0xa9a9,0xaaa9,0xaba9,0xaca9,0xada9,0xaea9,0xafa9, + 0xb0b1,0xb1b1,0xb2b1,0xb3b1,0xb4b1,0xb5b1,0xb6b1,0xb7b1, + 0xb8b9,0xb9b9,0xbab9,0xbbb9,0xbcb9,0xbdb9,0xbeb9,0xbfb9, + 0xc081,0xc181,0xc281,0xc381,0xc481,0xc581,0xc681,0xc781, + 0xc889,0xc989,0xca89,0xcb89,0xcc89,0xcd89,0xce89,0xcf89, + 0xd091,0xd191,0xd291,0xd391,0xd491,0xd591,0xd691,0xd791, + 0xd899,0xd999,0xda99,0xdb99,0xdc99,0xdd99,0xde99,0xdf99, + 0xe0a1,0xe1a1,0xe2a1,0xe3a1,0xe4a1,0xe5a1,0xe6a1,0xe7a1, + 0xe8a9,0xe9a9,0xeaa9,0xeba9,0xeca9,0xeda9,0xeea9,0xefa9, + 0xf0b1,0xf1b1,0xf2b1,0xf3b1,0xf4b1,0xf5b1,0xf6b1,0xf7b1, + 0xf8b9,0xf9b9,0xfab9,0xfbb9,0xfcb9,0xfdb9,0xfeb9,0xffb9, +}; + +/* cbitsDup16Table[i] = (i & 0x10) | ((i >> 8) & 1) | (i & 0x28), i = 0..511 */ +static const uint8 cbitsDup16Table[512] = { + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24, + 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40, + 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24, + 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40, + 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24, + 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40, + 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24, + 32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40, + 48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56, + 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, + 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25, + 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41, + 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57, + 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, + 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25, + 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41, + 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57, + 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, + 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25, + 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41, + 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57, + 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, + 17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25, + 33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41, + 49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57, +}; + +/* cbits2Table[i] = (i & 0x10) | ((i >> 8) & 1) | 2, i = 0..511 */ +static const uint8 cbits2Table[512] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +}; + +/* rrcaTable[i] = ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1), i = 0..255 */ +static const uint16 rrcaTable[256] = { + 0x0000,0x8001,0x0100,0x8101,0x0200,0x8201,0x0300,0x8301, + 0x0400,0x8401,0x0500,0x8501,0x0600,0x8601,0x0700,0x8701, + 0x0808,0x8809,0x0908,0x8909,0x0a08,0x8a09,0x0b08,0x8b09, + 0x0c08,0x8c09,0x0d08,0x8d09,0x0e08,0x8e09,0x0f08,0x8f09, + 0x1000,0x9001,0x1100,0x9101,0x1200,0x9201,0x1300,0x9301, + 0x1400,0x9401,0x1500,0x9501,0x1600,0x9601,0x1700,0x9701, + 0x1808,0x9809,0x1908,0x9909,0x1a08,0x9a09,0x1b08,0x9b09, + 0x1c08,0x9c09,0x1d08,0x9d09,0x1e08,0x9e09,0x1f08,0x9f09, + 0x2020,0xa021,0x2120,0xa121,0x2220,0xa221,0x2320,0xa321, + 0x2420,0xa421,0x2520,0xa521,0x2620,0xa621,0x2720,0xa721, + 0x2828,0xa829,0x2928,0xa929,0x2a28,0xaa29,0x2b28,0xab29, + 0x2c28,0xac29,0x2d28,0xad29,0x2e28,0xae29,0x2f28,0xaf29, + 0x3020,0xb021,0x3120,0xb121,0x3220,0xb221,0x3320,0xb321, + 0x3420,0xb421,0x3520,0xb521,0x3620,0xb621,0x3720,0xb721, + 0x3828,0xb829,0x3928,0xb929,0x3a28,0xba29,0x3b28,0xbb29, + 0x3c28,0xbc29,0x3d28,0xbd29,0x3e28,0xbe29,0x3f28,0xbf29, + 0x4000,0xc001,0x4100,0xc101,0x4200,0xc201,0x4300,0xc301, + 0x4400,0xc401,0x4500,0xc501,0x4600,0xc601,0x4700,0xc701, + 0x4808,0xc809,0x4908,0xc909,0x4a08,0xca09,0x4b08,0xcb09, + 0x4c08,0xcc09,0x4d08,0xcd09,0x4e08,0xce09,0x4f08,0xcf09, + 0x5000,0xd001,0x5100,0xd101,0x5200,0xd201,0x5300,0xd301, + 0x5400,0xd401,0x5500,0xd501,0x5600,0xd601,0x5700,0xd701, + 0x5808,0xd809,0x5908,0xd909,0x5a08,0xda09,0x5b08,0xdb09, + 0x5c08,0xdc09,0x5d08,0xdd09,0x5e08,0xde09,0x5f08,0xdf09, + 0x6020,0xe021,0x6120,0xe121,0x6220,0xe221,0x6320,0xe321, + 0x6420,0xe421,0x6520,0xe521,0x6620,0xe621,0x6720,0xe721, + 0x6828,0xe829,0x6928,0xe929,0x6a28,0xea29,0x6b28,0xeb29, + 0x6c28,0xec29,0x6d28,0xed29,0x6e28,0xee29,0x6f28,0xef29, + 0x7020,0xf021,0x7120,0xf121,0x7220,0xf221,0x7320,0xf321, + 0x7420,0xf421,0x7520,0xf521,0x7620,0xf621,0x7720,0xf721, + 0x7828,0xf829,0x7928,0xf929,0x7a28,0xfa29,0x7b28,0xfb29, + 0x7c28,0xfc29,0x7d28,0xfd29,0x7e28,0xfe29,0x7f28,0xff29, +}; + +/* rraTable[i] = ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1), i = 0..255 */ +static const uint16 rraTable[256] = { + 0x0000,0x0001,0x0100,0x0101,0x0200,0x0201,0x0300,0x0301, + 0x0400,0x0401,0x0500,0x0501,0x0600,0x0601,0x0700,0x0701, + 0x0808,0x0809,0x0908,0x0909,0x0a08,0x0a09,0x0b08,0x0b09, + 0x0c08,0x0c09,0x0d08,0x0d09,0x0e08,0x0e09,0x0f08,0x0f09, + 0x1000,0x1001,0x1100,0x1101,0x1200,0x1201,0x1300,0x1301, + 0x1400,0x1401,0x1500,0x1501,0x1600,0x1601,0x1700,0x1701, + 0x1808,0x1809,0x1908,0x1909,0x1a08,0x1a09,0x1b08,0x1b09, + 0x1c08,0x1c09,0x1d08,0x1d09,0x1e08,0x1e09,0x1f08,0x1f09, + 0x2020,0x2021,0x2120,0x2121,0x2220,0x2221,0x2320,0x2321, + 0x2420,0x2421,0x2520,0x2521,0x2620,0x2621,0x2720,0x2721, + 0x2828,0x2829,0x2928,0x2929,0x2a28,0x2a29,0x2b28,0x2b29, + 0x2c28,0x2c29,0x2d28,0x2d29,0x2e28,0x2e29,0x2f28,0x2f29, + 0x3020,0x3021,0x3120,0x3121,0x3220,0x3221,0x3320,0x3321, + 0x3420,0x3421,0x3520,0x3521,0x3620,0x3621,0x3720,0x3721, + 0x3828,0x3829,0x3928,0x3929,0x3a28,0x3a29,0x3b28,0x3b29, + 0x3c28,0x3c29,0x3d28,0x3d29,0x3e28,0x3e29,0x3f28,0x3f29, + 0x4000,0x4001,0x4100,0x4101,0x4200,0x4201,0x4300,0x4301, + 0x4400,0x4401,0x4500,0x4501,0x4600,0x4601,0x4700,0x4701, + 0x4808,0x4809,0x4908,0x4909,0x4a08,0x4a09,0x4b08,0x4b09, + 0x4c08,0x4c09,0x4d08,0x4d09,0x4e08,0x4e09,0x4f08,0x4f09, + 0x5000,0x5001,0x5100,0x5101,0x5200,0x5201,0x5300,0x5301, + 0x5400,0x5401,0x5500,0x5501,0x5600,0x5601,0x5700,0x5701, + 0x5808,0x5809,0x5908,0x5909,0x5a08,0x5a09,0x5b08,0x5b09, + 0x5c08,0x5c09,0x5d08,0x5d09,0x5e08,0x5e09,0x5f08,0x5f09, + 0x6020,0x6021,0x6120,0x6121,0x6220,0x6221,0x6320,0x6321, + 0x6420,0x6421,0x6520,0x6521,0x6620,0x6621,0x6720,0x6721, + 0x6828,0x6829,0x6928,0x6929,0x6a28,0x6a29,0x6b28,0x6b29, + 0x6c28,0x6c29,0x6d28,0x6d29,0x6e28,0x6e29,0x6f28,0x6f29, + 0x7020,0x7021,0x7120,0x7121,0x7220,0x7221,0x7320,0x7321, + 0x7420,0x7421,0x7520,0x7521,0x7620,0x7621,0x7720,0x7721, + 0x7828,0x7829,0x7928,0x7929,0x7a28,0x7a29,0x7b28,0x7b29, + 0x7c28,0x7c29,0x7d28,0x7d29,0x7e28,0x7e29,0x7f28,0x7f29, +}; + +/* addTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6), i = 0..511 */ +static const uint16 addTable[512] = { + 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700, + 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08, + 0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700, + 0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08, + 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720, + 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28, + 0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720, + 0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28, + 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700, + 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08, + 0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700, + 0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08, + 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720, + 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28, + 0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720, + 0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28, + 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780, + 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88, + 0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780, + 0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88, + 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0, + 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8, + 0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0, + 0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8, + 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780, + 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88, + 0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780, + 0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88, + 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0, + 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8, + 0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0, + 0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8, + 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700, + 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08, + 0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700, + 0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08, + 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720, + 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28, + 0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720, + 0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28, + 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700, + 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08, + 0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700, + 0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08, + 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720, + 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28, + 0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720, + 0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28, + 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780, + 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88, + 0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780, + 0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88, + 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0, + 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8, + 0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0, + 0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8, + 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780, + 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88, + 0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780, + 0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88, + 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0, + 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8, + 0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0, + 0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8, +}; + +/* subTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2, i = 0..255 */ +static const uint16 subTable[256] = { + 0x0042,0x0102,0x0202,0x0302,0x0402,0x0502,0x0602,0x0702, + 0x080a,0x090a,0x0a0a,0x0b0a,0x0c0a,0x0d0a,0x0e0a,0x0f0a, + 0x1002,0x1102,0x1202,0x1302,0x1402,0x1502,0x1602,0x1702, + 0x180a,0x190a,0x1a0a,0x1b0a,0x1c0a,0x1d0a,0x1e0a,0x1f0a, + 0x2022,0x2122,0x2222,0x2322,0x2422,0x2522,0x2622,0x2722, + 0x282a,0x292a,0x2a2a,0x2b2a,0x2c2a,0x2d2a,0x2e2a,0x2f2a, + 0x3022,0x3122,0x3222,0x3322,0x3422,0x3522,0x3622,0x3722, + 0x382a,0x392a,0x3a2a,0x3b2a,0x3c2a,0x3d2a,0x3e2a,0x3f2a, + 0x4002,0x4102,0x4202,0x4302,0x4402,0x4502,0x4602,0x4702, + 0x480a,0x490a,0x4a0a,0x4b0a,0x4c0a,0x4d0a,0x4e0a,0x4f0a, + 0x5002,0x5102,0x5202,0x5302,0x5402,0x5502,0x5602,0x5702, + 0x580a,0x590a,0x5a0a,0x5b0a,0x5c0a,0x5d0a,0x5e0a,0x5f0a, + 0x6022,0x6122,0x6222,0x6322,0x6422,0x6522,0x6622,0x6722, + 0x682a,0x692a,0x6a2a,0x6b2a,0x6c2a,0x6d2a,0x6e2a,0x6f2a, + 0x7022,0x7122,0x7222,0x7322,0x7422,0x7522,0x7622,0x7722, + 0x782a,0x792a,0x7a2a,0x7b2a,0x7c2a,0x7d2a,0x7e2a,0x7f2a, + 0x8082,0x8182,0x8282,0x8382,0x8482,0x8582,0x8682,0x8782, + 0x888a,0x898a,0x8a8a,0x8b8a,0x8c8a,0x8d8a,0x8e8a,0x8f8a, + 0x9082,0x9182,0x9282,0x9382,0x9482,0x9582,0x9682,0x9782, + 0x988a,0x998a,0x9a8a,0x9b8a,0x9c8a,0x9d8a,0x9e8a,0x9f8a, + 0xa0a2,0xa1a2,0xa2a2,0xa3a2,0xa4a2,0xa5a2,0xa6a2,0xa7a2, + 0xa8aa,0xa9aa,0xaaaa,0xabaa,0xacaa,0xadaa,0xaeaa,0xafaa, + 0xb0a2,0xb1a2,0xb2a2,0xb3a2,0xb4a2,0xb5a2,0xb6a2,0xb7a2, + 0xb8aa,0xb9aa,0xbaaa,0xbbaa,0xbcaa,0xbdaa,0xbeaa,0xbfaa, + 0xc082,0xc182,0xc282,0xc382,0xc482,0xc582,0xc682,0xc782, + 0xc88a,0xc98a,0xca8a,0xcb8a,0xcc8a,0xcd8a,0xce8a,0xcf8a, + 0xd082,0xd182,0xd282,0xd382,0xd482,0xd582,0xd682,0xd782, + 0xd88a,0xd98a,0xda8a,0xdb8a,0xdc8a,0xdd8a,0xde8a,0xdf8a, + 0xe0a2,0xe1a2,0xe2a2,0xe3a2,0xe4a2,0xe5a2,0xe6a2,0xe7a2, + 0xe8aa,0xe9aa,0xeaaa,0xebaa,0xecaa,0xedaa,0xeeaa,0xefaa, + 0xf0a2,0xf1a2,0xf2a2,0xf3a2,0xf4a2,0xf5a2,0xf6a2,0xf7a2, + 0xf8aa,0xf9aa,0xfaaa,0xfbaa,0xfcaa,0xfdaa,0xfeaa,0xffaa, +}; + +/* andTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i], i = 0..255 */ +static const uint16 andTable[256] = { + 0x0054,0x0110,0x0210,0x0314,0x0410,0x0514,0x0614,0x0710, + 0x0818,0x091c,0x0a1c,0x0b18,0x0c1c,0x0d18,0x0e18,0x0f1c, + 0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,0x1610,0x1714, + 0x181c,0x1918,0x1a18,0x1b1c,0x1c18,0x1d1c,0x1e1c,0x1f18, + 0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,0x2630,0x2734, + 0x283c,0x2938,0x2a38,0x2b3c,0x2c38,0x2d3c,0x2e3c,0x2f38, + 0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,0x3634,0x3730, + 0x3838,0x393c,0x3a3c,0x3b38,0x3c3c,0x3d38,0x3e38,0x3f3c, + 0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,0x4610,0x4714, + 0x481c,0x4918,0x4a18,0x4b1c,0x4c18,0x4d1c,0x4e1c,0x4f18, + 0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,0x5614,0x5710, + 0x5818,0x591c,0x5a1c,0x5b18,0x5c1c,0x5d18,0x5e18,0x5f1c, + 0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,0x6634,0x6730, + 0x6838,0x693c,0x6a3c,0x6b38,0x6c3c,0x6d38,0x6e38,0x6f3c, + 0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,0x7630,0x7734, + 0x783c,0x7938,0x7a38,0x7b3c,0x7c38,0x7d3c,0x7e3c,0x7f38, + 0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,0x8690,0x8794, + 0x889c,0x8998,0x8a98,0x8b9c,0x8c98,0x8d9c,0x8e9c,0x8f98, + 0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,0x9694,0x9790, + 0x9898,0x999c,0x9a9c,0x9b98,0x9c9c,0x9d98,0x9e98,0x9f9c, + 0xa0b4,0xa1b0,0xa2b0,0xa3b4,0xa4b0,0xa5b4,0xa6b4,0xa7b0, + 0xa8b8,0xa9bc,0xaabc,0xabb8,0xacbc,0xadb8,0xaeb8,0xafbc, + 0xb0b0,0xb1b4,0xb2b4,0xb3b0,0xb4b4,0xb5b0,0xb6b0,0xb7b4, + 0xb8bc,0xb9b8,0xbab8,0xbbbc,0xbcb8,0xbdbc,0xbebc,0xbfb8, + 0xc094,0xc190,0xc290,0xc394,0xc490,0xc594,0xc694,0xc790, + 0xc898,0xc99c,0xca9c,0xcb98,0xcc9c,0xcd98,0xce98,0xcf9c, + 0xd090,0xd194,0xd294,0xd390,0xd494,0xd590,0xd690,0xd794, + 0xd89c,0xd998,0xda98,0xdb9c,0xdc98,0xdd9c,0xde9c,0xdf98, + 0xe0b0,0xe1b4,0xe2b4,0xe3b0,0xe4b4,0xe5b0,0xe6b0,0xe7b4, + 0xe8bc,0xe9b8,0xeab8,0xebbc,0xecb8,0xedbc,0xeebc,0xefb8, + 0xf0b4,0xf1b0,0xf2b0,0xf3b4,0xf4b0,0xf5b4,0xf6b4,0xf7b0, + 0xf8b8,0xf9bc,0xfabc,0xfbb8,0xfcbc,0xfdb8,0xfeb8,0xffbc, +}; + +/* xororTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i], i = 0..255 */ +static const uint16 xororTable[256] = { + 0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700, + 0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c, + 0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704, + 0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08, + 0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724, + 0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28, + 0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720, + 0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c, + 0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704, + 0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08, + 0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700, + 0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c, + 0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720, + 0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c, + 0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724, + 0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28, + 0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784, + 0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88, + 0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780, + 0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c, + 0xa0a4,0xa1a0,0xa2a0,0xa3a4,0xa4a0,0xa5a4,0xa6a4,0xa7a0, + 0xa8a8,0xa9ac,0xaaac,0xaba8,0xacac,0xada8,0xaea8,0xafac, + 0xb0a0,0xb1a4,0xb2a4,0xb3a0,0xb4a4,0xb5a0,0xb6a0,0xb7a4, + 0xb8ac,0xb9a8,0xbaa8,0xbbac,0xbca8,0xbdac,0xbeac,0xbfa8, + 0xc084,0xc180,0xc280,0xc384,0xc480,0xc584,0xc684,0xc780, + 0xc888,0xc98c,0xca8c,0xcb88,0xcc8c,0xcd88,0xce88,0xcf8c, + 0xd080,0xd184,0xd284,0xd380,0xd484,0xd580,0xd680,0xd784, + 0xd88c,0xd988,0xda88,0xdb8c,0xdc88,0xdd8c,0xde8c,0xdf88, + 0xe0a0,0xe1a4,0xe2a4,0xe3a0,0xe4a4,0xe5a0,0xe6a0,0xe7a4, + 0xe8ac,0xe9a8,0xeaa8,0xebac,0xeca8,0xedac,0xeeac,0xefa8, + 0xf0a4,0xf1a0,0xf2a0,0xf3a4,0xf4a0,0xf5a4,0xf6a4,0xf7a0, + 0xf8a8,0xf9ac,0xfaac,0xfba8,0xfcac,0xfda8,0xfea8,0xffac, +}; + +/* rotateShiftTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff], i = 0..255 */ +static const uint8 rotateShiftTable[256] = { + 68, 0, 0, 4, 0, 4, 4, 0, 8, 12, 12, 8, 12, 8, 8, 12, + 0, 4, 4, 0, 4, 0, 0, 4, 12, 8, 8, 12, 8, 12, 12, 8, + 32, 36, 36, 32, 36, 32, 32, 36, 44, 40, 40, 44, 40, 44, 44, 40, + 36, 32, 32, 36, 32, 36, 36, 32, 40, 44, 44, 40, 44, 40, 40, 44, + 0, 4, 4, 0, 4, 0, 0, 4, 12, 8, 8, 12, 8, 12, 12, 8, + 4, 0, 0, 4, 0, 4, 4, 0, 8, 12, 12, 8, 12, 8, 8, 12, + 36, 32, 32, 36, 32, 36, 36, 32, 40, 44, 44, 40, 44, 40, 40, 44, + 32, 36, 36, 32, 36, 32, 32, 36, 44, 40, 40, 44, 40, 44, 44, 40, + 128,132,132,128,132,128,128,132,140,136,136,140,136,140,140,136, + 132,128,128,132,128,132,132,128,136,140,140,136,140,136,136,140, + 164,160,160,164,160,164,164,160,168,172,172,168,172,168,168,172, + 160,164,164,160,164,160,160,164,172,168,168,172,168,172,172,168, + 132,128,128,132,128,132,132,128,136,140,140,136,140,136,136,140, + 128,132,132,128,132,128,128,132,140,136,136,140,136,140,140,136, + 160,164,164,160,164,160,160,164,172,168,168,172,168,172,172,168, + 164,160,160,164,160,164,164,160,168,172,172,168,172,168,168,172, +}; + +/* incZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | + (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2), i = 0..256 */ +static const uint8 incZ80Table[257] = { + 80, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 148,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136, + 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136, + 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, + 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, + 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136, + 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136, + 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, + 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80, +}; + +/* decZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | + (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2, i = 0..255 */ +static const uint8 decZ80Table[256] = { + 66, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26, + 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58, + 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26, + 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 62, + 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154, + 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154, + 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186, + 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186, + 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154, + 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154, + 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186, + 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186, +}; + +/* cbitsZ80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1), i = 0..511 */ +static const uint8 cbitsZ80Table[512] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, +}; + +/* cbitsZ80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | + ((i >> 8) & 1) | (i & 0xa8), i = 0..511 */ +static const uint8 cbitsZ80DupTable[512] = { + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, + 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, + 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56, + 132,132,132,132,132,132,132,132,140,140,140,140,140,140,140,140, + 148,148,148,148,148,148,148,148,156,156,156,156,156,156,156,156, + 164,164,164,164,164,164,164,164,172,172,172,172,172,172,172,172, + 180,180,180,180,180,180,180,180,188,188,188,188,188,188,188,188, + 132,132,132,132,132,132,132,132,140,140,140,140,140,140,140,140, + 148,148,148,148,148,148,148,148,156,156,156,156,156,156,156,156, + 164,164,164,164,164,164,164,164,172,172,172,172,172,172,172,172, + 180,180,180,180,180,180,180,180,188,188,188,188,188,188,188,188, + 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13, 13, 13, 13, 13, + 21, 21, 21, 21, 21, 21, 21, 21, 29, 29, 29, 29, 29, 29, 29, 29, + 37, 37, 37, 37, 37, 37, 37, 37, 45, 45, 45, 45, 45, 45, 45, 45, + 53, 53, 53, 53, 53, 53, 53, 53, 61, 61, 61, 61, 61, 61, 61, 61, + 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13, 13, 13, 13, 13, + 21, 21, 21, 21, 21, 21, 21, 21, 29, 29, 29, 29, 29, 29, 29, 29, + 37, 37, 37, 37, 37, 37, 37, 37, 45, 45, 45, 45, 45, 45, 45, 45, + 53, 53, 53, 53, 53, 53, 53, 53, 61, 61, 61, 61, 61, 61, 61, 61, + 129,129,129,129,129,129,129,129,137,137,137,137,137,137,137,137, + 145,145,145,145,145,145,145,145,153,153,153,153,153,153,153,153, + 161,161,161,161,161,161,161,161,169,169,169,169,169,169,169,169, + 177,177,177,177,177,177,177,177,185,185,185,185,185,185,185,185, + 129,129,129,129,129,129,129,129,137,137,137,137,137,137,137,137, + 145,145,145,145,145,145,145,145,153,153,153,153,153,153,153,153, + 161,161,161,161,161,161,161,161,169,169,169,169,169,169,169,169, + 177,177,177,177,177,177,177,177,185,185,185,185,185,185,185,185, +}; + +/* cbits2Z80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2, i = 0..511 */ +static const uint8 cbits2Z80Table[512] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +}; + +/* cbits2Z80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 | + (i & 0xa8), i = 0..511 */ +static const uint8 cbits2Z80DupTable[512] = { + 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, + 18, 18, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 42, + 50, 50, 50, 50, 50, 50, 50, 50, 58, 58, 58, 58, 58, 58, 58, 58, + 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, + 18, 18, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 42, + 50, 50, 50, 50, 50, 50, 50, 50, 58, 58, 58, 58, 58, 58, 58, 58, + 134,134,134,134,134,134,134,134,142,142,142,142,142,142,142,142, + 150,150,150,150,150,150,150,150,158,158,158,158,158,158,158,158, + 166,166,166,166,166,166,166,166,174,174,174,174,174,174,174,174, + 182,182,182,182,182,182,182,182,190,190,190,190,190,190,190,190, + 134,134,134,134,134,134,134,134,142,142,142,142,142,142,142,142, + 150,150,150,150,150,150,150,150,158,158,158,158,158,158,158,158, + 166,166,166,166,166,166,166,166,174,174,174,174,174,174,174,174, + 182,182,182,182,182,182,182,182,190,190,190,190,190,190,190,190, + 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15, + 23, 23, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, + 39, 39, 39, 39, 39, 39, 39, 39, 47, 47, 47, 47, 47, 47, 47, 47, + 55, 55, 55, 55, 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, 63, 63, + 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15, + 23, 23, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, + 39, 39, 39, 39, 39, 39, 39, 39, 47, 47, 47, 47, 47, 47, 47, 47, + 55, 55, 55, 55, 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, 63, 63, + 131,131,131,131,131,131,131,131,139,139,139,139,139,139,139,139, + 147,147,147,147,147,147,147,147,155,155,155,155,155,155,155,155, + 163,163,163,163,163,163,163,163,171,171,171,171,171,171,171,171, + 179,179,179,179,179,179,179,179,187,187,187,187,187,187,187,187, + 131,131,131,131,131,131,131,131,139,139,139,139,139,139,139,139, + 147,147,147,147,147,147,147,147,155,155,155,155,155,155,155,155, + 163,163,163,163,163,163,163,163,171,171,171,171,171,171,171,171, + 179,179,179,179,179,179,179,179,187,187,187,187,187,187,187,187, +}; + +/* negTable[i] = (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0), i = 0..255 */ +static const uint8 negTable[256] = { + 2,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 7,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +}; + +/* rrdrldTable[i] = (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i], i = 0..255 */ +static const uint16 rrdrldTable[256] = { + 0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700, + 0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c, + 0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704, + 0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08, + 0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724, + 0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28, + 0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720, + 0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c, + 0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704, + 0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08, + 0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700, + 0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c, + 0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720, + 0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c, + 0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724, + 0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28, + 0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784, + 0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88, + 0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780, + 0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c, + 0xa0a4,0xa1a0,0xa2a0,0xa3a4,0xa4a0,0xa5a4,0xa6a4,0xa7a0, + 0xa8a8,0xa9ac,0xaaac,0xaba8,0xacac,0xada8,0xaea8,0xafac, + 0xb0a0,0xb1a4,0xb2a4,0xb3a0,0xb4a4,0xb5a0,0xb6a0,0xb7a4, + 0xb8ac,0xb9a8,0xbaa8,0xbbac,0xbca8,0xbdac,0xbeac,0xbfa8, + 0xc084,0xc180,0xc280,0xc384,0xc480,0xc584,0xc684,0xc780, + 0xc888,0xc98c,0xca8c,0xcb88,0xcc8c,0xcd88,0xce88,0xcf8c, + 0xd080,0xd184,0xd284,0xd380,0xd484,0xd580,0xd680,0xd784, + 0xd88c,0xd988,0xda88,0xdb8c,0xdc88,0xdd8c,0xde8c,0xdf88, + 0xe0a0,0xe1a4,0xe2a4,0xe3a0,0xe4a4,0xe5a0,0xe6a0,0xe7a4, + 0xe8ac,0xe9a8,0xeaa8,0xebac,0xeca8,0xedac,0xeeac,0xefa8, + 0xf0a4,0xf1a0,0xf2a0,0xf3a4,0xf4a0,0xf5a4,0xf6a4,0xf7a0, + 0xf8a8,0xf9ac,0xfaac,0xfba8,0xfcac,0xfda8,0xfea8,0xffac, +}; + +/* cpTable[i] = (i & 0x80) | (((i & 0xff) == 0) << 6), i = 0..255 */ +static const uint8 cpTable[256] = { + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +}; + +/* remove comments to generate table contents +static void altairz80_init(void); +void (*sim_vm_init) (void) = &altairz80_init; +static void altairz80_init(void) { +*/ +/* parityTable */ +/* + uint32 i, v; + for (i = 0; i < 256; i++) { + v = ((i & 1) + ((i & 2) >> 1) + ((i & 4) >> 2) + ((i & 8) >> 3) + + ((i & 16) >> 4) + ((i & 32) >> 5) + ((i & 64) >> 6) + ((i & 128) >> 7)) % 2 ? 0 : 4; + printf("%1d,", v); + if ( ((i+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* incTable */ +/* + uint32 temp, v; + for (temp = 0; temp <= 256; temp++) { + v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | (((temp & 0xf) == 0) << 4); + printf("%3d,", v); + if ( ((temp+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* decTable */ +/* + uint32 temp, v; + for (temp = 0; temp < 256; temp++) { + v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | (((temp & 0xf) == 0xf) << 4) | 2; + printf("%3d,", v); + if ( ((temp+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* cbitsTable */ +/* + uint32 cbits, v; + for (cbits = 0; cbits < 512; cbits++) { + v = (cbits & 0x10) | ((cbits >> 8) & 1); + printf("%2d,", v); + if ( ((cbits+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* cbitsDup8Table */ +/* + uint32 cbits, v; + for (cbits = 0; cbits < 512; cbits++) { + v = (cbits & 0x10) | ((cbits >> 8) & 1) | ((cbits & 0xff) << 8) | (cbits & 0xa8) | (((cbits & 0xff) == 0) << 6); + printf("0x%04x,", v); + if ( ((cbits+1) & 0x7) == 0) { + printf("\n"); + } + } +*/ +/* cbitsDup16Table */ +/* + uint32 cbits, v; + for (cbits = 0; cbits < 512; cbits++) { + v = (cbits & 0x10) | ((cbits >> 8) & 1) | (cbits & 0x28); + printf("%2d,", v); + if ( ((cbits+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* cbits2Table */ +/* + uint32 cbits, v; + for (cbits = 0; cbits < 512; cbits++) { + v = (cbits & 0x10) | ((cbits >> 8) & 1) | 2; + printf("%2d,", v); + if ( ((cbits+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* rrcaTable */ +/* + uint32 temp, sum, v; + for (temp = 0; temp < 256; temp++) { + sum = temp >> 1; + v = ((temp & 1) << 15) | (sum << 8) | (sum & 0x28) | (temp & 1); + printf("0x%04x,", v); + if ( ((temp+1) & 0x7) == 0) { + printf("\n"); + } + } +*/ +/* rraTable */ +/* + uint32 temp, sum, v; + for (temp = 0; temp < 256; temp++) { + sum = temp >> 1; + v = (sum << 8) | (sum & 0x28) | (temp & 1); + printf("0x%04x,", v); + if ( ((temp+1) & 0x7) == 0) { + printf("\n"); + } + } +*/ +/* addTable */ +/* + uint32 sum, v; + for (sum = 0; sum < 512; sum++) { + v = ((sum & 0xff) << 8) | (sum & 0xa8) | (((sum & 0xff) == 0) << 6); + printf("0x%04x,", v); + if ( ((sum+1) & 0x7) == 0) { + printf("\n"); + } + } +*/ +/* subTable */ +/* + uint32 sum, v; + for (sum = 0; sum < 256; sum++) { + v = ((sum & 0xff) << 8) | (sum & 0xa8) | (((sum & 0xff) == 0) << 6) | 2; + printf("0x%04x,", v); + if ( ((sum+1) & 0x7) == 0) { + printf("\n"); + } + } +*/ +/* andTable */ +/* + uint32 sum, v; + for (sum = 0; sum < 256; sum++) { + v = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | 0x10 | parityTable[sum]; + printf("0x%04x,", v); + if ( ((sum+1) & 0x7) == 0) { + printf("\n"); + } + } +*/ +/* xororTable */ +/* + uint32 sum, v; + for (sum = 0; sum < 256; sum++) { + v = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | parityTable[sum]; + printf("0x%04x,", v); + if ( ((sum+1) & 0x7) == 0) { + printf("\n"); + } + } +*/ +/* rotateShiftTable */ +/* + uint32 temp, v; + for (temp = 0; temp < 256; temp++) { + v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | parity(temp); + printf("%3d,", v); + if ( ((temp+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* incZ80Table */ +/* + uint32 temp, v; + for (temp = 0; temp < 256; temp++) { + v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0) << 4) | ((temp == 0x80) << 2); + printf("%3d,", v); + if ( ((temp+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* decZ80Table */ +/* + uint32 temp, v; + for (temp = 0; temp < 256; temp++) { + v = (temp & 0xa8) | (((temp & 0xff) == 0) << 6) | + (((temp & 0xf) == 0xf) << 4) | ((temp == 0x7f) << 2) | 2; + printf("%3d,", v); + if ( ((temp+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* cbitsZ80Table */ +/* + uint32 cbits, v; + for (cbits = 0; cbits < 512; cbits++) { + v = (cbits & 0x10) | (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1); + printf("%2d,", v); + if ( ((cbits+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* cbitsZ80DupTable */ +/* + uint32 cbits, v; + for (cbits = 0; cbits < 512; cbits++) { + v = (cbits & 0x10) | (((cbits >> 6) ^ (cbits >> 5)) & 4) | + ((cbits >> 8) & 1) | (cbits & 0xa8); + printf("%3d,", v); + if ( ((cbits+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* cbits2Z80Table */ +/* + uint32 cbits, v; + for (cbits = 0; cbits < 512; cbits++) { + v = (((cbits >> 6) ^ (cbits >> 5)) & 4) | (cbits & 0x10) | 2 | ((cbits >> 8) & 1); + printf("%2d,", v); + if ( ((cbits+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* cbits2Z80DupTable */ +/* + uint32 cbits, v; + for (cbits = 0; cbits < 512; cbits++) { + v = (((cbits >> 6) ^ (cbits >> 5)) & 4) | (cbits & 0x10) | 2 | ((cbits >> 8) & 1) | + (cbits & 0xa8); + printf("%3d,", v); + if ( ((cbits+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* negTable */ +/* + uint32 temp, v; + for (temp = 0; temp < 256; temp++) { + v = (((temp & 0x0f) != 0) << 4) | ((temp == 0x80) << 2) | 2 | (temp != 0); + printf("%2d,", v); + if ( ((temp+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* rrdrldTable */ +/* + uint32 acu, v; + for (acu = 0; acu < 256; acu++) { + v = (acu << 8) | (acu & 0xa8) | (((acu & 0xff) == 0) << 6) | parityTable[acu]; + printf("0x%04x,", v); + if ( ((acu+1) & 0x7) == 0) { + printf("\n"); + } + } +*/ +/* cpTable */ +/* + uint32 sum, v; + for (sum = 0; sum < 256; sum++) { + v = (sum & 0x80) | (((sum & 0xff) == 0) << 6); + printf("%3d,", v); + if ( ((sum+1) & 0xf) == 0) { + printf("\n"); + } + } +*/ +/* remove comments to generate table contents +} +*/ + +static void warnUnsuccessfulWriteAttempt(const uint32 Addr) { if (cpu_unit.flags & UNIT_WARNROM) { if (addressIsInROM(Addr)) { message2("Attempt to write to ROM " AddressFormat ".\n", Addr); @@ -399,29 +1466,29 @@ void warnUnsuccessfulWriteAttempt(uint32 Addr) { } } -uint8 warnUnsuccessfulReadAttempt(uint32 Addr) { +static uint8 warnUnsuccessfulReadAttempt(const uint32 Addr) { if (cpu_unit.flags & UNIT_WARNROM) { message2("Attempt to read from non existing memory " AddressFormat ".\n", Addr); } return 0xff; } -/* Determine whether Addr points to Read Only Memory */ -int32 addressIsInROM(uint32 Addr) { - Addr &= ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */ +/* determine whether Addr points to Read Only Memory */ +int32 addressIsInROM(const uint32 Addr) { + uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */ return (cpu_unit.flags & UNIT_ROM) && ( /* must have ROM enabled */ /* in banked case we have standard Altair ROM */ - ((cpu_unit.flags & UNIT_BANKED) && (defaultROMLow <= Addr)) || + ((cpu_unit.flags & UNIT_BANKED) && (defaultROMLow <= addr)) || /* in non-banked case we check the bounds of the ROM */ - (((cpu_unit.flags & UNIT_BANKED) == 0) && (ROMLow <= Addr) && (Addr <= ROMHigh))); + (((cpu_unit.flags & UNIT_BANKED) == 0) && (ROMLow <= addr) && (addr <= ROMHigh))); } -/* Determine whether Addr points to a valid memory address */ -int32 addressExists(uint32 Addr) { - Addr &= ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */ - return (cpu_unit.flags & UNIT_BANKED) || (Addr < MEMSIZE) || +/* determine whether Addr points to a valid memory address */ +int32 addressExists(const uint32 Addr) { + uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */ + return (cpu_unit.flags & UNIT_BANKED) || (addr < MEMSIZE) || ((cpu_unit.flags & UNIT_BANKED) == 0) && (cpu_unit.flags & UNIT_ROM) - && (ROMLow <= Addr) && (Addr <= ROMHigh); + && (ROMLow <= addr) && (addr <= ROMHigh); } INLINE uint8 GetBYTE(register uint32 Addr) { @@ -460,6 +1527,10 @@ INLINE void PutBYTE(register uint32 Addr, register uint32 Value) { } } +void PutBYTEBasic(const uint32 Addr, const uint32 Bank, const uint32 Value) { + M[Addr & ADDRMASK][Bank & BANKMASK] = Value; +} + void PutBYTEForced(register uint32 Addr, register uint32 Value) { Addr &= ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */ if ((cpu_unit.flags & UNIT_BANKED) && (Addr < common)) { @@ -470,7 +1541,7 @@ void PutBYTEForced(register uint32 Addr, register uint32 Value) { } } -INLINE void PutWORD(register uint32 Addr, register uint32 Value) { +static INLINE void PutWORD(register uint32 Addr, register uint32 Value) { Addr &= ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */ if (cpu_unit.flags & UNIT_BANKED) { if (Addr < common) { @@ -527,43 +1598,35 @@ void PutBYTEWrapper(register uint32 Addr, register uint32 Value) { #define PutBYTE_mm(a,v) PutBYTE(a--, v) #define mm_PutBYTE(a,v) PutBYTE(--a, v) -INLINE uint16 GetWORD(register uint32 a) { +static INLINE uint16 GetWORD(register uint32 a) { return GetBYTE(a) | (GetBYTE(a + 1) << 8); } -#define MASK_BRK (TRUE+1) - -/* repeated from scp.c */ -struct brktab { - t_addr addr; - int32 typ; - int32 cnt; - char *act; -}; -typedef struct brktab BRKTAB; +#define MASK_BRK (TRUE + 1) /* this is a modified version of sim_brk_test with two differences: 1) is does not set sim_brk_pend to FALSE (this if left to the instruction decode) 2) it returns MASK_BRK if a breakpoint is found but should be ignored */ -int32 sim_brk_lookup (t_addr loc, int32 btyp) { - extern BRKTAB *sim_brk_fnd (t_addr loc); +static int32 sim_brk_lookup (const t_addr loc, const int32 btyp) { extern t_bool sim_brk_pend; extern t_addr sim_brk_ploc; + extern char *sim_brk_act; BRKTAB *bp; - if ((bp = sim_brk_fnd (loc)) && - (btyp & bp -> typ) && - (!sim_brk_pend || (loc != sim_brk_ploc)) && - (--(bp -> cnt) <= 0)) { - bp -> cnt = 0; - sim_brk_ploc = loc; - sim_brk_pend = TRUE; + if ((bp = sim_brk_fnd (loc)) && /* entry in table? */ + (btyp & bp -> typ) && /* type match? */ + (!sim_brk_pend || (loc != sim_brk_ploc)) && /* new location? */ + (--(bp -> cnt) <= 0)) { /* count reach 0? */ + bp -> cnt = 0; /* reset count */ + sim_brk_ploc = loc; /* save location */ + sim_brk_act = bp -> act; /* set up actions */ + sim_brk_pend = TRUE; /* don't do twice */ return TRUE; } return (sim_brk_pend && (loc == sim_brk_ploc)) ? MASK_BRK : FALSE; } -void prepareMemoryAccessMessage(t_addr loc) { +static void prepareMemoryAccessMessage(t_addr loc) { sprintf(memoryAccessMessage, "Memory access breakpoint [%04xh]", loc); } @@ -604,14 +1667,17 @@ void prepareMemoryAccessMessage(t_addr loc) { #define CheckBreakTwoBytes(a1, a2) CheckBreakTwoBytesExtended(a1, a2,;) -#define CheckBreakWord(a) CheckBreakTwoBytes(a, (a+1)) +#define CheckBreakWord(a) CheckBreakTwoBytes(a, (a + 1)) int32 sim_instr (void) { extern int32 sim_interval; extern t_bool sim_brk_pend; extern int32 timerInterrupt; extern int32 timerInterruptHandler; + extern uint32 sim_os_msec(void); + extern t_bool rtc_avail; int32 reason = 0; + register uint32 specialProcessing; register uint32 AF; register uint32 BC; register uint32 DE; @@ -622,7 +1688,12 @@ int32 sim_instr (void) { register uint32 IY; register uint32 temp, acu, sum, cbits; register uint32 op, adr; - int32 br1, br2; + /* tStates contains the number of t-states executed. One t-state is executed + in one microsecond on a 1MHz CPU. tStates is used real-time simulation */ + register uint32 tStates; + uint32 tStatesInSlice; /* number of t-states in 10 mSec time-slice */ + uint32 startTime; + int32 br1, br2, tStateModifier; pc = saved_PC & ADDRMASK; /* load local PC */ af[af_sel] = AF_S; @@ -637,7 +1708,7 @@ int32 sim_instr (void) { regs[1 - regs_sel].de = DE1_S; regs[1 - regs_sel].hl = HL1_S; IFF = IFF_S; - ir = INT_S; + ir = IR_S; AF = af[af_sel]; BC = regs[regs_sel].bc; @@ -647,27 +1718,49 @@ int32 sim_instr (void) { SP = sp; IX = ix; IY = iy; + specialProcessing = clockFrequency | timerInterrupt | sim_brk_summ; + tStates = 0; + if (rtc_avail) { + startTime = sim_os_msec(); + tStatesInSlice = sliceLength*clockFrequency; + } + else { /* make sure that sim_os_msec() is not called later */ + clockFrequency = startTime = tStatesInSlice = 0; + } - /* Main instruction fetch/decode loop */ + /* main instruction fetch/decode loop */ while (TRUE) { /* loop until halted */ if (sim_interval <= 0) { /* check clock queue */ if (reason = sim_process_event()) { break; } + else { + specialProcessing = clockFrequency | timerInterrupt | sim_brk_summ; + } } - if (timerInterrupt && (IFF & 1)) { - timerInterrupt = FALSE; - IFF = 0; /* disable interrupts */ - CheckBreakTwoBytesExtended(SP - 2, SP - 1, (timerInterrupt = TRUE, IFF |= 1)); - PUSH(PC); - PCQ_ENTRY(PC - 1); - PC = timerInterruptHandler & ADDRMASK; - } + if (specialProcessing) { /* quick check for special processing */ + if (clockFrequency && (tStates >= tStatesInSlice)) { + /* clockFrequency != 0 implies that real time clock is available */ + startTime += sliceLength; + tStates -= tStatesInSlice; + while (sim_os_msec() <= startTime) {} /* poor man's sleep */ + } - if (sim_brk_summ && (sim_brk_lookup(PC, SWMASK('E')) == TRUE)) { /* breakpoint? */ - reason = STOP_IBKPT; /* stop simulation */ - break; + if (timerInterrupt && (IFF & 1)) { + timerInterrupt = FALSE; + specialProcessing = clockFrequency | sim_brk_summ; + IFF = 0; /* disable interrupts */ + CheckBreakTwoBytesExtended(SP - 2, SP - 1, (timerInterrupt = TRUE, IFF |= 1)); + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = timerInterruptHandler & ADDRMASK; + } + + if (sim_brk_summ && (sim_brk_lookup(PC, SWMASK('E')) == TRUE)) { /* breakpoint? */ + reason = STOP_IBKPT; /* stop simulation */ + break; + } } PCX = PC; @@ -679,49 +1772,52 @@ int32 sim_instr (void) { */ switch(RAM_pp(PC)) { case 0x00: /* NOP */ + tStates += 4; sim_brk_pend = FALSE; break; case 0x01: /* LD BC,nnnn */ + tStates += 10; sim_brk_pend = FALSE; BC = GetWORD(PC); PC += 2; break; case 0x02: /* LD (BC),A */ + tStates += 7; CheckBreakByte(BC) PutBYTE(BC, hreg(AF)); break; case 0x03: /* INC BC */ + tStates += 6; sim_brk_pend = FALSE; ++BC; break; case 0x04: /* INC B */ + tStates += 4; sim_brk_pend = FALSE; BC += 0x100; temp = hreg(BC); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - SetPV2(0x80); + AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x05: /* DEC B */ + tStates += 4; sim_brk_pend = FALSE; BC -= 0x100; temp = hreg(BC); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - SetPV2(0x7f) | 2; + AF = (AF & ~0xfe) | decTable[temp] | SetPV2(0x7f); break; case 0x06: /* LD B,nn */ + tStates += 7; sim_brk_pend = FALSE; Sethreg(BC, RAM_pp(PC)); break; case 0x07: /* RLCA */ + tStates += 4; sim_brk_pend = FALSE; AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) | (AF & 0xc4) | ((AF >> 15) & 1); break; case 0x08: /* EX AF,AF' */ + tStates += 4; sim_brk_pend = FALSE; checkCPU8080; af[af_sel] = AF; @@ -729,51 +1825,47 @@ int32 sim_instr (void) { AF = af[af_sel]; break; case 0x09: /* ADD HL,BC */ + tStates += 11; sim_brk_pend = FALSE; HL &= ADDRMASK; BC &= ADDRMASK; sum = HL + BC; - cbits = (HL ^ BC ^ sum) >> 8; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ BC ^ sum) >> 8]; HL = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); break; case 0x0a: /* LD A,(BC) */ + tStates += 7; CheckBreakByte(BC) Sethreg(AF, GetBYTE(BC)); break; case 0x0b: /* DEC BC */ + tStates += 6; sim_brk_pend = FALSE; --BC; break; case 0x0c: /* INC C */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC) + 1; Setlreg(BC, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - SetPV2(0x80); + AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x0d: /* DEC C */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC) - 1; Setlreg(BC, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - SetPV2(0x7f) | 2; + AF = (AF & ~0xfe) | decTable[temp & 0xff] | SetPV2(0x7f); break; case 0x0e: /* LD C,nn */ + tStates += 7; sim_brk_pend = FALSE; Setlreg(BC, RAM_pp(PC)); break; case 0x0f: /* RRCA */ + tStates += 4; sim_brk_pend = FALSE; - temp = hreg(AF); - sum = temp >> 1; - AF = ((temp & 1) << 15) | (sum << 8) | - (sum & 0x28) | (AF & 0xc4) | (temp & 1); + AF = (AF & 0xc4) | rrcaTable[hreg(AF)]; break; case 0x10: /* DJNZ dd */ sim_brk_pend = FALSE; @@ -781,153 +1873,156 @@ int32 sim_instr (void) { if ((BC -= 0x100) & 0xff00) { PCQ_ENTRY(PC - 1); PC += (signed char) GetBYTE(PC) + 1; + tStates += 13; } else { PC++; + tStates += 8; } break; case 0x11: /* LD DE,nnnn */ + tStates += 10; sim_brk_pend = FALSE; DE = GetWORD(PC); PC += 2; break; case 0x12: /* LD (DE),A */ + tStates += 7; CheckBreakByte(DE) PutBYTE(DE, hreg(AF)); break; case 0x13: /* INC DE */ + tStates += 6; sim_brk_pend = FALSE; ++DE; break; case 0x14: /* INC D */ + tStates += 4; sim_brk_pend = FALSE; DE += 0x100; temp = hreg(DE); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - SetPV2(0x80); + AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x15: /* DEC D */ + tStates += 4; sim_brk_pend = FALSE; DE -= 0x100; temp = hreg(DE); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - SetPV2(0x7f) | 2; + AF = (AF & ~0xfe) | decTable[temp] | SetPV2(0x7f); break; case 0x16: /* LD D,nn */ + tStates += 7; sim_brk_pend = FALSE; Sethreg(DE, RAM_pp(PC)); break; case 0x17: /* RLA */ + tStates += 4; sim_brk_pend = FALSE; AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) | (AF & 0xc4) | ((AF >> 15) & 1); break; case 0x18: /* JR dd */ + tStates += 12; sim_brk_pend = FALSE; checkCPU8080; PCQ_ENTRY(PC - 1); PC += (signed char) GetBYTE(PC) + 1; break; case 0x19: /* ADD HL,DE */ + tStates += 11; sim_brk_pend = FALSE; HL &= ADDRMASK; DE &= ADDRMASK; sum = HL + DE; - cbits = (HL ^ DE ^ sum) >> 8; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ DE ^ sum) >> 8]; HL = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); break; case 0x1a: /* LD A,(DE) */ + tStates += 7; CheckBreakByte(DE) Sethreg(AF, GetBYTE(DE)); break; case 0x1b: /* DEC DE */ + tStates += 6; sim_brk_pend = FALSE; --DE; break; case 0x1c: /* INC E */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE) + 1; Setlreg(DE, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - SetPV2(0x80); + AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x1d: /* DEC E */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE) - 1; Setlreg(DE, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - SetPV2(0x7f) | 2; + AF = (AF & ~0xfe) | decTable[temp & 0xff] | SetPV2(0x7f); break; case 0x1e: /* LD E,nn */ + tStates += 7; sim_brk_pend = FALSE; Setlreg(DE, RAM_pp(PC)); break; case 0x1f: /* RRA */ + tStates += 4; sim_brk_pend = FALSE; - temp = hreg(AF); - sum = temp >> 1; - AF = ((AF & 1) << 15) | (sum << 8) | - (sum & 0x28) | (AF & 0xc4) | (temp & 1); + AF = ((AF & 1) << 15) | (AF & 0xc4) | rraTable[hreg(AF)]; break; case 0x20: /* JR NZ,dd */ sim_brk_pend = FALSE; checkCPU8080; if (TSTFLAG(Z)) { PC++; + tStates += 7; } else { PCQ_ENTRY(PC - 1); PC += (signed char) GetBYTE(PC) + 1; + tStates += 12; } break; case 0x21: /* LD HL,nnnn */ + tStates += 10; sim_brk_pend = FALSE; HL = GetWORD(PC); PC += 2; break; case 0x22: /* LD (nnnn),HL */ + tStates += 16; temp = GetWORD(PC); CheckBreakWord(temp); PutWORD(temp, HL); PC += 2; break; case 0x23: /* INC HL */ + tStates += 6; sim_brk_pend = FALSE; ++HL; break; case 0x24: /* INC H */ + tStates += 4; sim_brk_pend = FALSE; HL += 0x100; temp = hreg(HL); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - SetPV2(0x80); + AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x25: /* DEC H */ + tStates += 4; sim_brk_pend = FALSE; HL -= 0x100; temp = hreg(HL); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - SetPV2(0x7f) | 2; + AF = (AF & ~0xfe) | decTable[temp] | SetPV2(0x7f); break; case 0x26: /* LD H,nn */ + tStates += 7; sim_brk_pend = FALSE; Sethreg(HL, RAM_pp(PC)); break; case 0x27: /* DAA */ + tStates += 4; sim_brk_pend = FALSE; acu = hreg(AF); temp = ldig(acu); @@ -954,10 +2049,7 @@ int32 sim_instr (void) { acu += 0x60; } } - cbits |= (acu >> 8) & 1; - acu &= 0xff; - AF = (acu << 8) | (acu & 0xa8) | ((acu == 0) << 6) | - (AF & 0x12) | partab[acu] | cbits; + AF = (AF & 0x12) | rrdrldTable[acu & 0xff] | (acu >> 8) & 1 | cbits; break; case 0x28: /* JR Z,dd */ sim_brk_pend = FALSE; @@ -965,53 +2057,54 @@ int32 sim_instr (void) { if (TSTFLAG(Z)) { PCQ_ENTRY(PC - 1); PC += (signed char) GetBYTE(PC) + 1; + tStates += 12; } else { PC++; + tStates += 7; } break; case 0x29: /* ADD HL,HL */ + tStates += 11; sim_brk_pend = FALSE; HL &= ADDRMASK; sum = HL + HL; - cbits = (HL ^ HL ^ sum) >> 8; + AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8]; HL = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); break; case 0x2a: /* LD HL,(nnnn) */ + tStates += 16; temp = GetWORD(PC); CheckBreakWord(temp); HL = GetWORD(temp); PC += 2; break; case 0x2b: /* DEC HL */ + tStates += 6; sim_brk_pend = FALSE; --HL; break; case 0x2c: /* INC L */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL) + 1; Setlreg(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - SetPV2(0x80); + AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x2d: /* DEC L */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL) - 1; Setlreg(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - SetPV2(0x7f) | 2; + AF = (AF & ~0xfe) | decTable[temp & 0xff] | SetPV2(0x7f); break; case 0x2e: /* LD L,nn */ + tStates += 7; sim_brk_pend = FALSE; Setlreg(HL, RAM_pp(PC)); break; case 0x2f: /* CPL */ + tStates += 4; sim_brk_pend = FALSE; AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12; break; @@ -1020,52 +2113,55 @@ int32 sim_instr (void) { checkCPU8080; if (TSTFLAG(C)) { PC++; + tStates += 7; } else { PCQ_ENTRY(PC - 1); PC += (signed char) GetBYTE(PC) + 1; + tStates += 12; } break; case 0x31: /* LD SP,nnnn */ + tStates += 10; sim_brk_pend = FALSE; SP = GetWORD(PC); PC += 2; break; case 0x32: /* LD (nnnn),A */ + tStates += 13; temp = GetWORD(PC); CheckBreakByte(temp); PutBYTE(temp, hreg(AF)); PC += 2; break; case 0x33: /* INC SP */ + tStates += 6; sim_brk_pend = FALSE; ++SP; break; case 0x34: /* INC (HL) */ + tStates += 11; CheckBreakByte(HL); temp = GetBYTE(HL) + 1; PutBYTE(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - SetPV2(0x80); + AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x35: /* DEC (HL) */ + tStates += 11; CheckBreakByte(HL); temp = GetBYTE(HL) - 1; PutBYTE(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - SetPV2(0x7f) | 2; + AF = (AF & ~0xfe) | decTable[temp & 0xff] | SetPV2(0x7f); break; case 0x36: /* LD (HL),nn */ + tStates += 10; CheckBreakByte(HL); PutBYTE(HL, RAM_pp(PC)); break; case 0x37: /* SCF */ + tStates += 4; sim_brk_pend = FALSE; - AF = (AF & ~0x3b) | ((AF>>8) & 0x28) | 1; + AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | 1; break; case 0x38: /* JR C,dd */ sim_brk_pend = FALSE; @@ -1073,1114 +2169,1147 @@ int32 sim_instr (void) { if (TSTFLAG(C)) { PCQ_ENTRY(PC - 1); PC += (signed char) GetBYTE(PC) + 1; + tStates += 12; } else { PC++; + tStates += 7; } break; case 0x39: /* ADD HL,SP */ + tStates += 11; sim_brk_pend = FALSE; HL &= ADDRMASK; SP &= ADDRMASK; sum = HL + SP; - cbits = (HL ^ SP ^ sum) >> 8; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ SP ^ sum) >> 8]; HL = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); break; case 0x3a: /* LD A,(nnnn) */ + tStates += 13; temp = GetWORD(PC); CheckBreakByte(temp); Sethreg(AF, GetBYTE(temp)); PC += 2; break; case 0x3b: /* DEC SP */ + tStates += 6; sim_brk_pend = FALSE; --SP; break; case 0x3c: /* INC A */ + tStates += 4; sim_brk_pend = FALSE; AF += 0x100; temp = hreg(AF); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - SetPV2(0x80); + AF = (AF & ~0xfe) | incTable[temp] | SetPV2(0x80); break; case 0x3d: /* DEC A */ + tStates += 4; sim_brk_pend = FALSE; AF -= 0x100; temp = hreg(AF); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - SetPV2(0x7f) | 2; + AF = (AF & ~0xfe) | decTable[temp] | SetPV2(0x7f); break; case 0x3e: /* LD A,nn */ + tStates += 7; sim_brk_pend = FALSE; Sethreg(AF, RAM_pp(PC)); break; case 0x3f: /* CCF */ + tStates += 4; sim_brk_pend = FALSE; - AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | - ((AF & 1) << 4) | (~AF & 1); + AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | ((AF & 1) << 4) | (~AF & 1); break; case 0x40: /* LD B,B */ - sim_brk_pend = FALSE; - /* nop */ + tStates += 4; + sim_brk_pend = FALSE; /* nop */ break; case 0x41: /* LD B,C */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & 255) | ((BC & 255) << 8); + BC = (BC & 0xff) | ((BC & 0xff) << 8); break; case 0x42: /* LD B,D */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & 255) | (DE & ~255); + BC = (BC & 0xff) | (DE & ~0xff); break; case 0x43: /* LD B,E */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & 255) | ((DE & 255) << 8); + BC = (BC & 0xff) | ((DE & 0xff) << 8); break; case 0x44: /* LD B,H */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & 255) | (HL & ~255); + BC = (BC & 0xff) | (HL & ~0xff); break; case 0x45: /* LD B,L */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & 255) | ((HL & 255) << 8); + BC = (BC & 0xff) | ((HL & 0xff) << 8); break; case 0x46: /* LD B,(HL) */ + tStates += 7; CheckBreakByte(HL); Sethreg(BC, GetBYTE(HL)); break; case 0x47: /* LD B,A */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & 255) | (AF & ~255); + BC = (BC & 0xff) | (AF & ~0xff); break; case 0x48: /* LD C,B */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & ~255) | ((BC >> 8) & 255); + BC = (BC & ~0xff) | ((BC >> 8) & 0xff); break; case 0x49: /* LD C,C */ - sim_brk_pend = FALSE; - /* nop */ + tStates += 4; + sim_brk_pend = FALSE; /* nop */ break; case 0x4a: /* LD C,D */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & ~255) | ((DE >> 8) & 255); + BC = (BC & ~0xff) | ((DE >> 8) & 0xff); break; case 0x4b: /* LD C,E */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & ~255) | (DE & 255); + BC = (BC & ~0xff) | (DE & 0xff); break; case 0x4c: /* LD C,H */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & ~255) | ((HL >> 8) & 255); + BC = (BC & ~0xff) | ((HL >> 8) & 0xff); break; case 0x4d: /* LD C,L */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & ~255) | (HL & 255); + BC = (BC & ~0xff) | (HL & 0xff); break; case 0x4e: /* LD C,(HL) */ + tStates += 7; CheckBreakByte(HL); Setlreg(BC, GetBYTE(HL)); break; case 0x4f: /* LD C,A */ + tStates += 4; sim_brk_pend = FALSE; - BC = (BC & ~255) | ((AF >> 8) & 255); + BC = (BC & ~0xff) | ((AF >> 8) & 0xff); break; case 0x50: /* LD D,B */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & 255) | (BC & ~255); + DE = (DE & 0xff) | (BC & ~0xff); break; case 0x51: /* LD D,C */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & 255) | ((BC & 255) << 8); + DE = (DE & 0xff) | ((BC & 0xff) << 8); break; case 0x52: /* LD D,D */ - sim_brk_pend = FALSE; - /* nop */ + tStates += 4; + sim_brk_pend = FALSE; /* nop */ break; case 0x53: /* LD D,E */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & 255) | ((DE & 255) << 8); + DE = (DE & 0xff) | ((DE & 0xff) << 8); break; case 0x54: /* LD D,H */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & 255) | (HL & ~255); + DE = (DE & 0xff) | (HL & ~0xff); break; case 0x55: /* LD D,L */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & 255) | ((HL & 255) << 8); + DE = (DE & 0xff) | ((HL & 0xff) << 8); break; case 0x56: /* LD D,(HL) */ + tStates += 7; CheckBreakByte(HL); Sethreg(DE, GetBYTE(HL)); break; case 0x57: /* LD D,A */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & 255) | (AF & ~255); + DE = (DE & 0xff) | (AF & ~0xff); break; case 0x58: /* LD E,B */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & ~255) | ((BC >> 8) & 255); + DE = (DE & ~0xff) | ((BC >> 8) & 0xff); break; case 0x59: /* LD E,C */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & ~255) | (BC & 255); + DE = (DE & ~0xff) | (BC & 0xff); break; case 0x5a: /* LD E,D */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & ~255) | ((DE >> 8) & 255); + DE = (DE & ~0xff) | ((DE >> 8) & 0xff); break; case 0x5b: /* LD E,E */ - sim_brk_pend = FALSE; - /* nop */ + tStates += 4; + sim_brk_pend = FALSE; /* nop */ break; case 0x5c: /* LD E,H */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & ~255) | ((HL >> 8) & 255); + DE = (DE & ~0xff) | ((HL >> 8) & 0xff); break; case 0x5d: /* LD E,L */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & ~255) | (HL & 255); + DE = (DE & ~0xff) | (HL & 0xff); break; case 0x5e: /* LD E,(HL) */ + tStates += 7; CheckBreakByte(HL); Setlreg(DE, GetBYTE(HL)); break; case 0x5f: /* LD E,A */ + tStates += 4; sim_brk_pend = FALSE; - DE = (DE & ~255) | ((AF >> 8) & 255); + DE = (DE & ~0xff) | ((AF >> 8) & 0xff); break; case 0x60: /* LD H,B */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & 255) | (BC & ~255); + HL = (HL & 0xff) | (BC & ~0xff); break; case 0x61: /* LD H,C */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & 255) | ((BC & 255) << 8); + HL = (HL & 0xff) | ((BC & 0xff) << 8); break; case 0x62: /* LD H,D */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & 255) | (DE & ~255); + HL = (HL & 0xff) | (DE & ~0xff); break; case 0x63: /* LD H,E */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & 255) | ((DE & 255) << 8); + HL = (HL & 0xff) | ((DE & 0xff) << 8); break; case 0x64: /* LD H,H */ - sim_brk_pend = FALSE; - /* nop */ + tStates += 4; + sim_brk_pend = FALSE; /* nop */ break; case 0x65: /* LD H,L */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & 255) | ((HL & 255) << 8); + HL = (HL & 0xff) | ((HL & 0xff) << 8); break; case 0x66: /* LD H,(HL) */ + tStates += 7; CheckBreakByte(HL); Sethreg(HL, GetBYTE(HL)); break; case 0x67: /* LD H,A */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & 255) | (AF & ~255); + HL = (HL & 0xff) | (AF & ~0xff); break; case 0x68: /* LD L,B */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & ~255) | ((BC >> 8) & 255); + HL = (HL & ~0xff) | ((BC >> 8) & 0xff); break; case 0x69: /* LD L,C */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & ~255) | (BC & 255); + HL = (HL & ~0xff) | (BC & 0xff); break; case 0x6a: /* LD L,D */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & ~255) | ((DE >> 8) & 255); + HL = (HL & ~0xff) | ((DE >> 8) & 0xff); break; case 0x6b: /* LD L,E */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & ~255) | (DE & 255); + HL = (HL & ~0xff) | (DE & 0xff); break; case 0x6c: /* LD L,H */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & ~255) | ((HL >> 8) & 255); + HL = (HL & ~0xff) | ((HL >> 8) & 0xff); break; case 0x6d: /* LD L,L */ - sim_brk_pend = FALSE; - /* nop */ + tStates += 4; + sim_brk_pend = FALSE; /* nop */ break; case 0x6e: /* LD L,(HL) */ + tStates += 7; CheckBreakByte(HL); Setlreg(HL, GetBYTE(HL)); break; case 0x6f: /* LD L,A */ + tStates += 4; sim_brk_pend = FALSE; - HL = (HL & ~255) | ((AF >> 8) & 255); + HL = (HL & ~0xff) | ((AF >> 8) & 0xff); break; case 0x70: /* LD (HL),B */ + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, hreg(BC)); break; case 0x71: /* LD (HL),C */ + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, lreg(BC)); break; case 0x72: /* LD (HL),D */ + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, hreg(DE)); break; case 0x73: /* LD (HL),E */ + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, lreg(DE)); break; case 0x74: /* LD (HL),H */ + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, hreg(HL)); break; case 0x75: /* LD (HL),L */ + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, lreg(HL)); break; case 0x76: /* HALT */ + tStates += 4; sim_brk_pend = FALSE; reason = STOP_HALT; PC--; goto end_decode; case 0x77: /* LD (HL),A */ + tStates += 7; CheckBreakByte(HL); PutBYTE(HL, hreg(AF)); break; case 0x78: /* LD A,B */ + tStates += 4; sim_brk_pend = FALSE; - AF = (AF & 255) | (BC & ~255); + AF = (AF & 0xff) | (BC & ~0xff); break; case 0x79: /* LD A,C */ + tStates += 4; sim_brk_pend = FALSE; - AF = (AF & 255) | ((BC & 255) << 8); + AF = (AF & 0xff) | ((BC & 0xff) << 8); break; case 0x7a: /* LD A,D */ + tStates += 4; sim_brk_pend = FALSE; - AF = (AF & 255) | (DE & ~255); + AF = (AF & 0xff) | (DE & ~0xff); break; case 0x7b: /* LD A,E */ + tStates += 4; sim_brk_pend = FALSE; - AF = (AF & 255) | ((DE & 255) << 8); + AF = (AF & 0xff) | ((DE & 0xff) << 8); break; case 0x7c: /* LD A,H */ + tStates += 4; sim_brk_pend = FALSE; - AF = (AF & 255) | (HL & ~255); + AF = (AF & 0xff) | (HL & ~0xff); break; case 0x7d: /* LD A,L */ + tStates += 4; sim_brk_pend = FALSE; - AF = (AF & 255) | ((HL & 255) << 8); + AF = (AF & 0xff) | ((HL & 0xff) << 8); break; case 0x7e: /* LD A,(HL) */ + tStates += 7; CheckBreakByte(HL); Sethreg(AF, GetBYTE(HL)); break; case 0x7f: /* LD A,A */ - sim_brk_pend = FALSE; - /* nop */ + tStates += 4; + sim_brk_pend = FALSE; /* nop */ break; case 0x80: /* ADD A,B */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); acu = hreg(AF); sum = acu + temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x81: /* ADD A,C */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); acu = hreg(AF); sum = acu + temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x82: /* ADD A,D */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); acu = hreg(AF); sum = acu + temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x83: /* ADD A,E */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); acu = hreg(AF); sum = acu + temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x84: /* ADD A,H */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); acu = hreg(AF); sum = acu + temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x85: /* ADD A,L */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); acu = hreg(AF); sum = acu + temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x86: /* ADD A,(HL) */ + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); acu = hreg(AF); sum = acu + temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x87: /* ADD A,A */ + tStates += 4; sim_brk_pend = FALSE; - temp = hreg(AF); - acu = hreg(AF); - sum = acu + temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + cbits = 2 * hreg(AF); + AF = cbitsDup8Table[cbits] | (SetPVS(cbits)); break; case 0x88: /* ADC A,B */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); acu = hreg(AF); sum = acu + temp + TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x89: /* ADC A,C */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); acu = hreg(AF); sum = acu + temp + TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8a: /* ADC A,D */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); acu = hreg(AF); sum = acu + temp + TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8b: /* ADC A,E */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); acu = hreg(AF); sum = acu + temp + TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8c: /* ADC A,H */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); acu = hreg(AF); sum = acu + temp + TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8d: /* ADC A,L */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); acu = hreg(AF); sum = acu + temp + TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8e: /* ADC A,(HL) */ + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); acu = hreg(AF); sum = acu + temp + TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0x8f: /* ADC A,A */ + tStates += 4; sim_brk_pend = FALSE; - temp = hreg(AF); - acu = hreg(AF); - sum = acu + temp + TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + cbits = 2 * hreg(AF) + TSTFLAG(C); + AF = cbitsDup8Table[cbits] | (SetPVS(cbits)); break; case 0x90: /* SUB B */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x91: /* SUB C */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x92: /* SUB D */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x93: /* SUB E */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x94: /* SUB H */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x95: /* SUB L */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x96: /* SUB (HL) */ + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x97: /* SUB A */ + tStates += 4; sim_brk_pend = FALSE; - temp = hreg(AF); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = cpu_unit.flags & UNIT_CHIP ? 0x42 : 0x46; break; case 0x98: /* SBC A,B */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); acu = hreg(AF); sum = acu - temp - TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x99: /* SBC A,C */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); acu = hreg(AF); sum = acu - temp - TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9a: /* SBC A,D */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); acu = hreg(AF); sum = acu - temp - TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9b: /* SBC A,E */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); acu = hreg(AF); sum = acu - temp - TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9c: /* SBC A,H */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); acu = hreg(AF); sum = acu - temp - TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9d: /* SBC A,L */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); acu = hreg(AF); sum = acu - temp - TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9e: /* SBC A,(HL) */ + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); acu = hreg(AF); sum = acu - temp - TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0x9f: /* SBC A,A */ + tStates += 4; sim_brk_pend = FALSE; - temp = hreg(AF); - acu = hreg(AF); - sum = acu - temp - TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + cbits = -TSTFLAG(C); + AF = subTable[cbits & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPVS(cbits)); break; case 0xa0: /* AND B */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF & (BC)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; + AF = andTable[((AF & BC) >> 8) & 0xff]; break; case 0xa1: /* AND C */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) & BC) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; + AF = andTable[((AF >> 8) & BC) & 0xff]; break; case 0xa2: /* AND D */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF & (DE)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; + AF = andTable[((AF & DE) >> 8) & 0xff]; break; case 0xa3: /* AND E */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) & DE) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; + AF = andTable[((AF >> 8) & DE) & 0xff]; break; case 0xa4: /* AND H */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF & (HL)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; + AF = andTable[((AF & HL) >> 8) & 0xff]; break; case 0xa5: /* AND L */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) & HL) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; + AF = andTable[((AF >> 8) & HL) & 0xff]; break; case 0xa6: /* AND (HL) */ + tStates += 7; CheckBreakByte(HL); - sum = ((AF >> 8) & GetBYTE(HL)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; + AF = andTable[((AF >> 8) & GetBYTE(HL)) & 0xff]; break; case 0xa7: /* AND A */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF & (AF)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; + AF = andTable[(AF >> 8) & 0xff]; break; case 0xa8: /* XOR B */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF ^ (BC)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF ^ BC) >> 8) & 0xff]; break; case 0xa9: /* XOR C */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) ^ BC) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) ^ BC) & 0xff]; break; case 0xaa: /* XOR D */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF ^ (DE)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF ^ DE) >> 8) & 0xff]; break; case 0xab: /* XOR E */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) ^ DE) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) ^ DE) & 0xff]; break; case 0xac: /* XOR H */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF ^ (HL)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF ^ HL) >> 8) & 0xff]; break; case 0xad: /* XOR L */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) ^ HL) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) ^ HL) & 0xff]; break; case 0xae: /* XOR (HL) */ + tStates += 7; CheckBreakByte(HL); - sum = ((AF >> 8) ^ GetBYTE(HL)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) ^ GetBYTE(HL)) & 0xff]; break; case 0xaf: /* XOR A */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF ^ (AF)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = 0x44; break; case 0xb0: /* OR B */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF | (BC)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF | BC) >> 8) & 0xff]; break; case 0xb1: /* OR C */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) | BC) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) | BC) & 0xff]; break; case 0xb2: /* OR D */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF | (DE)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF | DE) >> 8) & 0xff]; break; case 0xb3: /* OR E */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) | DE) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) | DE) & 0xff]; break; case 0xb4: /* OR H */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF | (HL)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF | HL) >> 8) & 0xff]; break; case 0xb5: /* OR L */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF >> 8) | HL) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) | HL) & 0xff]; break; case 0xb6: /* OR (HL) */ + tStates += 7; CheckBreakByte(HL); - sum = ((AF >> 8) | GetBYTE(HL)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) | GetBYTE(HL)) & 0xff]; break; case 0xb7: /* OR A */ + tStates += 4; sim_brk_pend = FALSE; - sum = ((AF | (AF)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[(AF >> 8) & 0xff]; break; case 0xb8: /* CP B */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(BC); AF = (AF & ~0x28) | (temp & 0x28); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xb9: /* CP C */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(BC); AF = (AF & ~0x28) | (temp & 0x28); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xba: /* CP D */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(DE); AF = (AF & ~0x28) | (temp & 0x28); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbb: /* CP E */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(DE); AF = (AF & ~0x28) | (temp & 0x28); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbc: /* CP H */ + tStates += 4; sim_brk_pend = FALSE; temp = hreg(HL); AF = (AF & ~0x28) | (temp & 0x28); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbd: /* CP L */ + tStates += 4; sim_brk_pend = FALSE; temp = lreg(HL); AF = (AF & ~0x28) | (temp & 0x28); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbe: /* CP (HL) */ + tStates += 7; CheckBreakByte(HL); temp = GetBYTE(HL); AF = (AF & ~0x28) | (temp & 0x28); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xbf: /* CP A */ + tStates += 4; sim_brk_pend = FALSE; - temp = hreg(AF); - AF = (AF & ~0x28) | (temp & 0x28); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + Setlreg(AF, (hreg(AF) & 0x28) | (cpu_unit.flags & UNIT_CHIP ? 0x42 : 0x46)); break; case 0xc0: /* RET NZ */ if (TSTFLAG(Z)) { sim_brk_pend = FALSE; + tStates += 5; } else { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); + tStates += 11; } break; case 0xc1: /* POP BC */ + tStates += 10; CheckBreakWord(SP); POP(BC); break; case 0xc2: /* JP NZ,nnnn */ sim_brk_pend = FALSE; - JPC(!TSTFLAG(Z)); + JPC(!TSTFLAG(Z)); /* also updates tStates */ break; case 0xc3: /* JP nnnn */ sim_brk_pend = FALSE; - JPC(1); + JPC(1); /* also updates tStates */ break; case 0xc4: /* CALL NZ,nnnn */ - CALLC(!TSTFLAG(Z)); + CALLC(!TSTFLAG(Z)); /* also updates tStates */ break; case 0xc5: /* PUSH BC */ + tStates += 11; CheckBreakWord(SP - 2); PUSH(BC); break; case 0xc6: /* ADD A,nn */ + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); acu = hreg(AF); sum = acu + temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0xc7: /* RST 0 */ + tStates += 11; CheckBreakWord(SP - 2); - PUSH(PC); PCQ_ENTRY(PC - 1); PC = 0; + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = 0; break; case 0xc8: /* RET Z */ if (TSTFLAG(Z)) { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); + tStates += 11; } else { sim_brk_pend = FALSE; + tStates += 5; } break; case 0xc9: /* RET */ + tStates += 10; CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); break; case 0xca: /* JP Z,nnnn */ sim_brk_pend = FALSE; - JPC(TSTFLAG(Z)); + JPC(TSTFLAG(Z)); /* also updates tStates */ break; case 0xcb: /* CB prefix */ checkCPU8080; adr = HL; switch ((op = GetBYTE(PC)) & 7) { - case 0: sim_brk_pend = FALSE; ++PC; acu = hreg(BC); break; - case 1: sim_brk_pend = FALSE; ++PC; acu = lreg(BC); break; - case 2: sim_brk_pend = FALSE; ++PC; acu = hreg(DE); break; - case 3: sim_brk_pend = FALSE; ++PC; acu = lreg(DE); break; - case 4: sim_brk_pend = FALSE; ++PC; acu = hreg(HL); break; - case 5: sim_brk_pend = FALSE; ++PC; acu = lreg(HL); break; - case 6: CheckBreakByte(adr); ++PC; acu = GetBYTE(adr); break; - case 7: sim_brk_pend = FALSE; ++PC; acu = hreg(AF); break; + case 0: + sim_brk_pend = tStateModifier = FALSE; + ++PC; + acu = hreg(BC); + tStates += 8; + break; + case 1: + sim_brk_pend = tStateModifier = FALSE; + ++PC; + acu = lreg(BC); + tStates += 8; + break; + case 2: + sim_brk_pend = tStateModifier = FALSE; + ++PC; + acu = hreg(DE); + tStates += 8; + break; + case 3: + sim_brk_pend = tStateModifier = FALSE; + ++PC; + acu = lreg(DE); + tStates += 8; + break; + case 4: + sim_brk_pend = tStateModifier = FALSE; + ++PC; + acu = hreg(HL); + tStates += 8; + break; + case 5: + sim_brk_pend = tStateModifier = FALSE; + ++PC; + acu = lreg(HL); + tStates += 8; + break; + case 6: + CheckBreakByte(adr); + ++PC; + acu = GetBYTE(adr); + tStateModifier = TRUE; + tStates += 15; + break; + case 7: + sim_brk_pend = tStateModifier = FALSE; + ++PC; + acu = hreg(AF); + tStates += 8; + break; } switch (op & 0xc0) { - case 0x00: /* shift/rotate */ - switch (op & 0x38) { - case 0x00: /* RLC */ - temp = (acu << 1) | (acu >> 7); - cbits = temp & 1; - goto cbshflg1; - case 0x08: /* RRC */ - temp = (acu >> 1) | (acu << 7); - cbits = temp & 0x80; - goto cbshflg1; - case 0x10: /* RL */ - temp = (acu << 1) | TSTFLAG(C); - cbits = acu & 0x80; - goto cbshflg1; - case 0x18: /* RR */ - temp = (acu >> 1) | (TSTFLAG(C) << 7); - cbits = acu & 1; - goto cbshflg1; - case 0x20: /* SLA */ - temp = acu << 1; - cbits = acu & 0x80; - goto cbshflg1; - case 0x28: /* SRA */ - temp = (acu >> 1) | (acu & 0x80); - cbits = acu & 1; - goto cbshflg1; - case 0x30: /* SLIA */ - temp = (acu << 1) | 1; - cbits = acu & 0x80; - goto cbshflg1; - case 0x38: /* SRL */ - temp = acu >> 1; - cbits = acu & 1; - cbshflg1: - AF = (AF & ~0xff) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp) | !!cbits; - } - break; - case 0x40: /* BIT */ - if (acu & (1 << ((op >> 3) & 7))) { - AF = (AF & ~0xfe) | 0x10 | - (((op & 0x38) == 0x38) << 7); - } - else { - AF = (AF & ~0xfe) | 0x54; - } - if ((op & 7) != 6) { - AF |= (acu & 0x28); - } - temp = acu; - break; - case 0x80: /* RES */ - temp = acu & ~(1 << ((op >> 3) & 7)); - break; - case 0xc0: /* SET */ - temp = acu | (1 << ((op >> 3) & 7)); - break; + case 0x00: /* shift/rotate */ + switch (op & 0x38) { + case 0x00: /* RLC */ + temp = (acu << 1) | (acu >> 7); + cbits = temp & 1; + goto cbshflg1; + case 0x08: /* RRC */ + temp = (acu >> 1) | (acu << 7); + cbits = temp & 0x80; + goto cbshflg1; + case 0x10: /* RL */ + temp = (acu << 1) | TSTFLAG(C); + cbits = acu & 0x80; + goto cbshflg1; + case 0x18: /* RR */ + temp = (acu >> 1) | (TSTFLAG(C) << 7); + cbits = acu & 1; + goto cbshflg1; + case 0x20: /* SLA */ + temp = acu << 1; + cbits = acu & 0x80; + goto cbshflg1; + case 0x28: /* SRA */ + temp = (acu >> 1) | (acu & 0x80); + cbits = acu & 1; + goto cbshflg1; + case 0x30: /* SLIA */ + temp = (acu << 1) | 1; + cbits = acu & 0x80; + goto cbshflg1; + case 0x38: /* SRL */ + temp = acu >> 1; + cbits = acu & 1; + cbshflg1: + AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits; + } + break; + case 0x40: /* BIT */ + if (tStateModifier) { + tStates -= 3; + } + if (acu & (1 << ((op >> 3) & 7))) { + AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7); + } + else { + AF = (AF & ~0xfe) | 0x54; + } + if ((op & 7) != 6) { + AF |= (acu & 0x28); + } + temp = acu; + break; + case 0x80: /* RES */ + temp = acu & ~(1 << ((op >> 3) & 7)); + break; + case 0xc0: /* SET */ + temp = acu | (1 << ((op >> 3) & 7)); + break; } switch (op & 7) { - case 0: Sethreg(BC, temp); break; - case 1: Setlreg(BC, temp); break; - case 2: Sethreg(DE, temp); break; - case 3: Setlreg(DE, temp); break; - case 4: Sethreg(HL, temp); break; - case 5: Setlreg(HL, temp); break; - case 6: PutBYTE(adr, temp); break; - case 7: Sethreg(AF, temp); break; + case 0: + Sethreg(BC, temp); + break; + case 1: + Setlreg(BC, temp); + break; + case 2: + Sethreg(DE, temp); + break; + case 3: + Setlreg(DE, temp); + break; + case 4: + Sethreg(HL, temp); + break; + case 5: + Setlreg(HL, temp); + break; + case 6: + PutBYTE(adr, temp); + break; + case 7: + Sethreg(AF, temp); + break; } break; case 0xcc: /* CALL Z,nnnn */ - CALLC(TSTFLAG(Z)); + CALLC(TSTFLAG(Z)); /* also updates tStates */ break; case 0xcd: /* CALL nnnn */ - CALLC(1); + CALLC(1); /* also updates tStates */ break; case 0xce: /* ADC A,nn */ + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); acu = hreg(AF); sum = acu + temp + TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | - ((cbits >> 8) & 1); + AF = addTable[sum] | cbitsTable[cbits] | (SetPV); break; case 0xcf: /* RST 8 */ + tStates += 11; CheckBreakWord(SP - 2); - PUSH(PC); PCQ_ENTRY(PC - 1); PC = 8; + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = 8; break; case 0xd0: /* RET NC */ if (TSTFLAG(C)) { sim_brk_pend = FALSE; + tStates += 5; } else { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); + tStates += 11; } break; case 0xd1: /* POP DE */ + tStates += 10; CheckBreakWord(SP); POP(DE); break; case 0xd2: /* JP NC,nnnn */ sim_brk_pend = FALSE; - JPC(!TSTFLAG(C)); + JPC(!TSTFLAG(C)); /* also updates tStates */ break; case 0xd3: /* OUT (nn),A */ + tStates += 11; sim_brk_pend = FALSE; out(RAM_pp(PC), hreg(AF)); break; case 0xd4: /* CALL NC,nnnn */ - CALLC(!TSTFLAG(C)); + CALLC(!TSTFLAG(C)); /* also updates tStates */ break; case 0xd5: /* PUSH DE */ + tStates += 11; CheckBreakWord(SP - 2); PUSH(DE); break; case 0xd6: /* SUB nn */ + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0xd7: /* RST 10H */ + tStates += 11; CheckBreakWord(SP - 2); - PUSH(PC); PCQ_ENTRY(PC - 1); PC = 0x10; + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = 0x10; break; case 0xd8: /* RET C */ if (TSTFLAG(C)) { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); + tStates += 11; } else { sim_brk_pend = FALSE; + tStates += 5; } break; case 0xd9: /* EXX */ + tStates += 4; sim_brk_pend = FALSE; checkCPU8080; regs[regs_sel].bc = BC; @@ -2193,1936 +3322,2062 @@ int32 sim_instr (void) { break; case 0xda: /* JP C,nnnn */ sim_brk_pend = FALSE; - JPC(TSTFLAG(C)); + JPC(TSTFLAG(C)); /* also updates tStates */ break; case 0xdb: /* IN A,(nn) */ + tStates += 11; sim_brk_pend = FALSE; Sethreg(AF, in(RAM_pp(PC))); break; case 0xdc: /* CALL C,nnnn */ - CALLC(TSTFLAG(C)); + CALLC(TSTFLAG(C)); /* also updates tStates */ break; case 0xdd: /* DD prefix */ checkCPU8080; switch (op = RAM_pp(PC)) { - case 0x09: /* ADD IX,BC */ - sim_brk_pend = FALSE; - IX &= ADDRMASK; - BC &= ADDRMASK; - sum = IX + BC; - cbits = (IX ^ BC ^ sum) >> 8; - IX = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x19: /* ADD IX,DE */ - sim_brk_pend = FALSE; - IX &= ADDRMASK; - DE &= ADDRMASK; - sum = IX + DE; - cbits = (IX ^ DE ^ sum) >> 8; - IX = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x21: /* LD IX,nnnn */ - sim_brk_pend = FALSE; - IX = GetWORD(PC); - PC += 2; - break; - case 0x22: /* LD (nnnn),IX */ - temp = GetWORD(PC); - CheckBreakWord(temp); - PutWORD(temp, IX); - PC += 2; - break; - case 0x23: /* INC IX */ - sim_brk_pend = FALSE; - ++IX; - break; - case 0x24: /* INC IXH */ - sim_brk_pend = FALSE; - IX += 0x100; - temp = hreg(IX); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x25: /* DEC IXH */ - sim_brk_pend = FALSE; - IX -= 0x100; - temp = hreg(IX); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x26: /* LD IXH,nn */ - sim_brk_pend = FALSE; - Sethreg(IX, RAM_pp(PC)); - break; - case 0x29: /* ADD IX,IX */ - sim_brk_pend = FALSE; - IX &= ADDRMASK; - sum = IX + IX; - cbits = (IX ^ IX ^ sum) >> 8; - IX = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x2a: /* LD IX,(nnnn) */ - temp = GetWORD(PC); - CheckBreakWord(temp); - IX = GetWORD(temp); - PC += 2; - break; - case 0x2b: /* DEC IX */ - sim_brk_pend = FALSE; - --IX; - break; - case 0x2c: /* INC IXL */ - sim_brk_pend = FALSE; - temp = lreg(IX) + 1; - Setlreg(IX, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x2d: /* DEC IXL */ - sim_brk_pend = FALSE; - temp = lreg(IX) - 1; - Setlreg(IX, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x2e: /* LD IXL,nn */ - sim_brk_pend = FALSE; - Setlreg(IX, RAM_pp(PC)); - break; - case 0x34: /* INC (IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr) + 1; - PutBYTE(adr, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x35: /* DEC (IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr) - 1; - PutBYTE(adr, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x36: /* LD (IX+dd),nn */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, RAM_pp(PC)); - break; - case 0x39: /* ADD IX,SP */ - sim_brk_pend = FALSE; - IX &= ADDRMASK; - SP &= ADDRMASK; - sum = IX + SP; - cbits = (IX ^ SP ^ sum) >> 8; - IX = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x44: /* LD B,IXH */ - sim_brk_pend = FALSE; - Sethreg(BC, hreg(IX)); - break; - case 0x45: /* LD B,IXL */ - sim_brk_pend = FALSE; - Sethreg(BC, lreg(IX)); - break; - case 0x46: /* LD B,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Sethreg(BC, GetBYTE(adr)); - break; - case 0x4c: /* LD C,IXH */ - sim_brk_pend = FALSE; - Setlreg(BC, hreg(IX)); - break; - case 0x4d: /* LD C,IXL */ - sim_brk_pend = FALSE; - Setlreg(BC, lreg(IX)); - break; - case 0x4e: /* LD C,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Setlreg(BC, GetBYTE(adr)); - break; - case 0x54: /* LD D,IXH */ - sim_brk_pend = FALSE; - Sethreg(DE, hreg(IX)); - break; - case 0x55: /* LD D,IXL */ - sim_brk_pend = FALSE; - Sethreg(DE, lreg(IX)); - break; - case 0x56: /* LD D,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Sethreg(DE, GetBYTE(adr)); - break; - case 0x5c: /* LD E,H */ - sim_brk_pend = FALSE; - Setlreg(DE, hreg(IX)); - break; - case 0x5d: /* LD E,L */ - sim_brk_pend = FALSE; - Setlreg(DE, lreg(IX)); - break; - case 0x5e: /* LD E,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Setlreg(DE, GetBYTE(adr)); - break; - case 0x60: /* LD IXH,B */ - sim_brk_pend = FALSE; - Sethreg(IX, hreg(BC)); - break; - case 0x61: /* LD IXH,C */ - sim_brk_pend = FALSE; - Sethreg(IX, lreg(BC)); - break; - case 0x62: /* LD IXH,D */ - sim_brk_pend = FALSE; - Sethreg(IX, hreg(DE)); - break; - case 0x63: /* LD IXH,E */ - sim_brk_pend = FALSE; - Sethreg(IX, lreg(DE)); - break; - case 0x64: /* LD IXH,IXH */ - sim_brk_pend = FALSE; - /* nop */ - break; - case 0x65: /* LD IXH,IXL */ - sim_brk_pend = FALSE; - Sethreg(IX, lreg(IX)); - break; - case 0x66: /* LD H,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Sethreg(HL, GetBYTE(adr)); - break; - case 0x67: /* LD IXH,A */ - sim_brk_pend = FALSE; - Sethreg(IX, hreg(AF)); - break; - case 0x68: /* LD IXL,B */ - sim_brk_pend = FALSE; - Setlreg(IX, hreg(BC)); - break; - case 0x69: /* LD IXL,C */ - sim_brk_pend = FALSE; - Setlreg(IX, lreg(BC)); - break; - case 0x6a: /* LD IXL,D */ - sim_brk_pend = FALSE; - Setlreg(IX, hreg(DE)); - break; - case 0x6b: /* LD IXL,E */ - sim_brk_pend = FALSE; - Setlreg(IX, lreg(DE)); - break; - case 0x6c: /* LD IXL,IXH */ - sim_brk_pend = FALSE; - Setlreg(IX, hreg(IX)); - break; - case 0x6d: /* LD IXL,IXL */ - sim_brk_pend = FALSE; - /* nop */ - break; - case 0x6e: /* LD L,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Setlreg(HL, GetBYTE(adr)); - break; - case 0x6f: /* LD IXL,A */ - sim_brk_pend = FALSE; - Setlreg(IX, hreg(AF)); - break; - case 0x70: /* LD (IX+dd),B */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, hreg(BC)); - break; - case 0x71: /* LD (IX+dd),C */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, lreg(BC)); - break; - case 0x72: /* LD (IX+dd),D */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, hreg(DE)); - break; - case 0x73: /* LD (IX+dd),E */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, lreg(DE)); - break; - case 0x74: /* LD (IX+dd),H */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, hreg(HL)); - break; - case 0x75: /* LD (IX+dd),L */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, lreg(HL)); - break; - case 0x77: /* LD (IX+dd),A */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, hreg(AF)); - break; - case 0x7c: /* LD A,IXH */ - sim_brk_pend = FALSE; - Sethreg(AF, hreg(IX)); - break; - case 0x7d: /* LD A,IXL */ - sim_brk_pend = FALSE; - Sethreg(AF, lreg(IX)); - break; - case 0x7e: /* LD A,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Sethreg(AF, GetBYTE(adr)); - break; - case 0x84: /* ADD A,IXH */ - sim_brk_pend = FALSE; - temp = hreg(IX); - acu = hreg(AF); - sum = acu + temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x85: /* ADD A,IXL */ - sim_brk_pend = FALSE; - temp = lreg(IX); - acu = hreg(AF); - sum = acu + temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x86: /* ADD A,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - acu = hreg(AF); - sum = acu + temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8c: /* ADC A,IXH */ - sim_brk_pend = FALSE; - temp = hreg(IX); - acu = hreg(AF); - sum = acu + temp + TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8d: /* ADC A,IXL */ - sim_brk_pend = FALSE; - temp = lreg(IX); - acu = hreg(AF); - sum = acu + temp + TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8e: /* ADC A,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - acu = hreg(AF); - sum = acu + temp + TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x94: /* SUB IXH */ - sim_brk_pend = FALSE; - temp = hreg(IX); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x95: /* SUB IXL */ - sim_brk_pend = FALSE; - temp = lreg(IX); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x96: /* SUB (IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9c: /* SBC A,IXH */ - sim_brk_pend = FALSE; - temp = hreg(IX); - acu = hreg(AF); - sum = acu - temp - TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9d: /* SBC A,IXL */ - sim_brk_pend = FALSE; - temp = lreg(IX); - acu = hreg(AF); - sum = acu - temp - TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9e: /* SBC A,(IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - acu = hreg(AF); - sum = acu - temp - TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0xa4: /* AND IXH */ - sim_brk_pend = FALSE; - sum = ((AF & (IX)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; - break; - case 0xa5: /* AND IXL */ - sim_brk_pend = FALSE; - sum = ((AF >> 8) & IX) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xa6: /* AND (IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - sum = ((AF >> 8) & GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xac: /* XOR IXH */ - sim_brk_pend = FALSE; - sum = ((AF ^ (IX)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xad: /* XOR IXL */ - sim_brk_pend = FALSE; - sum = ((AF >> 8) ^ IX) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xae: /* XOR (IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - sum = ((AF >> 8) ^ GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xb4: /* OR IXH */ - sim_brk_pend = FALSE; - sum = ((AF | (IX)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xb5: /* OR IXL */ - sim_brk_pend = FALSE; - sum = ((AF >> 8) | IX) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xb6: /* OR (IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - sum = ((AF >> 8) | GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xbc: /* CP IXH */ - sim_brk_pend = FALSE; - temp = hreg(IX); - AF = (AF & ~0x28) | (temp & 0x28); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xbd: /* CP IXL */ - sim_brk_pend = FALSE; - temp = lreg(IX); - AF = (AF & ~0x28) | (temp & 0x28); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xbe: /* CP (IX+dd) */ - adr = IX + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - AF = (AF & ~0x28) | (temp & 0x28); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xcb: /* CB prefix */ - adr = IX + (signed char) RAM_pp(PC); - switch ((op = GetBYTE(PC)) & 7) { - case 0: sim_brk_pend = FALSE; ++PC; acu = hreg(BC); break; - case 1: sim_brk_pend = FALSE; ++PC; acu = lreg(BC); break; - case 2: sim_brk_pend = FALSE; ++PC; acu = hreg(DE); break; - case 3: sim_brk_pend = FALSE; ++PC; acu = lreg(DE); break; - case 4: sim_brk_pend = FALSE; ++PC; acu = hreg(HL); break; - case 5: sim_brk_pend = FALSE; ++PC; acu = lreg(HL); break; - case 6: CheckBreakByte(adr); ++PC; acu = GetBYTE(adr); break; - case 7: sim_brk_pend = FALSE; ++PC; acu = hreg(AF); break; - } - switch (op & 0xc0) { - case 0x00: /* shift/rotate */ - switch (op & 0x38) { - case 0x00: /* RLC */ - temp = (acu << 1) | (acu >> 7); - cbits = temp & 1; - goto cbshflg2; - case 0x08: /* RRC */ - temp = (acu >> 1) | (acu << 7); - cbits = temp & 0x80; - goto cbshflg2; - case 0x10: /* RL */ - temp = (acu << 1) | TSTFLAG(C); - cbits = acu & 0x80; - goto cbshflg2; - case 0x18: /* RR */ - temp = (acu >> 1) | (TSTFLAG(C) << 7); - cbits = acu & 1; - goto cbshflg2; - case 0x20: /* SLA */ - temp = acu << 1; - cbits = acu & 0x80; - goto cbshflg2; - case 0x28: /* SRA */ - temp = (acu >> 1) | (acu & 0x80); - cbits = acu & 1; - goto cbshflg2; - case 0x30: /* SLIA */ - temp = (acu << 1) | 1; - cbits = acu & 0x80; - goto cbshflg2; - case 0x38: /* SRL */ - temp = acu >> 1; - cbits = acu & 1; - cbshflg2: - AF = (AF & ~0xff) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp) | !!cbits; + case 0x09: /* ADD IX,BC */ + tStates += 15; + sim_brk_pend = FALSE; + IX &= ADDRMASK; + BC &= ADDRMASK; + sum = IX + BC; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ BC ^ sum) >> 8]; + IX = sum; + break; + case 0x19: /* ADD IX,DE */ + tStates += 15; + sim_brk_pend = FALSE; + IX &= ADDRMASK; + DE &= ADDRMASK; + sum = IX + DE; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ DE ^ sum) >> 8]; + IX = sum; + break; + case 0x21: /* LD IX,nnnn */ + tStates += 14; + sim_brk_pend = FALSE; + IX = GetWORD(PC); + PC += 2; + break; + case 0x22: /* LD (nnnn),IX */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + PutWORD(temp, IX); + PC += 2; + break; + case 0x23: /* INC IX */ + tStates += 10; + sim_brk_pend = FALSE; + ++IX; + break; + case 0x24: /* INC IXH */ + tStates += 9; + sim_brk_pend = FALSE; + IX += 0x100; + AF = (AF & ~0xfe) | incZ80Table[hreg(IX)]; + break; + case 0x25: /* DEC IXH */ + tStates += 9; + sim_brk_pend = FALSE; + IX -= 0x100; + AF = (AF & ~0xfe) | decZ80Table[hreg(IX)]; + break; + case 0x26: /* LD IXH,nn */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IX, RAM_pp(PC)); + break; + case 0x29: /* ADD IX,IX */ + tStates += 15; + sim_brk_pend = FALSE; + IX &= ADDRMASK; + sum = IX + IX; + AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8]; + IX = sum; + break; + case 0x2a: /* LD IX,(nnnn) */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + IX = GetWORD(temp); + PC += 2; + break; + case 0x2b: /* DEC IX */ + tStates += 10; + sim_brk_pend = FALSE; + --IX; + break; + case 0x2c: /* INC IXL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IX) + 1; + Setlreg(IX, temp); + AF = (AF & ~0xfe) | incZ80Table[temp]; + break; + case 0x2d: /* DEC IXL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IX) - 1; + Setlreg(IX, temp); + AF = (AF & ~0xfe) | decZ80Table[temp & 0xff]; + break; + case 0x2e: /* LD IXL,nn */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IX, RAM_pp(PC)); + break; + case 0x34: /* INC (IX+dd) */ + tStates += 23; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr) + 1; + PutBYTE(adr, temp); + AF = (AF & ~0xfe) | incZ80Table[temp]; + break; + case 0x35: /* DEC (IX+dd) */ + tStates += 23; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr) - 1; + PutBYTE(adr, temp); + AF = (AF & ~0xfe) | decZ80Table[temp & 0xff]; + break; + case 0x36: /* LD (IX+dd),nn */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, RAM_pp(PC)); + break; + case 0x39: /* ADD IX,SP */ + tStates += 15; + sim_brk_pend = FALSE; + IX &= ADDRMASK; + SP &= ADDRMASK; + sum = IX + SP; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ SP ^ sum) >> 8]; + IX = sum; + break; + case 0x44: /* LD B,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(BC, hreg(IX)); + break; + case 0x45: /* LD B,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(BC, lreg(IX)); + break; + case 0x46: /* LD B,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Sethreg(BC, GetBYTE(adr)); + break; + case 0x4c: /* LD C,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(BC, hreg(IX)); + break; + case 0x4d: /* LD C,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(BC, lreg(IX)); + break; + case 0x4e: /* LD C,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Setlreg(BC, GetBYTE(adr)); + break; + case 0x54: /* LD D,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(DE, hreg(IX)); + break; + case 0x55: /* LD D,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(DE, lreg(IX)); + break; + case 0x56: /* LD D,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Sethreg(DE, GetBYTE(adr)); + break; + case 0x5c: /* LD E,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(DE, hreg(IX)); + break; + case 0x5d: /* LD E,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(DE, lreg(IX)); + break; + case 0x5e: /* LD E,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Setlreg(DE, GetBYTE(adr)); + break; + case 0x60: /* LD IXH,B */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IX, hreg(BC)); + break; + case 0x61: /* LD IXH,C */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IX, lreg(BC)); + break; + case 0x62: /* LD IXH,D */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IX, hreg(DE)); + break; + case 0x63: /* LD IXH,E */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IX, lreg(DE)); + break; + case 0x64: /* LD IXH,IXH */ + tStates += 9; + sim_brk_pend = FALSE; /* nop */ + break; + case 0x65: /* LD IXH,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IX, lreg(IX)); + break; + case 0x66: /* LD H,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Sethreg(HL, GetBYTE(adr)); + break; + case 0x67: /* LD IXH,A */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IX, hreg(AF)); + break; + case 0x68: /* LD IXL,B */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IX, hreg(BC)); + break; + case 0x69: /* LD IXL,C */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IX, lreg(BC)); + break; + case 0x6a: /* LD IXL,D */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IX, hreg(DE)); + break; + case 0x6b: /* LD IXL,E */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IX, lreg(DE)); + break; + case 0x6c: /* LD IXL,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IX, hreg(IX)); + break; + case 0x6d: /* LD IXL,IXL */ + tStates += 9; + sim_brk_pend = FALSE; /* nop */ + break; + case 0x6e: /* LD L,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Setlreg(HL, GetBYTE(adr)); + break; + case 0x6f: /* LD IXL,A */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IX, hreg(AF)); + break; + case 0x70: /* LD (IX+dd),B */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, hreg(BC)); + break; + case 0x71: /* LD (IX+dd),C */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, lreg(BC)); + break; + case 0x72: /* LD (IX+dd),D */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, hreg(DE)); + break; + case 0x73: /* LD (IX+dd),E */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, lreg(DE)); + break; + case 0x74: /* LD (IX+dd),H */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, hreg(HL)); + break; + case 0x75: /* LD (IX+dd),L */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, lreg(HL)); + break; + case 0x77: /* LD (IX+dd),A */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, hreg(AF)); + break; + case 0x7c: /* LD A,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(AF, hreg(IX)); + break; + case 0x7d: /* LD A,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(AF, lreg(IX)); + break; + case 0x7e: /* LD A,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Sethreg(AF, GetBYTE(adr)); + break; + case 0x84: /* ADD A,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + temp = hreg(IX); + acu = hreg(AF); + sum = acu + temp; + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x85: /* ADD A,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IX); + acu = hreg(AF); + sum = acu + temp; + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x86: /* ADD A,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + acu = hreg(AF); + sum = acu + temp; + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x8c: /* ADC A,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + temp = hreg(IX); + acu = hreg(AF); + sum = acu + temp + TSTFLAG(C); + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x8d: /* ADC A,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IX); + acu = hreg(AF); + sum = acu + temp + TSTFLAG(C); + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x8e: /* ADC A,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + acu = hreg(AF); + sum = acu + temp + TSTFLAG(C); + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x96: /* SUB (IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + acu = hreg(AF); + sum = acu - temp; + AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0x94: /* SUB IXH */ + SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */ + case 0x9c: /* SBC A,IXH */ + tStates += 9; + sim_brk_pend = FALSE; + temp = hreg(IX); + acu = hreg(AF); + sum = acu - temp - TSTFLAG(C); + AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0x95: /* SUB IXL */ + SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */ + case 0x9d: /* SBC A,IXL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IX); + acu = hreg(AF); + sum = acu - temp - TSTFLAG(C); + AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0x9e: /* SBC A,(IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + acu = hreg(AF); + sum = acu - temp - TSTFLAG(C); + AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0xa4: /* AND IXH */ + tStates += 9; + sim_brk_pend = FALSE; + AF = andTable[((AF & IX) >> 8) & 0xff]; + break; + case 0xa5: /* AND IXL */ + tStates += 9; + sim_brk_pend = FALSE; + AF = andTable[((AF >> 8) & IX) & 0xff]; + break; + case 0xa6: /* AND (IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + AF = andTable[((AF >> 8) & GetBYTE(adr)) & 0xff]; + break; + case 0xac: /* XOR IXH */ + tStates += 9; + sim_brk_pend = FALSE; + AF = xororTable[((AF ^ IX) >> 8) & 0xff]; + break; + case 0xad: /* XOR IXL */ + tStates += 9; + sim_brk_pend = FALSE; + AF = xororTable[((AF >> 8) ^ IX) & 0xff]; + break; + case 0xae: /* XOR (IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + AF = xororTable[((AF >> 8) ^ GetBYTE(adr)) & 0xff]; + break; + case 0xb4: /* OR IXH */ + tStates += 9; + sim_brk_pend = FALSE; + AF = xororTable[((AF | IX) >> 8) & 0xff]; + break; + case 0xb5: /* OR IXL */ + tStates += 9; + sim_brk_pend = FALSE; + AF = xororTable[((AF >> 8) | IX) & 0xff]; + break; + case 0xb6: /* OR (IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + AF = xororTable[((AF >> 8) | GetBYTE(adr)) & 0xff]; + break; + case 0xbc: /* CP IXH */ + tStates += 9; + sim_brk_pend = FALSE; + temp = hreg(IX); + AF = (AF & ~0x28) | (temp & 0x28); + acu = hreg(AF); + sum = acu - temp; + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0xbd: /* CP IXL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IX); + AF = (AF & ~0x28) | (temp & 0x28); + acu = hreg(AF); + sum = acu - temp; + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0xbe: /* CP (IX+dd) */ + tStates += 19; + adr = IX + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + AF = (AF & ~0x28) | (temp & 0x28); + acu = hreg(AF); + sum = acu - temp; + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0xcb: /* CB prefix */ + adr = IX + (signed char) RAM_pp(PC); + switch ((op = GetBYTE(PC)) & 7) { + case 0: + sim_brk_pend = FALSE; + ++PC; + acu = hreg(BC); + break; + case 1: + sim_brk_pend = FALSE; + ++PC; + acu = lreg(BC); + break; + case 2: + sim_brk_pend = FALSE; + ++PC; + acu = hreg(DE); + break; + case 3: + sim_brk_pend = FALSE; + ++PC; + acu = lreg(DE); + break; + case 4: + sim_brk_pend = FALSE; + ++PC; + acu = hreg(HL); + break; + case 5: + sim_brk_pend = FALSE; + ++PC; + acu = lreg(HL); + break; + case 6: + CheckBreakByte(adr); + ++PC; + acu = GetBYTE(adr); + break; + case 7: + sim_brk_pend = FALSE; + ++PC; + acu = hreg(AF); + break; + } + switch (op & 0xc0) { + case 0x00: /* shift/rotate */ + tStates += 23; + switch (op & 0x38) { + case 0x00: /* RLC */ + temp = (acu << 1) | (acu >> 7); + cbits = temp & 1; + goto cbshflg2; + case 0x08: /* RRC */ + temp = (acu >> 1) | (acu << 7); + cbits = temp & 0x80; + goto cbshflg2; + case 0x10: /* RL */ + temp = (acu << 1) | TSTFLAG(C); + cbits = acu & 0x80; + goto cbshflg2; + case 0x18: /* RR */ + temp = (acu >> 1) | (TSTFLAG(C) << 7); + cbits = acu & 1; + goto cbshflg2; + case 0x20: /* SLA */ + temp = acu << 1; + cbits = acu & 0x80; + goto cbshflg2; + case 0x28: /* SRA */ + temp = (acu >> 1) | (acu & 0x80); + cbits = acu & 1; + goto cbshflg2; + case 0x30: /* SLIA */ + temp = (acu << 1) | 1; + cbits = acu & 0x80; + goto cbshflg2; + case 0x38: /* SRL */ + temp = acu >> 1; + cbits = acu & 1; + cbshflg2: + AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits; + } + break; + case 0x40: /* BIT */ + tStates += 20; + if (acu & (1 << ((op >> 3) & 7))) { + AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7); + } + else { + AF = (AF & ~0xfe) | 0x54; + } + if ((op & 7) != 6) { + AF |= (acu & 0x28); + } + temp = acu; + break; + case 0x80: /* RES */ + tStates += 23; + temp = acu & ~(1 << ((op >> 3) & 7)); + break; + case 0xc0: /* SET */ + tStates += 23; + temp = acu | (1 << ((op >> 3) & 7)); + break; + } + switch (op & 7) { + case 0: + Sethreg(BC, temp); + break; + case 1: + Setlreg(BC, temp); + break; + case 2: + Sethreg(DE, temp); + break; + case 3: + Setlreg(DE, temp); + break; + case 4: + Sethreg(HL, temp); + break; + case 5: + Setlreg(HL, temp); + break; + case 6: + PutBYTE(adr, temp); + break; + case 7: + Sethreg(AF, temp); + break; } break; - case 0x40: /* BIT */ - if (acu & (1 << ((op >> 3) & 7))) { - AF = (AF & ~0xfe) | 0x10 | - (((op & 0x38) == 0x38) << 7); - } - else { - AF = (AF & ~0xfe) | 0x54; - } - if ((op & 7) != 6) { - AF |= (acu & 0x28); - } - temp = acu; + case 0xe1: /* POP IX */ + tStates += 14; + CheckBreakWord(SP); + POP(IX); break; - case 0x80: /* RES */ - temp = acu & ~(1 << ((op >> 3) & 7)); + case 0xe3: /* EX (SP),IX */ + tStates += 23; + CheckBreakWord(SP); + temp = IX; + POP(IX); + PUSH(temp); break; - case 0xc0: /* SET */ - temp = acu | (1 << ((op >> 3) & 7)); + case 0xe5: /* PUSH IX */ + tStates += 15; + CheckBreakWord(SP - 2); + PUSH(IX); break; - } - switch (op & 7) { - case 0: Sethreg(BC, temp); break; - case 1: Setlreg(BC, temp); break; - case 2: Sethreg(DE, temp); break; - case 3: Setlreg(DE, temp); break; - case 4: Sethreg(HL, temp); break; - case 5: Setlreg(HL, temp); break; - case 6: PutBYTE(adr, temp); break; - case 7: Sethreg(AF, temp); break; - } - break; - case 0xe1: /* POP IX */ - CheckBreakWord(SP); - POP(IX); - break; - case 0xe3: /* EX (SP),IX */ - CheckBreakWord(SP); - temp = IX; POP(IX); PUSH(temp); - break; - case 0xe5: /* PUSH IX */ - CheckBreakWord(SP - 2); - PUSH(IX); - break; - case 0xe9: /* JP (IX) */ - sim_brk_pend = FALSE; - PCQ_ENTRY(PC - 2); - PC = IX; - break; - case 0xf9: /* LD SP,IX */ - sim_brk_pend = FALSE; - SP = IX; - break; - default: /* ignore DD */ - sim_brk_pend = FALSE; - checkCPUZ80; - PC--; + case 0xe9: /* JP (IX) */ + tStates += 8; + sim_brk_pend = FALSE; + PCQ_ENTRY(PC - 2); + PC = IX; + break; + case 0xf9: /* LD SP,IX */ + tStates += 10; + sim_brk_pend = FALSE; + SP = IX; + break; + default: /* ignore DD */ + sim_brk_pend = FALSE; + checkCPUZ80; + PC--; } break; case 0xde: /* SBC A,nn */ + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); acu = hreg(AF); sum = acu - temp - TSTFLAG(C); cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (SetPV) | 2 | - ((cbits >> 8) & 1); + AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SetPV); break; case 0xdf: /* RST 18H */ + tStates += 11; CheckBreakWord(SP - 2); - PUSH(PC); PCQ_ENTRY(PC - 1); PC = 0x18; + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = 0x18; break; case 0xe0: /* RET PO */ if (TSTFLAG(P)) { sim_brk_pend = FALSE; + tStates += 5; } else { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); + tStates += 11; } break; case 0xe1: /* POP HL */ + tStates += 10; CheckBreakWord(SP); POP(HL); break; case 0xe2: /* JP PO,nnnn */ sim_brk_pend = FALSE; - JPC(!TSTFLAG(P)); + JPC(!TSTFLAG(P)); /* also updates tStates */ break; case 0xe3: /* EX (SP),HL */ + tStates += 19; CheckBreakWord(SP); - temp = HL; POP(HL); PUSH(temp); + temp = HL; + POP(HL); + PUSH(temp); break; case 0xe4: /* CALL PO,nnnn */ - CALLC(!TSTFLAG(P)); + CALLC(!TSTFLAG(P)); /* also updates tStates */ break; case 0xe5: /* PUSH HL */ + tStates += 11; CheckBreakWord(SP - 2); PUSH(HL); break; case 0xe6: /* AND nn */ + tStates += 7; sim_brk_pend = FALSE; - sum = ((AF >> 8) & RAM_pp(PC)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; + AF = andTable[((AF >> 8) & RAM_pp(PC)) & 0xff]; break; case 0xe7: /* RST 20H */ + tStates += 11; CheckBreakWord(SP - 2); - PUSH(PC); PCQ_ENTRY(PC - 1); PC = 0x20; + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = 0x20; break; case 0xe8: /* RET PE */ if (TSTFLAG(P)) { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); + tStates += 11; } else { sim_brk_pend = FALSE; + tStates += 5; } break; case 0xe9: /* JP (HL) */ + tStates += 4; sim_brk_pend = FALSE; PCQ_ENTRY(PC - 1); PC = HL; break; case 0xea: /* JP PE,nnnn */ sim_brk_pend = FALSE; - JPC(TSTFLAG(P)); + JPC(TSTFLAG(P)); /* also updates tStates */ break; case 0xeb: /* EX DE,HL */ + tStates += 4; sim_brk_pend = FALSE; - temp = HL; HL = DE; DE = temp; + temp = HL; + HL = DE; + DE = temp; break; case 0xec: /* CALL PE,nnnn */ - CALLC(TSTFLAG(P)); + CALLC(TSTFLAG(P)); /* also updates tStates */ break; case 0xed: /* ED prefix */ checkCPU8080; switch (op = RAM_pp(PC)) { - case 0x40: /* IN B,(C) */ - sim_brk_pend = FALSE; - temp = in(lreg(BC)); - Sethreg(BC, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x41: /* OUT (C),B */ - sim_brk_pend = FALSE; - out(lreg(BC), hreg(BC)); - break; - case 0x42: /* SBC HL,BC */ - sim_brk_pend = FALSE; - HL &= ADDRMASK; - BC &= ADDRMASK; - sum = HL - BC - TSTFLAG(C); - cbits = (HL ^ BC ^ sum) >> 8; - HL = sum; - AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | - (((sum & ADDRMASK) == 0) << 6) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - (cbits & 0x10) | 2 | ((cbits >> 8) & 1); - break; - case 0x43: /* LD (nnnn),BC */ - temp = GetWORD(PC); - CheckBreakWord(temp); - PutWORD(temp, BC); - PC += 2; - break; - case 0x44: /* NEG */ - sim_brk_pend = FALSE; - temp = hreg(AF); - AF = ((~(AF & 0xff00) + 1) & 0xff00); /* AF = (-(AF & 0xff00) & 0xff00); */ - AF |= ((AF >> 8) & 0xa8) | (((AF & 0xff00) == 0) << 6) | - (((temp & 0x0f) != 0) << 4) | - ((temp == 0x80) << 2) | - 2 | (temp != 0); - break; - case 0x45: /* RETN */ - IFF |= IFF >> 1; - CheckBreakWord(SP); - PCQ_ENTRY(PC - 2); - POP(PC); - break; - case 0x46: /* IM 0 */ - sim_brk_pend = FALSE; - /* interrupt mode 0 */ - break; - case 0x47: /* LD I,A */ - sim_brk_pend = FALSE; - ir = (ir & 255) | (AF & ~255); - break; - case 0x48: /* IN C,(C) */ - sim_brk_pend = FALSE; - temp = in(lreg(BC)); - Setlreg(BC, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x49: /* OUT (C),C */ - sim_brk_pend = FALSE; - out(lreg(BC), lreg(BC)); - break; - case 0x4a: /* ADC HL,BC */ - sim_brk_pend = FALSE; - HL &= ADDRMASK; - BC &= ADDRMASK; - sum = HL + BC + TSTFLAG(C); - cbits = (HL ^ BC ^ sum) >> 8; - HL = sum; - AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | - (((sum & ADDRMASK) == 0) << 6) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x4b: /* LD BC,(nnnn) */ - temp = GetWORD(PC); - CheckBreakWord(temp); - BC = GetWORD(temp); - PC += 2; - break; - case 0x4d: /* RETI */ - IFF |= IFF >> 1; - CheckBreakWord(SP); - PCQ_ENTRY(PC - 2); - POP(PC); - break; - case 0x4f: /* LD R,A */ - sim_brk_pend = FALSE; - ir = (ir & ~255) | ((AF >> 8) & 255); - break; - case 0x50: /* IN D,(C) */ - sim_brk_pend = FALSE; - temp = in(lreg(BC)); - Sethreg(DE, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x51: /* OUT (C),D */ - sim_brk_pend = FALSE; - out(lreg(BC), hreg(DE)); - break; - case 0x52: /* SBC HL,DE */ - sim_brk_pend = FALSE; - HL &= ADDRMASK; - DE &= ADDRMASK; - sum = HL - DE - TSTFLAG(C); - cbits = (HL ^ DE ^ sum) >> 8; - HL = sum; - AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | - (((sum & ADDRMASK) == 0) << 6) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - (cbits & 0x10) | 2 | ((cbits >> 8) & 1); - break; - case 0x53: /* LD (nnnn),DE */ - temp = GetWORD(PC); - CheckBreakWord(temp); - PutWORD(temp, DE); - PC += 2; - break; - case 0x56: /* IM 1 */ - sim_brk_pend = FALSE; - /* interrupt mode 1 */ - break; - case 0x57: /* LD A,I */ - sim_brk_pend = FALSE; - AF = (AF & 0x29) | (ir & ~255) | ((ir >> 8) & 0x80) | (((ir & ~255) == 0) << 6) | ((IFF & 2) << 1); - break; - case 0x58: /* IN E,(C) */ - sim_brk_pend = FALSE; - temp = in(lreg(BC)); - Setlreg(DE, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x59: /* OUT (C),E */ - sim_brk_pend = FALSE; - out(lreg(BC), lreg(DE)); - break; - case 0x5a: /* ADC HL,DE */ - sim_brk_pend = FALSE; - HL &= ADDRMASK; - DE &= ADDRMASK; - sum = HL + DE + TSTFLAG(C); - cbits = (HL ^ DE ^ sum) >> 8; - HL = sum; - AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | - (((sum & ADDRMASK) == 0) << 6) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x5b: /* LD DE,(nnnn) */ - temp = GetWORD(PC); - CheckBreakWord(temp); - DE = GetWORD(temp); - PC += 2; - break; - case 0x5e: /* IM 2 */ - sim_brk_pend = FALSE; - /* interrupt mode 2 */ - break; - case 0x5f: /* LD A,R */ - sim_brk_pend = FALSE; - AF = (AF & 0x29) | ((ir & 255) << 8) | (ir & 0x80) | (((ir & 255) == 0) << 6) | ((IFF & 2) << 1); - break; - case 0x60: /* IN H,(C) */ - sim_brk_pend = FALSE; - temp = in(lreg(BC)); - Sethreg(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x61: /* OUT (C),H */ - sim_brk_pend = FALSE; - out(lreg(BC), hreg(HL)); - break; - case 0x62: /* SBC HL,HL */ - sim_brk_pend = FALSE; - HL &= ADDRMASK; - sum = HL - HL - TSTFLAG(C); - cbits = (HL ^ HL ^ sum) >> 8; - HL = sum; - AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | - (((sum & ADDRMASK) == 0) << 6) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - (cbits & 0x10) | 2 | ((cbits >> 8) & 1); - break; - case 0x63: /* LD (nnnn),HL */ - temp = GetWORD(PC); - CheckBreakWord(temp); - PutWORD(temp, HL); - PC += 2; - break; - case 0x67: /* RRD */ - sim_brk_pend = FALSE; - temp = GetBYTE(HL); - acu = hreg(AF); - PutBYTE(HL, hdig(temp) | (ldig(acu) << 4)); - acu = (acu & 0xf0) | ldig(temp); - AF = (acu << 8) | (acu & 0xa8) | (((acu & 0xff) == 0) << 6) | - partab[acu] | (AF & 1); - break; - case 0x68: /* IN L,(C) */ - sim_brk_pend = FALSE; - temp = in(lreg(BC)); - Setlreg(HL, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x69: /* OUT (C),L */ - sim_brk_pend = FALSE; - out(lreg(BC), lreg(HL)); - break; - case 0x6a: /* ADC HL,HL */ - sim_brk_pend = FALSE; - HL &= ADDRMASK; - sum = HL + HL + TSTFLAG(C); - cbits = (HL ^ HL ^ sum) >> 8; - HL = sum; - AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | - (((sum & ADDRMASK) == 0) << 6) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x6b: /* LD HL,(nnnn) */ - temp = GetWORD(PC); - CheckBreakWord(temp); - HL = GetWORD(temp); - PC += 2; - break; - case 0x6f: /* RLD */ - sim_brk_pend = FALSE; - temp = GetBYTE(HL); - acu = hreg(AF); - PutBYTE(HL, (ldig(temp) << 4) | ldig(acu)); - acu = (acu & 0xf0) | hdig(temp); - AF = (acu << 8) | (acu & 0xa8) | (((acu & 0xff) == 0) << 6) | - partab[acu] | (AF & 1); - break; - case 0x70: /* IN (C) */ - sim_brk_pend = FALSE; - temp = in(lreg(BC)); - Setlreg(temp, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x71: /* OUT (C),0 */ - sim_brk_pend = FALSE; - out(lreg(BC), 0); - break; - case 0x72: /* SBC HL,SP */ - sim_brk_pend = FALSE; - HL &= ADDRMASK; - SP &= ADDRMASK; - sum = HL - SP - TSTFLAG(C); - cbits = (HL ^ SP ^ sum) >> 8; - HL = sum; - AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | - (((sum & ADDRMASK) == 0) << 6) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - (cbits & 0x10) | 2 | ((cbits >> 8) & 1); - break; - case 0x73: /* LD (nnnn),SP */ - temp = GetWORD(PC); - CheckBreakWord(temp); - PutWORD(temp, SP); - PC += 2; - break; - case 0x78: /* IN A,(C) */ - sim_brk_pend = FALSE; - temp = in(lreg(BC)); - Sethreg(AF, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp); - break; - case 0x79: /* OUT (C),A */ - sim_brk_pend = FALSE; - out(lreg(BC), hreg(AF)); - break; - case 0x7a: /* ADC HL,SP */ - sim_brk_pend = FALSE; - HL &= ADDRMASK; - SP &= ADDRMASK; - sum = HL + SP + TSTFLAG(C); - cbits = (HL ^ SP ^ sum) >> 8; - HL = sum; - AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | - (((sum & ADDRMASK) == 0) << 6) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x7b: /* LD SP,(nnnn) */ - temp = GetWORD(PC); - CheckBreakWord(temp); - SP = GetWORD(temp); - PC += 2; - break; - case 0xa0: /* LDI */ - CheckBreakTwoBytes(HL, DE); - acu = RAM_pp(HL); - PutBYTE_pp(DE, acu); - acu += hreg(AF); - AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) | - (((--BC & ADDRMASK) != 0) << 2); - break; - case 0xa1: /* CPI */ - CheckBreakByte(HL); - acu = hreg(AF); - temp = RAM_pp(HL); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | - (((sum - ((cbits & 16)>>4)) & 2) << 4) | (cbits & 16) | - ((sum - ((cbits >> 4) & 1)) & 8) | - ((--BC & ADDRMASK) != 0) << 2 | 2; - if ((sum & 15) == 8 && (cbits & 16) != 0) { - AF &= ~8; - } - break; - case 0xa2: /* INI */ - CheckBreakByte(HL); - PutBYTE(HL, in(lreg(BC))); ++HL; - SETFLAG(N, 1); - SETFLAG(P, (--BC & ADDRMASK) != 0); - break; - case 0xa3: /* OUTI */ - CheckBreakByte(HL); - out(lreg(BC), GetBYTE(HL)); ++HL; - SETFLAG(N, 1); - Sethreg(BC, lreg(BC) - 1); - SETFLAG(Z, lreg(BC) == 0); - break; - case 0xa8: /* LDD */ - CheckBreakTwoBytes(HL, DE); - acu = RAM_mm(HL); - PutBYTE_mm(DE, acu); - acu += hreg(AF); - AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) | - (((--BC & ADDRMASK) != 0) << 2); - break; - case 0xa9: /* CPD */ - CheckBreakByte(HL); - acu = hreg(AF); - temp = RAM_mm(HL); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | - (((sum - ((cbits & 16)>>4)) & 2) << 4) | (cbits & 16) | - ((sum - ((cbits >> 4) & 1)) & 8) | - ((--BC & ADDRMASK) != 0) << 2 | 2; - if ((sum & 15) == 8 && (cbits & 16) != 0) { - AF &= ~8; - } - break; - case 0xaa: /* IND */ - CheckBreakByte(HL); - PutBYTE(HL, in(lreg(BC))); --HL; - SETFLAG(N, 1); - Sethreg(BC, lreg(BC) - 1); - SETFLAG(Z, lreg(BC) == 0); - break; - case 0xab: /* OUTD */ - CheckBreakByte(HL); - out(lreg(BC), GetBYTE(HL)); --HL; - SETFLAG(N, 1); - Sethreg(BC, lreg(BC) - 1); - SETFLAG(Z, lreg(BC) == 0); - break; - case 0xb0: /* LDIR */ - acu = hreg(AF); - BC &= ADDRMASK; - do { + case 0x40: /* IN B,(C) */ + tStates += 12; + sim_brk_pend = FALSE; + temp = in(lreg(BC)); + Sethreg(BC, temp); + AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; + break; + case 0x41: /* OUT (C),B */ + tStates += 12; + sim_brk_pend = FALSE; + out(lreg(BC), hreg(BC)); + break; + case 0x42: /* SBC HL,BC */ + tStates += 15; + sim_brk_pend = FALSE; + HL &= ADDRMASK; + BC &= ADDRMASK; + sum = HL - BC - TSTFLAG(C); + AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) | + cbits2Z80Table[((HL ^ BC ^ sum) >> 8) & 0x1ff]; + HL = sum; + break; + case 0x43: /* LD (nnnn),BC */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + PutWORD(temp, BC); + PC += 2; + break; + case 0x44: /* NEG */ + case 0x4C: /* NEG, unofficial */ + case 0x54: /* NEG, unofficial */ + case 0x5C: /* NEG, unofficial */ + case 0x64: /* NEG, unofficial */ + case 0x6C: /* NEG, unofficial */ + case 0x74: /* NEG, unofficial */ + case 0x7C: /* NEG, unofficial */ + tStates += 8; + sim_brk_pend = FALSE; + temp = hreg(AF); + AF = ((~(AF & 0xff00) + 1) & 0xff00); /* AF = (-(AF & 0xff00) & 0xff00); */ + AF |= ((AF >> 8) & 0xa8) | (((AF & 0xff00) == 0) << 6) | negTable[temp]; + break; + case 0x45: /* RETN */ + case 0x55: /* RETN, unofficial */ + case 0x5D: /* RETN, unofficial */ + case 0x65: /* RETN, unofficial */ + case 0x6D: /* RETN, unofficial */ + case 0x75: /* RETN, unofficial */ + case 0x7D: /* RETN, unofficial */ + tStates += 14; + IFF |= IFF >> 1; + CheckBreakWord(SP); + PCQ_ENTRY(PC - 2); + POP(PC); + break; + case 0x46: /* IM 0 */ + tStates += 8; + sim_brk_pend = FALSE; + /* interrupt mode 0 */ + break; + case 0x47: /* LD I,A */ + tStates += 9; + sim_brk_pend = FALSE; + ir = (ir & 0xff) | (AF & ~0xff); + break; + case 0x48: /* IN C,(C) */ + tStates += 12; + sim_brk_pend = FALSE; + temp = in(lreg(BC)); + Setlreg(BC, temp); + AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; + break; + case 0x49: /* OUT (C),C */ + tStates += 12; + sim_brk_pend = FALSE; + out(lreg(BC), lreg(BC)); + break; + case 0x4a: /* ADC HL,BC */ + tStates += 15; + sim_brk_pend = FALSE; + HL &= ADDRMASK; + BC &= ADDRMASK; + sum = HL + BC + TSTFLAG(C); + AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) | + cbitsZ80Table[(HL ^ BC ^ sum) >> 8]; + HL = sum; + break; + case 0x4b: /* LD BC,(nnnn) */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + BC = GetWORD(temp); + PC += 2; + break; + case 0x4d: /* RETI */ + tStates += 14; + IFF |= IFF >> 1; + CheckBreakWord(SP); + PCQ_ENTRY(PC - 2); + POP(PC); + break; + case 0x4f: /* LD R,A */ + tStates += 9; + sim_brk_pend = FALSE; + ir = (ir & ~0xff) | ((AF >> 8) & 0xff); + break; + case 0x50: /* IN D,(C) */ + tStates += 12; + sim_brk_pend = FALSE; + temp = in(lreg(BC)); + Sethreg(DE, temp); + AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; + break; + case 0x51: /* OUT (C),D */ + tStates += 12; + sim_brk_pend = FALSE; + out(lreg(BC), hreg(DE)); + break; + case 0x52: /* SBC HL,DE */ + tStates += 15; + sim_brk_pend = FALSE; + HL &= ADDRMASK; + DE &= ADDRMASK; + sum = HL - DE - TSTFLAG(C); + AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) | + cbits2Z80Table[((HL ^ DE ^ sum) >> 8) & 0x1ff]; + HL = sum; + break; + case 0x53: /* LD (nnnn),DE */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + PutWORD(temp, DE); + PC += 2; + break; + case 0x56: /* IM 1 */ + tStates += 8; + sim_brk_pend = FALSE; + /* interrupt mode 1 */ + break; + case 0x57: /* LD A,I */ + tStates += 9; + sim_brk_pend = FALSE; + AF = (AF & 0x29) | (ir & ~0xff) | ((ir >> 8) & 0x80) | (((ir & ~0xff) == 0) << 6) | ((IFF & 2) << 1); + break; + case 0x58: /* IN E,(C) */ + tStates += 12; + sim_brk_pend = FALSE; + temp = in(lreg(BC)); + Setlreg(DE, temp); + AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; + break; + case 0x59: /* OUT (C),E */ + tStates += 12; + sim_brk_pend = FALSE; + out(lreg(BC), lreg(DE)); + break; + case 0x5a: /* ADC HL,DE */ + tStates += 15; + sim_brk_pend = FALSE; + HL &= ADDRMASK; + DE &= ADDRMASK; + sum = HL + DE + TSTFLAG(C); + AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) | + cbitsZ80Table[(HL ^ DE ^ sum) >> 8]; + HL = sum; + break; + case 0x5b: /* LD DE,(nnnn) */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + DE = GetWORD(temp); + PC += 2; + break; + case 0x5e: /* IM 2 */ + tStates += 8; + sim_brk_pend = FALSE; + /* interrupt mode 2 */ + break; + case 0x5f: /* LD A,R */ + tStates += 9; + sim_brk_pend = FALSE; + AF = (AF & 0x29) | ((ir & 0xff) << 8) | (ir & 0x80) | + (((ir & 0xff) == 0) << 6) | ((IFF & 2) << 1); + break; + case 0x60: /* IN H,(C) */ + tStates += 12; + sim_brk_pend = FALSE; + temp = in(lreg(BC)); + Sethreg(HL, temp); + AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; + break; + case 0x61: /* OUT (C),H */ + tStates += 12; + sim_brk_pend = FALSE; + out(lreg(BC), hreg(HL)); + break; + case 0x62: /* SBC HL,HL */ + tStates += 15; + sim_brk_pend = FALSE; + HL &= ADDRMASK; + sum = HL - HL - TSTFLAG(C); + AF = (AF & ~0xff) | (((sum & ADDRMASK) == 0) << 6) | + cbits2Z80DupTable[(sum >> 8) & 0x1ff]; + HL = sum; + break; + case 0x63: /* LD (nnnn),HL */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + PutWORD(temp, HL); + PC += 2; + break; + case 0x67: /* RRD */ + tStates += 18; + sim_brk_pend = FALSE; + temp = GetBYTE(HL); + acu = hreg(AF); + PutBYTE(HL, hdig(temp) | (ldig(acu) << 4)); + AF = rrdrldTable[(acu & 0xf0) | ldig(temp)] | (AF & 1); + break; + case 0x68: /* IN L,(C) */ + tStates += 12; + sim_brk_pend = FALSE; + temp = in(lreg(BC)); + Setlreg(HL, temp); + AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; + break; + case 0x69: /* OUT (C),L */ + tStates += 12; + sim_brk_pend = FALSE; + out(lreg(BC), lreg(HL)); + break; + case 0x6a: /* ADC HL,HL */ + tStates += 15; + sim_brk_pend = FALSE; + HL &= ADDRMASK; + sum = HL + HL + TSTFLAG(C); + AF = (AF & ~0xff) | (((sum & ADDRMASK) == 0) << 6) | + cbitsZ80DupTable[sum >> 8]; + HL = sum; + break; + case 0x6b: /* LD HL,(nnnn) */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + HL = GetWORD(temp); + PC += 2; + break; + case 0x6f: /* RLD */ + tStates += 18; + sim_brk_pend = FALSE; + temp = GetBYTE(HL); + acu = hreg(AF); + PutBYTE(HL, (ldig(temp) << 4) | ldig(acu)); + AF = rrdrldTable[(acu & 0xf0) | hdig(temp)] | (AF & 1); + break; + case 0x70: /* IN (C) */ + tStates += 12; + sim_brk_pend = FALSE; + temp = in(lreg(BC)); + Setlreg(temp, temp); + AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; + break; + case 0x71: /* OUT (C),0 */ + tStates += 12; + sim_brk_pend = FALSE; + out(lreg(BC), 0); + break; + case 0x72: /* SBC HL,SP */ + tStates += 15; + sim_brk_pend = FALSE; + HL &= ADDRMASK; + SP &= ADDRMASK; + sum = HL - SP - TSTFLAG(C); + AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) | + cbits2Z80Table[((HL ^ SP ^ sum) >> 8) & 0x1ff]; + HL = sum; + break; + case 0x73: /* LD (nnnn),SP */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + PutWORD(temp, SP); + PC += 2; + break; + case 0x78: /* IN A,(C) */ + tStates += 12; + sim_brk_pend = FALSE; + temp = in(lreg(BC)); + Sethreg(AF, temp); + AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff]; + break; + case 0x79: /* OUT (C),A */ + tStates += 12; + sim_brk_pend = FALSE; + out(lreg(BC), hreg(AF)); + break; + case 0x7a: /* ADC HL,SP */ + tStates += 15; + sim_brk_pend = FALSE; + HL &= ADDRMASK; + SP &= ADDRMASK; + sum = HL + SP + TSTFLAG(C); + AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) | + cbitsZ80Table[(HL ^ SP ^ sum) >> 8]; + HL = sum; + break; + case 0x7b: /* LD SP,(nnnn) */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + SP = GetWORD(temp); + PC += 2; + break; + case 0xa0: /* LDI */ + tStates += 16; CheckBreakTwoBytes(HL, DE); acu = RAM_pp(HL); PutBYTE_pp(DE, acu); - } while (--BC); - acu += hreg(AF); - AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); - break; - case 0xb1: /* CPIR */ - acu = hreg(AF); - BC &= ADDRMASK; - do { + acu += hreg(AF); + AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) | + (((--BC & ADDRMASK) != 0) << 2); + break; + case 0xa1: /* CPI */ + tStates += 16; CheckBreakByte(HL); + acu = hreg(AF); temp = RAM_pp(HL); - op = --BC != 0; sum = acu - temp; - } while (op && sum != 0); - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | - (((sum - ((cbits & 16)>>4)) & 2) << 4) | - (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) | - op << 2 | 2; - if ((sum & 15) == 8 && (cbits & 16) != 0) { - AF &= ~8; - } - break; - case 0xb2: /* INIR */ - temp = hreg(BC); - do { + cbits = acu ^ temp ^ sum; + AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | + (((sum - ((cbits & 16) >> 4)) & 2) << 4) | (cbits & 16) | + ((sum - ((cbits >> 4) & 1)) & 8) | + ((--BC & ADDRMASK) != 0) << 2 | 2; + if ((sum & 15) == 8 && (cbits & 16) != 0) { + AF &= ~8; + } + break; + case 0xa2: /* INI */ + tStates += 16; CheckBreakByte(HL); - PutBYTE(HL, in(lreg(BC))); ++HL; - } while (--temp); - Sethreg(BC, 0); - SETFLAG(N, 1); - SETFLAG(Z, 1); - break; - case 0xb3: /* OTIR */ - temp = hreg(BC); - do { + PutBYTE(HL, in(lreg(BC))); + ++HL; + SETFLAG(N, 1); + SETFLAG(P, (--BC & ADDRMASK) != 0); + break; + case 0xa3: /* OUTI */ + tStates += 16; CheckBreakByte(HL); - out(lreg(BC), GetBYTE(HL)); ++HL; - } while (--temp); - Sethreg(BC, 0); - SETFLAG(N, 1); - SETFLAG(Z, 1); - break; - case 0xb8: /* LDDR */ - BC &= ADDRMASK; - do { + out(lreg(BC), GetBYTE(HL)); + ++HL; + SETFLAG(N, 1); + Sethreg(BC, lreg(BC) - 1); + SETFLAG(Z, lreg(BC) == 0); + break; + case 0xa8: /* LDD */ + tStates += 16; CheckBreakTwoBytes(HL, DE); acu = RAM_mm(HL); PutBYTE_mm(DE, acu); - } while (--BC); - acu += hreg(AF); - AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); - break; - case 0xb9: /* CPDR */ - acu = hreg(AF); - BC &= ADDRMASK; - do { + acu += hreg(AF); + AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) | + (((--BC & ADDRMASK) != 0) << 2); + break; + case 0xa9: /* CPD */ + tStates += 16; CheckBreakByte(HL); + acu = hreg(AF); temp = RAM_mm(HL); - op = --BC != 0; sum = acu - temp; - } while (op && sum != 0); - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | - (((sum - ((cbits & 16)>>4)) & 2) << 4) | - (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) | - op << 2 | 2; - if ((sum & 15) == 8 && (cbits & 16) != 0) { - AF &= ~8; - } - break; - case 0xba: /* INDR */ - temp = hreg(BC); - do { + cbits = acu ^ temp ^ sum; + AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | + (((sum - ((cbits & 16) >> 4)) & 2) << 4) | (cbits & 16) | + ((sum - ((cbits >> 4) & 1)) & 8) | + ((--BC & ADDRMASK) != 0) << 2 | 2; + if ((sum & 15) == 8 && (cbits & 16) != 0) { + AF &= ~8; + } + break; + case 0xaa: /* IND */ + tStates += 16; CheckBreakByte(HL); - PutBYTE(HL, in(lreg(BC))); --HL; - } while (--temp); - Sethreg(BC, 0); - SETFLAG(N, 1); - SETFLAG(Z, 1); - break; - case 0xbb: /* OTDR */ - temp = hreg(BC); - do { + PutBYTE(HL, in(lreg(BC))); + --HL; + SETFLAG(N, 1); + Sethreg(BC, lreg(BC) - 1); + SETFLAG(Z, lreg(BC) == 0); + break; + case 0xab: /* OUTD */ + tStates += 16; CheckBreakByte(HL); - out(lreg(BC), GetBYTE(HL)); --HL; - } while (--temp); - Sethreg(BC, 0); - SETFLAG(N, 1); - SETFLAG(Z, 1); - break; - default: /* ignore ED and following byte */ - sim_brk_pend = FALSE; - checkCPUZ80; + out(lreg(BC), GetBYTE(HL)); + --HL; + SETFLAG(N, 1); + Sethreg(BC, lreg(BC) - 1); + SETFLAG(Z, lreg(BC) == 0); + break; + case 0xb0: /* LDIR */ + tStates -= 5; + acu = hreg(AF); + BC &= ADDRMASK; + do { + tStates += 21; + CheckBreakTwoBytes(HL, DE); + acu = RAM_pp(HL); + PutBYTE_pp(DE, acu); + } while (--BC); + acu += hreg(AF); + AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); + break; + case 0xb1: /* CPIR */ + tStates -= 5; + acu = hreg(AF); + BC &= ADDRMASK; + do { + tStates += 21; + CheckBreakByte(HL); + temp = RAM_pp(HL); + op = --BC != 0; + sum = acu - temp; + } while (op && sum != 0); + cbits = acu ^ temp ^ sum; + AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | + (((sum - ((cbits & 16) >> 4)) & 2) << 4) | + (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) | + op << 2 | 2; + if ((sum & 15) == 8 && (cbits & 16) != 0) { + AF &= ~8; + } + break; + case 0xb2: /* INIR */ + tStates -= 5; + temp = hreg(BC); + do { + tStates += 21; + CheckBreakByte(HL); + PutBYTE(HL, in(lreg(BC))); + ++HL; + } while (--temp); + Sethreg(BC, 0); + SETFLAG(N, 1); + SETFLAG(Z, 1); + break; + case 0xb3: /* OTIR */ + tStates -= 5; + temp = hreg(BC); + do { + tStates += 21; + CheckBreakByte(HL); + out(lreg(BC), GetBYTE(HL)); + ++HL; + } while (--temp); + Sethreg(BC, 0); + SETFLAG(N, 1); + SETFLAG(Z, 1); + break; + case 0xb8: /* LDDR */ + tStates -= 5; + BC &= ADDRMASK; + do { + tStates += 21; + CheckBreakTwoBytes(HL, DE); + acu = RAM_mm(HL); + PutBYTE_mm(DE, acu); + } while (--BC); + acu += hreg(AF); + AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4); + break; + case 0xb9: /* CPDR */ + tStates -= 5; + acu = hreg(AF); + BC &= ADDRMASK; + do { + tStates += 21; + CheckBreakByte(HL); + temp = RAM_mm(HL); + op = --BC != 0; + sum = acu - temp; + } while (op && sum != 0); + cbits = acu ^ temp ^ sum; + AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) | + (((sum - ((cbits & 16) >> 4)) & 2) << 4) | + (cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) | + op << 2 | 2; + if ((sum & 15) == 8 && (cbits & 16) != 0) { + AF &= ~8; + } + break; + case 0xba: /* INDR */ + tStates -= 5; + temp = hreg(BC); + do { + tStates += 21; + CheckBreakByte(HL); + PutBYTE(HL, in(lreg(BC))); + --HL; + } while (--temp); + Sethreg(BC, 0); + SETFLAG(N, 1); + SETFLAG(Z, 1); + break; + case 0xbb: /* OTDR */ + tStates -= 5; + temp = hreg(BC); + do { + tStates += 21; + CheckBreakByte(HL); + out(lreg(BC), GetBYTE(HL)); + --HL; + } while (--temp); + Sethreg(BC, 0); + SETFLAG(N, 1); + SETFLAG(Z, 1); + break; + default: /* ignore ED and following byte */ + sim_brk_pend = FALSE; + checkCPUZ80; } break; case 0xee: /* XOR nn */ + tStates += 7; sim_brk_pend = FALSE; - sum = ((AF >> 8) ^ RAM_pp(PC)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) ^ RAM_pp(PC)) & 0xff]; break; case 0xef: /* RST 28H */ + tStates += 11; CheckBreakWord(SP - 2); - PUSH(PC); PCQ_ENTRY(PC - 1); PC = 0x28; + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = 0x28; break; case 0xf0: /* RET P */ if (TSTFLAG(S)) { sim_brk_pend = FALSE; + tStates += 5; } else { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); + tStates += 11; } break; case 0xf1: /* POP AF */ + tStates += 10; CheckBreakWord(SP); POP(AF); break; case 0xf2: /* JP P,nnnn */ sim_brk_pend = FALSE; - JPC(!TSTFLAG(S)); + JPC(!TSTFLAG(S)); /* also updates tStates */ break; case 0xf3: /* DI */ + tStates += 4; sim_brk_pend = FALSE; IFF = 0; break; case 0xf4: /* CALL P,nnnn */ - CALLC(!TSTFLAG(S)); + CALLC(!TSTFLAG(S)); /* also updates tStates */ break; case 0xf5: /* PUSH AF */ + tStates += 11; CheckBreakWord(SP - 2); PUSH(AF); break; case 0xf6: /* OR nn */ + tStates += 7; sim_brk_pend = FALSE; - sum = ((AF >> 8) | RAM_pp(PC)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; + AF = xororTable[((AF >> 8) | RAM_pp(PC)) & 0xff]; break; case 0xf7: /* RST 30H */ + tStates += 11; CheckBreakWord(SP - 2); - PUSH(PC); PCQ_ENTRY(PC - 1); PC = 0x30; + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = 0x30; break; case 0xf8: /* RET M */ if (TSTFLAG(S)) { CheckBreakWord(SP); PCQ_ENTRY(PC - 1); POP(PC); + tStates += 11; } else { sim_brk_pend = FALSE; + tStates += 5; } break; case 0xf9: /* LD SP,HL */ + tStates += 6; sim_brk_pend = FALSE; SP = HL; break; case 0xfa: /* JP M,nnnn */ sim_brk_pend = FALSE; - JPC(TSTFLAG(S)); + JPC(TSTFLAG(S)); /* also updates tStates */ break; case 0xfb: /* EI */ + tStates += 4; sim_brk_pend = FALSE; IFF = 3; break; case 0xfc: /* CALL M,nnnn */ - CALLC(TSTFLAG(S)); + CALLC(TSTFLAG(S)); /* also updates tStates */ break; case 0xfd: /* FD prefix */ checkCPU8080; switch (op = RAM_pp(PC)) { - case 0x09: /* ADD IY,BC */ - sim_brk_pend = FALSE; - IY &= ADDRMASK; - BC &= ADDRMASK; - sum = IY + BC; - cbits = (IY ^ BC ^ sum) >> 8; - IY = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x19: /* ADD IY,DE */ - sim_brk_pend = FALSE; - IY &= ADDRMASK; - DE &= ADDRMASK; - sum = IY + DE; - cbits = (IY ^ DE ^ sum) >> 8; - IY = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x21: /* LD IY,nnnn */ - sim_brk_pend = FALSE; - IY = GetWORD(PC); - PC += 2; - break; - case 0x22: /* LD (nnnn),IY */ - temp = GetWORD(PC); - CheckBreakWord(temp); - PutWORD(temp, IY); - PC += 2; - break; - case 0x23: /* INC IY */ - sim_brk_pend = FALSE; - ++IY; - break; - case 0x24: /* INC IYH */ - sim_brk_pend = FALSE; - IY += 0x100; - temp = hreg(IY); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x25: /* DEC IYH */ - sim_brk_pend = FALSE; - IY -= 0x100; - temp = hreg(IY); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x26: /* LD IYH,nn */ - sim_brk_pend = FALSE; - Sethreg(IY, RAM_pp(PC)); - break; - case 0x29: /* ADD IY,IY */ - sim_brk_pend = FALSE; - IY &= ADDRMASK; - sum = IY + IY; - cbits = (IY ^ IY ^ sum) >> 8; - IY = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x2a: /* LD IY,(nnnn) */ - temp = GetWORD(PC); - CheckBreakWord(temp); - IY = GetWORD(temp); - PC += 2; - break; - case 0x2b: /* DEC IY */ - sim_brk_pend = FALSE; - --IY; - break; - case 0x2c: /* INC IYL */ - sim_brk_pend = FALSE; - temp = lreg(IY) + 1; - Setlreg(IY, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x2d: /* DEC IYL */ - sim_brk_pend = FALSE; - temp = lreg(IY) - 1; - Setlreg(IY, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x2e: /* LD IYL,nn */ - sim_brk_pend = FALSE; - Setlreg(IY, RAM_pp(PC)); - break; - case 0x34: /* INC (IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr) + 1; - PutBYTE(adr, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0) << 4) | - ((temp == 0x80) << 2); - break; - case 0x35: /* DEC (IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr) - 1; - PutBYTE(adr, temp); - AF = (AF & ~0xfe) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - (((temp & 0xf) == 0xf) << 4) | - ((temp == 0x7f) << 2) | 2; - break; - case 0x36: /* LD (IY+dd),nn */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, RAM_pp(PC)); - break; - case 0x39: /* ADD IY,SP */ - sim_brk_pend = FALSE; - IY &= ADDRMASK; - SP &= ADDRMASK; - sum = IY + SP; - cbits = (IY ^ SP ^ sum) >> 8; - IY = sum; - AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0x44: /* LD B,IYH */ - sim_brk_pend = FALSE; - Sethreg(BC, hreg(IY)); - break; - case 0x45: /* LD B,IYL */ - sim_brk_pend = FALSE; - Sethreg(BC, lreg(IY)); - break; - case 0x46: /* LD B,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Sethreg(BC, GetBYTE(adr)); - break; - case 0x4c: /* LD C,IYH */ - sim_brk_pend = FALSE; - Setlreg(BC, hreg(IY)); - break; - case 0x4d: /* LD C,IYL */ - sim_brk_pend = FALSE; - Setlreg(BC, lreg(IY)); - break; - case 0x4e: /* LD C,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Setlreg(BC, GetBYTE(adr)); - break; - case 0x54: /* LD D,IYH */ - sim_brk_pend = FALSE; - Sethreg(DE, hreg(IY)); - break; - case 0x55: /* LD D,IYL */ - sim_brk_pend = FALSE; - Sethreg(DE, lreg(IY)); - break; - case 0x56: /* LD D,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Sethreg(DE, GetBYTE(adr)); - break; - case 0x5c: /* LD E,H */ - sim_brk_pend = FALSE; - Setlreg(DE, hreg(IY)); - break; - case 0x5d: /* LD E,L */ - sim_brk_pend = FALSE; - Setlreg(DE, lreg(IY)); - break; - case 0x5e: /* LD E,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Setlreg(DE, GetBYTE(adr)); - break; - case 0x60: /* LD IYH,B */ - sim_brk_pend = FALSE; - Sethreg(IY, hreg(BC)); - break; - case 0x61: /* LD IYH,C */ - sim_brk_pend = FALSE; - Sethreg(IY, lreg(BC)); - break; - case 0x62: /* LD IYH,D */ - sim_brk_pend = FALSE; - Sethreg(IY, hreg(DE)); - break; - case 0x63: /* LD IYH,E */ - sim_brk_pend = FALSE; - Sethreg(IY, lreg(DE)); - break; - case 0x64: /* LD IYH,IYH */ - sim_brk_pend = FALSE; - /* nop */ - break; - case 0x65: /* LD IYH,IYL */ - sim_brk_pend = FALSE; - Sethreg(IY, lreg(IY)); - break; - case 0x66: /* LD H,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Sethreg(HL, GetBYTE(adr)); - break; - case 0x67: /* LD IYH,A */ - sim_brk_pend = FALSE; - Sethreg(IY, hreg(AF)); - break; - case 0x68: /* LD IYL,B */ - sim_brk_pend = FALSE; - Setlreg(IY, hreg(BC)); - break; - case 0x69: /* LD IYL,C */ - sim_brk_pend = FALSE; - Setlreg(IY, lreg(BC)); - break; - case 0x6a: /* LD IYL,D */ - sim_brk_pend = FALSE; - Setlreg(IY, hreg(DE)); - break; - case 0x6b: /* LD IYL,E */ - sim_brk_pend = FALSE; - Setlreg(IY, lreg(DE)); - break; - case 0x6c: /* LD IYL,IYH */ - sim_brk_pend = FALSE; - Setlreg(IY, hreg(IY)); - break; - case 0x6d: /* LD IYL,IYL */ - sim_brk_pend = FALSE; - /* nop */ - break; - case 0x6e: /* LD L,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Setlreg(HL, GetBYTE(adr)); - break; - case 0x6f: /* LD IYL,A */ - sim_brk_pend = FALSE; - Setlreg(IY, hreg(AF)); - break; - case 0x70: /* LD (IY+dd),B */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, hreg(BC)); - break; - case 0x71: /* LD (IY+dd),C */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, lreg(BC)); - break; - case 0x72: /* LD (IY+dd),D */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, hreg(DE)); - break; - case 0x73: /* LD (IY+dd),E */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, lreg(DE)); - break; - case 0x74: /* LD (IY+dd),H */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, hreg(HL)); - break; - case 0x75: /* LD (IY+dd),L */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, lreg(HL)); - break; - case 0x77: /* LD (IY+dd),A */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - PutBYTE(adr, hreg(AF)); - break; - case 0x7c: /* LD A,IYH */ - sim_brk_pend = FALSE; - Sethreg(AF, hreg(IY)); - break; - case 0x7d: /* LD A,IYL */ - sim_brk_pend = FALSE; - Sethreg(AF, lreg(IY)); - break; - case 0x7e: /* LD A,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - Sethreg(AF, GetBYTE(adr)); - break; - case 0x84: /* ADD A,IYH */ - sim_brk_pend = FALSE; - temp = hreg(IY); - acu = hreg(AF); - sum = acu + temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x85: /* ADD A,IYL */ - sim_brk_pend = FALSE; - temp = lreg(IY); - acu = hreg(AF); - sum = acu + temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x86: /* ADD A,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - acu = hreg(AF); - sum = acu + temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8c: /* ADC A,IYH */ - sim_brk_pend = FALSE; - temp = hreg(IY); - acu = hreg(AF); - sum = acu + temp + TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8d: /* ADC A,IYL */ - sim_brk_pend = FALSE; - temp = lreg(IY); - acu = hreg(AF); - sum = acu + temp + TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x8e: /* ADC A,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - acu = hreg(AF); - sum = acu + temp + TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | - ((cbits >> 8) & 1); - break; - case 0x94: /* SUB IYH */ - sim_brk_pend = FALSE; - temp = hreg(IY); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x95: /* SUB IYL */ - sim_brk_pend = FALSE; - temp = lreg(IY); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x96: /* SUB (IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9c: /* SBC A,IYH */ - sim_brk_pend = FALSE; - temp = hreg(IY); - acu = hreg(AF); - sum = acu - temp - TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9d: /* SBC A,IYL */ - sim_brk_pend = FALSE; - temp = lreg(IY); - acu = hreg(AF); - sum = acu - temp - TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0x9e: /* SBC A,(IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - acu = hreg(AF); - sum = acu - temp - TSTFLAG(C); - cbits = acu ^ temp ^ sum; - AF = ((sum & 0xff) << 8) | (sum & 0xa8) | - (((sum & 0xff) == 0) << 6) | (cbits & 0x10) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - ((cbits >> 8) & 1); - break; - case 0xa4: /* AND IYH */ - sim_brk_pend = FALSE; - sum = ((AF & (IY)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | - ((sum == 0) << 6) | 0x10 | partab[sum]; - break; - case 0xa5: /* AND IYL */ - sim_brk_pend = FALSE; - sum = ((AF >> 8) & IY) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xa6: /* AND (IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - sum = ((AF >> 8) & GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | 0x10 | - ((sum == 0) << 6) | partab[sum]; - break; - case 0xac: /* XOR IYH */ - sim_brk_pend = FALSE; - sum = ((AF ^ (IY)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xad: /* XOR IYL */ - sim_brk_pend = FALSE; - sum = ((AF >> 8) ^ IY) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xae: /* XOR (IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - sum = ((AF >> 8) ^ GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xb4: /* OR IYH */ - sim_brk_pend = FALSE; - sum = ((AF | (IY)) >> 8) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xb5: /* OR IYL */ - sim_brk_pend = FALSE; - sum = ((AF >> 8) | IY) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xb6: /* OR (IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - sum = ((AF >> 8) | GetBYTE(adr)) & 0xff; - AF = (sum << 8) | (sum & 0xa8) | ((sum == 0) << 6) | partab[sum]; - break; - case 0xbc: /* CP IYH */ - sim_brk_pend = FALSE; - temp = hreg(IY); - AF = (AF & ~0x28) | (temp & 0x28); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xbd: /* CP IYL */ - sim_brk_pend = FALSE; - temp = lreg(IY); - AF = (AF & ~0x28) | (temp & 0x28); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xbe: /* CP (IY+dd) */ - adr = IY + (signed char) RAM_pp(PC); - CheckBreakByte(adr); - temp = GetBYTE(adr); - AF = (AF & ~0x28) | (temp & 0x28); - acu = hreg(AF); - sum = acu - temp; - cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (((cbits >> 6) ^ (cbits >> 5)) & 4) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); - break; - case 0xcb: /* CB prefix */ - adr = IY + (signed char) RAM_pp(PC); - switch ((op = GetBYTE(PC)) & 7) { - case 0: sim_brk_pend = FALSE; ++PC; acu = hreg(BC); break; - case 1: sim_brk_pend = FALSE; ++PC; acu = lreg(BC); break; - case 2: sim_brk_pend = FALSE; ++PC; acu = hreg(DE); break; - case 3: sim_brk_pend = FALSE; ++PC; acu = lreg(DE); break; - case 4: sim_brk_pend = FALSE; ++PC; acu = hreg(HL); break; - case 5: sim_brk_pend = FALSE; ++PC; acu = lreg(HL); break; - case 6: CheckBreakByte(adr); ++PC; acu = GetBYTE(adr); break; - case 7: sim_brk_pend = FALSE; ++PC; acu = hreg(AF); break; - } - switch (op & 0xc0) { - case 0x00: /* shift/rotate */ - switch (op & 0x38) { - case 0x00: /* RLC */ - temp = (acu << 1) | (acu >> 7); - cbits = temp & 1; - goto cbshflg3; - case 0x08: /* RRC */ - temp = (acu >> 1) | (acu << 7); - cbits = temp & 0x80; - goto cbshflg3; - case 0x10: /* RL */ - temp = (acu << 1) | TSTFLAG(C); - cbits = acu & 0x80; - goto cbshflg3; - case 0x18: /* RR */ - temp = (acu >> 1) | (TSTFLAG(C) << 7); - cbits = acu & 1; - goto cbshflg3; - case 0x20: /* SLA */ - temp = acu << 1; - cbits = acu & 0x80; - goto cbshflg3; - case 0x28: /* SRA */ - temp = (acu >> 1) | (acu & 0x80); - cbits = acu & 1; - goto cbshflg3; - case 0x30: /* SLIA */ - temp = (acu << 1) | 1; - cbits = acu & 0x80; - goto cbshflg3; - case 0x38: /* SRL */ - temp = acu >> 1; - cbits = acu & 1; - cbshflg3: - AF = (AF & ~0xff) | (temp & 0xa8) | - (((temp & 0xff) == 0) << 6) | - parity(temp) | !!cbits; + case 0x09: /* ADD IY,BC */ + tStates += 15; + sim_brk_pend = FALSE; + IY &= ADDRMASK; + BC &= ADDRMASK; + sum = IY + BC; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ BC ^ sum) >> 8]; + IY = sum; + break; + case 0x19: /* ADD IY,DE */ + tStates += 15; + sim_brk_pend = FALSE; + IY &= ADDRMASK; + DE &= ADDRMASK; + sum = IY + DE; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ DE ^ sum) >> 8]; + IY = sum; + break; + case 0x21: /* LD IY,nnnn */ + tStates += 14; + sim_brk_pend = FALSE; + IY = GetWORD(PC); + PC += 2; + break; + case 0x22: /* LD (nnnn),IY */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + PutWORD(temp, IY); + PC += 2; + break; + case 0x23: /* INC IY */ + tStates += 10; + sim_brk_pend = FALSE; + ++IY; + break; + case 0x24: /* INC IYH */ + tStates += 9; + sim_brk_pend = FALSE; + IY += 0x100; + AF = (AF & ~0xfe) | incZ80Table[hreg(IY)]; + break; + case 0x25: /* DEC IYH */ + tStates += 9; + sim_brk_pend = FALSE; + IY -= 0x100; + AF = (AF & ~0xfe) | decZ80Table[hreg(IY)]; + break; + case 0x26: /* LD IYH,nn */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IY, RAM_pp(PC)); + break; + case 0x29: /* ADD IY,IY */ + tStates += 15; + sim_brk_pend = FALSE; + IY &= ADDRMASK; + sum = IY + IY; + AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8]; + IY = sum; + break; + case 0x2a: /* LD IY,(nnnn) */ + tStates += 20; + temp = GetWORD(PC); + CheckBreakWord(temp); + IY = GetWORD(temp); + PC += 2; + break; + case 0x2b: /* DEC IY */ + tStates += 10; + sim_brk_pend = FALSE; + --IY; + break; + case 0x2c: /* INC IYL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IY) + 1; + Setlreg(IY, temp); + AF = (AF & ~0xfe) | incZ80Table[temp]; + break; + case 0x2d: /* DEC IYL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IY) - 1; + Setlreg(IY, temp); + AF = (AF & ~0xfe) | decZ80Table[temp & 0xff]; + break; + case 0x2e: /* LD IYL,nn */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IY, RAM_pp(PC)); + break; + case 0x34: /* INC (IY+dd) */ + tStates += 23; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr) + 1; + PutBYTE(adr, temp); + AF = (AF & ~0xfe) | incZ80Table[temp]; + break; + case 0x35: /* DEC (IY+dd) */ + tStates += 23; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr) - 1; + PutBYTE(adr, temp); + AF = (AF & ~0xfe) | decZ80Table[temp & 0xff]; + break; + case 0x36: /* LD (IY+dd),nn */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, RAM_pp(PC)); + break; + case 0x39: /* ADD IY,SP */ + tStates += 15; + sim_brk_pend = FALSE; + IY &= ADDRMASK; + SP &= ADDRMASK; + sum = IY + SP; + AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ SP ^ sum) >> 8]; + IY = sum; + break; + case 0x44: /* LD B,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(BC, hreg(IY)); + break; + case 0x45: /* LD B,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(BC, lreg(IY)); + break; + case 0x46: /* LD B,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Sethreg(BC, GetBYTE(adr)); + break; + case 0x4c: /* LD C,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(BC, hreg(IY)); + break; + case 0x4d: /* LD C,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(BC, lreg(IY)); + break; + case 0x4e: /* LD C,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Setlreg(BC, GetBYTE(adr)); + break; + case 0x54: /* LD D,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(DE, hreg(IY)); + break; + case 0x55: /* LD D,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(DE, lreg(IY)); + break; + case 0x56: /* LD D,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Sethreg(DE, GetBYTE(adr)); + break; + case 0x5c: /* LD E,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(DE, hreg(IY)); + break; + case 0x5d: /* LD E,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(DE, lreg(IY)); + break; + case 0x5e: /* LD E,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Setlreg(DE, GetBYTE(adr)); + break; + case 0x60: /* LD IYH,B */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IY, hreg(BC)); + break; + case 0x61: /* LD IYH,C */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IY, lreg(BC)); + break; + case 0x62: /* LD IYH,D */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IY, hreg(DE)); + break; + case 0x63: /* LD IYH,E */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IY, lreg(DE)); + break; + case 0x64: /* LD IYH,IYH */ + tStates += 9; + sim_brk_pend = FALSE; /* nop */ + break; + case 0x65: /* LD IYH,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IY, lreg(IY)); + break; + case 0x66: /* LD H,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Sethreg(HL, GetBYTE(adr)); + break; + case 0x67: /* LD IYH,A */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(IY, hreg(AF)); + break; + case 0x68: /* LD IYL,B */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IY, hreg(BC)); + break; + case 0x69: /* LD IYL,C */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IY, lreg(BC)); + break; + case 0x6a: /* LD IYL,D */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IY, hreg(DE)); + break; + case 0x6b: /* LD IYL,E */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IY, lreg(DE)); + break; + case 0x6c: /* LD IYL,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IY, hreg(IY)); + break; + case 0x6d: /* LD IYL,IYL */ + tStates += 9; + sim_brk_pend = FALSE; /* nop */ + break; + case 0x6e: /* LD L,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Setlreg(HL, GetBYTE(adr)); + break; + case 0x6f: /* LD IYL,A */ + tStates += 9; + sim_brk_pend = FALSE; + Setlreg(IY, hreg(AF)); + break; + case 0x70: /* LD (IY+dd),B */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, hreg(BC)); + break; + case 0x71: /* LD (IY+dd),C */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, lreg(BC)); + break; + case 0x72: /* LD (IY+dd),D */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, hreg(DE)); + break; + case 0x73: /* LD (IY+dd),E */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, lreg(DE)); + break; + case 0x74: /* LD (IY+dd),H */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, hreg(HL)); + break; + case 0x75: /* LD (IY+dd),L */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, lreg(HL)); + break; + case 0x77: /* LD (IY+dd),A */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + PutBYTE(adr, hreg(AF)); + break; + case 0x7c: /* LD A,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(AF, hreg(IY)); + break; + case 0x7d: /* LD A,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + Sethreg(AF, lreg(IY)); + break; + case 0x7e: /* LD A,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + Sethreg(AF, GetBYTE(adr)); + break; + case 0x84: /* ADD A,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + temp = hreg(IY); + acu = hreg(AF); + sum = acu + temp; + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x85: /* ADD A,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IY); + acu = hreg(AF); + sum = acu + temp; + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x86: /* ADD A,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + acu = hreg(AF); + sum = acu + temp; + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x8c: /* ADC A,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + temp = hreg(IY); + acu = hreg(AF); + sum = acu + temp + TSTFLAG(C); + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x8d: /* ADC A,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IY); + acu = hreg(AF); + sum = acu + temp + TSTFLAG(C); + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x8e: /* ADC A,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + acu = hreg(AF); + sum = acu + temp + TSTFLAG(C); + AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum]; + break; + case 0x96: /* SUB (IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + acu = hreg(AF); + sum = acu - temp; + AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0x94: /* SUB IYH */ + SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */ + case 0x9c: /* SBC A,IYH */ + tStates += 9; + sim_brk_pend = FALSE; + temp = hreg(IY); + acu = hreg(AF); + sum = acu - temp - TSTFLAG(C); + AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0x95: /* SUB IYL */ + SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */ + case 0x9d: /* SBC A,IYL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IY); + acu = hreg(AF); + sum = acu - temp - TSTFLAG(C); + AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0x9e: /* SBC A,(IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + acu = hreg(AF); + sum = acu - temp - TSTFLAG(C); + AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0xa4: /* AND IYH */ + tStates += 9; + sim_brk_pend = FALSE; + AF = andTable[((AF & IY) >> 8) & 0xff]; + break; + case 0xa5: /* AND IYL */ + tStates += 9; + sim_brk_pend = FALSE; + AF = andTable[((AF >> 8) & IY) & 0xff]; + break; + case 0xa6: /* AND (IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + AF = andTable[((AF >> 8) & GetBYTE(adr)) & 0xff]; + break; + case 0xac: /* XOR IYH */ + tStates += 9; + sim_brk_pend = FALSE; + AF = xororTable[((AF ^ IY) >> 8) & 0xff]; + break; + case 0xad: /* XOR IYL */ + tStates += 9; + sim_brk_pend = FALSE; + AF = xororTable[((AF >> 8) ^ IY) & 0xff]; + break; + case 0xae: /* XOR (IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + AF = xororTable[((AF >> 8) ^ GetBYTE(adr)) & 0xff]; + break; + case 0xb4: /* OR IYH */ + tStates += 9; + sim_brk_pend = FALSE; + AF = xororTable[((AF | IY) >> 8) & 0xff]; + break; + case 0xb5: /* OR IYL */ + tStates += 9; + sim_brk_pend = FALSE; + AF = xororTable[((AF >> 8) | IY) & 0xff]; + break; + case 0xb6: /* OR (IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + AF = xororTable[((AF >> 8) | GetBYTE(adr)) & 0xff]; + break; + case 0xbc: /* CP IYH */ + tStates += 9; + sim_brk_pend = FALSE; + temp = hreg(IY); + AF = (AF & ~0x28) | (temp & 0x28); + acu = hreg(AF); + sum = acu - temp; + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0xbd: /* CP IYL */ + tStates += 9; + sim_brk_pend = FALSE; + temp = lreg(IY); + AF = (AF & ~0x28) | (temp & 0x28); + acu = hreg(AF); + sum = acu - temp; + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0xbe: /* CP (IY+dd) */ + tStates += 19; + adr = IY + (signed char) RAM_pp(PC); + CheckBreakByte(adr); + temp = GetBYTE(adr); + AF = (AF & ~0x28) | (temp & 0x28); + acu = hreg(AF); + sum = acu - temp; + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff]; + break; + case 0xcb: /* CB prefix */ + adr = IY + (signed char) RAM_pp(PC); + switch ((op = GetBYTE(PC)) & 7) { + case 0: + sim_brk_pend = FALSE; + ++PC; + acu = hreg(BC); + break; + case 1: + sim_brk_pend = FALSE; + ++PC; + acu = lreg(BC); + break; + case 2: + sim_brk_pend = FALSE; + ++PC; + acu = hreg(DE); + break; + case 3: + sim_brk_pend = FALSE; + ++PC; + acu = lreg(DE); + break; + case 4: + sim_brk_pend = FALSE; + ++PC; + acu = hreg(HL); + break; + case 5: + sim_brk_pend = FALSE; + ++PC; + acu = lreg(HL); + break; + case 6: + CheckBreakByte(adr); + ++PC; + acu = GetBYTE(adr); + break; + case 7: + sim_brk_pend = FALSE; + ++PC; + acu = hreg(AF); + break; + } + switch (op & 0xc0) { + case 0x00: /* shift/rotate */ + tStates += 23; + switch (op & 0x38) { + case 0x00: /* RLC */ + temp = (acu << 1) | (acu >> 7); + cbits = temp & 1; + goto cbshflg3; + case 0x08: /* RRC */ + temp = (acu >> 1) | (acu << 7); + cbits = temp & 0x80; + goto cbshflg3; + case 0x10: /* RL */ + temp = (acu << 1) | TSTFLAG(C); + cbits = acu & 0x80; + goto cbshflg3; + case 0x18: /* RR */ + temp = (acu >> 1) | (TSTFLAG(C) << 7); + cbits = acu & 1; + goto cbshflg3; + case 0x20: /* SLA */ + temp = acu << 1; + cbits = acu & 0x80; + goto cbshflg3; + case 0x28: /* SRA */ + temp = (acu >> 1) | (acu & 0x80); + cbits = acu & 1; + goto cbshflg3; + case 0x30: /* SLIA */ + temp = (acu << 1) | 1; + cbits = acu & 0x80; + goto cbshflg3; + case 0x38: /* SRL */ + temp = acu >> 1; + cbits = acu & 1; + cbshflg3: + AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits; + } + break; + case 0x40: /* BIT */ + tStates += 20; + if (acu & (1 << ((op >> 3) & 7))) { + AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7); + } + else { + AF = (AF & ~0xfe) | 0x54; + } + if ((op & 7) != 6) { + AF |= (acu & 0x28); + } + temp = acu; + break; + case 0x80: /* RES */ + tStates += 23; + temp = acu & ~(1 << ((op >> 3) & 7)); + break; + case 0xc0: /* SET */ + tStates += 23; + temp = acu | (1 << ((op >> 3) & 7)); + break; + } + switch (op & 7) { + case 0: + Sethreg(BC, temp); + break; + case 1: + Setlreg(BC, temp); + break; + case 2: + Sethreg(DE, temp); + break; + case 3: + Setlreg(DE, temp); + break; + case 4: + Sethreg(HL, temp); + break; + case 5: + Setlreg(HL, temp); + break; + case 6: + PutBYTE(adr, temp); + break; + case 7: + Sethreg(AF, temp); + break; } break; - case 0x40: /* BIT */ - if (acu & (1 << ((op >> 3) & 7))) { - AF = (AF & ~0xfe) | 0x10 | - (((op & 0x38) == 0x38) << 7); - } - else { - AF = (AF & ~0xfe) | 0x54; - } - if ((op & 7) != 6) { - AF |= (acu & 0x28); - } - temp = acu; + case 0xe1: /* POP IY */ + tStates += 14; + CheckBreakWord(SP); + POP(IY); break; - case 0x80: /* RES */ - temp = acu & ~(1 << ((op >> 3) & 7)); + case 0xe3: /* EX (SP),IY */ + tStates += 23; + CheckBreakWord(SP); + temp = IY; + POP(IY); + PUSH(temp); break; - case 0xc0: /* SET */ - temp = acu | (1 << ((op >> 3) & 7)); + case 0xe5: /* PUSH IY */ + tStates += 15; + CheckBreakWord(SP - 2); + PUSH(IY); break; - } - switch (op & 7) { - case 0: Sethreg(BC, temp); break; - case 1: Setlreg(BC, temp); break; - case 2: Sethreg(DE, temp); break; - case 3: Setlreg(DE, temp); break; - case 4: Sethreg(HL, temp); break; - case 5: Setlreg(HL, temp); break; - case 6: PutBYTE(adr, temp); break; - case 7: Sethreg(AF, temp); break; - } - break; - case 0xe1: /* POP IY */ - CheckBreakWord(SP); - POP(IY); - break; - case 0xe3: /* EX (SP),IY */ - CheckBreakWord(SP); - temp = IY; POP(IY); PUSH(temp); - break; - case 0xe5: /* PUSH IY */ - CheckBreakWord(SP - 2); - PUSH(IY); - break; - case 0xe9: /* JP (IY) */ - sim_brk_pend = FALSE; - PCQ_ENTRY(PC - 2); - PC = IY; - break; - case 0xf9: /* LD SP,IY */ - sim_brk_pend = FALSE; - SP = IY; - break; - default: /* ignore FD */ - sim_brk_pend = FALSE; - checkCPUZ80; - PC--; + case 0xe9: /* JP (IY) */ + tStates += 8; + sim_brk_pend = FALSE; + PCQ_ENTRY(PC - 2); + PC = IY; + break; + case 0xf9: /* LD SP,IY */ + tStates += 10; + sim_brk_pend = FALSE; + SP = IY; + break; + default: /* ignore FD */ + sim_brk_pend = FALSE; + checkCPUZ80; + PC--; } break; case 0xfe: /* CP nn */ + tStates += 7; sim_brk_pend = FALSE; temp = RAM_pp(PC); AF = (AF & ~0x28) | (temp & 0x28); acu = hreg(AF); sum = acu - temp; cbits = acu ^ temp ^ sum; - AF = (AF & ~0xff) | (sum & 0x80) | - (((sum & 0xff) == 0) << 6) | (temp & 0x28) | - (SetPV) | 2 | - (cbits & 0x10) | ((cbits >> 8) & 1); + AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) | + (SetPV) | cbits2Table[cbits & 0x1ff]; break; case 0xff: /* RST 38H */ + tStates += 11; CheckBreakWord(SP - 2); - PUSH(PC); PCQ_ENTRY(PC - 1); PC = 0x38; + PUSH(PC); + PCQ_ENTRY(PC - 1); + PC = 0x38; } } end_decode: @@ -4135,7 +5390,7 @@ int32 sim_instr (void) { iy = IY; sp = SP; - /* Simulation halted */ + /* simulation halted */ saved_PC = ((reason == STOP_OPCODE) || (reason == STOP_MEM)) ? PCX : pc; pcq_r -> qptr = pcq_p; /* update pc q ptr */ AF_S = af[af_sel]; @@ -4150,7 +5405,8 @@ int32 sim_instr (void) { DE1_S = regs[1 - regs_sel].de; HL1_S = regs[1 - regs_sel].hl; IFF_S = IFF; - INT_S = ir; + IR_S = ir; + executedTStates = tStates; return reason; } @@ -4165,23 +5421,23 @@ int32 install_bootrom(void) { return cnt; } -int32 lowProtect; -int32 highProtect; -int32 isProtected = FALSE; +static int32 lowProtect; +static int32 highProtect; +static int32 isProtected = FALSE; -void protect(int32 l, int32 h) { +void protect(const int32 l, const int32 h) { isProtected = TRUE; lowProtect = l; highProtect = h; } -void resetCell(int32 address, int32 bank) { +static void resetCell(const int32 address, const int32 bank) { if (!(isProtected && (bank == 0) && (lowProtect <= address) && (address <= highProtect))) { M[address][bank] = 0; } } -void reset_memory(void) { +static void reset_memory(void) { uint32 i, j; checkROMBoundaries(); if (cpu_unit.flags & UNIT_BANKED) { @@ -4195,7 +5451,7 @@ void reset_memory(void) { for (i = 0; i < ROMLow; i++) { resetCell(i, 0); } - for (i = ROMHigh+1; i < MAXMEMSIZE; i++) { + for (i = ROMHigh + 1; i < MAXMEMSIZE; i++) { resetCell(i, 0); } } @@ -4210,7 +5466,13 @@ void reset_memory(void) { isProtected = FALSE; } -/* Reset routine */ +void printROMMessage(const uint32 cntROM) { + if (cntROM) { + printf("Warning: %d bytes written to ROM [%04X - %04X].\n", cntROM, ROMLow, ROMHigh); + } +} + +/* reset routine */ t_stat cpu_reset(DEVICE *dptr) { int32 i; @@ -4219,7 +5481,7 @@ t_stat cpu_reset(DEVICE *dptr) { BC_S = DE_S = HL_S = 0; regs_sel = 0; BC1_S = DE1_S = HL1_S = 0; - INT_S = IX_S = IY_S = SP_S = 0; + IR_S = IX_S = IY_S = SP_S = 0; IFF_S = 3; bankSelect = 0; reset_memory(); @@ -4239,31 +5501,19 @@ t_stat cpu_reset(DEVICE *dptr) { return SCPE_OK; } -/* Memory examine */ +/* memory examine */ t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) { - if (addressExists(addr)) { - if (vptr != NULL) { - *vptr = GetBYTE(addr) & 0xff; - } - return SCPE_OK; - } - else { - return SCPE_NXM; - } + *vptr = M[addr & ADDRMASK][(addr >> 16) & BANKMASK]; + return SCPE_OK; } -/* Memory deposit */ +/* memory deposit */ t_stat cpu_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw) { - if (addressExists(addr) && (!addressIsInROM(addr))) { - PutBYTE(addr, val & 0xff); - return SCPE_OK; - } - else { - return SCPE_NXM; - } + M[addr & ADDRMASK][(addr >> 16) & BANKMASK] = val & 0xff; + return SCPE_OK; } -void checkROMBoundaries(void) { +static void checkROMBoundaries(void) { uint32 temp; if (ROMLow > ROMHigh) { printf("ROMLOW [%04X] must be less than or equal to ROMHIGH [%04X]. Values exchanged.\n", @@ -4284,12 +5534,12 @@ void checkROMBoundaries(void) { } } -t_stat cpu_set_rom(UNIT *uptr, int32 value, char *cptr, void *desc) { +static t_stat cpu_set_rom(UNIT *uptr, int32 value, char *cptr, void *desc) { checkROMBoundaries(); return SCPE_OK; } -t_stat cpu_set_norom(UNIT *uptr, int32 value, char *cptr, void *desc) { +static t_stat cpu_set_norom(UNIT *uptr, int32 value, char *cptr, void *desc) { if (cpu_unit.flags & UNIT_ALTAIRROM) { printf("\"SET CPU NOALTAIRROM\" also executed.\n"); cpu_unit.flags &= ~UNIT_ALTAIRROM; @@ -4297,7 +5547,7 @@ t_stat cpu_set_norom(UNIT *uptr, int32 value, char *cptr, void *desc) { return SCPE_OK; } -t_stat cpu_set_altairrom(UNIT *uptr, int32 value, char *cptr, void *desc) { +static t_stat cpu_set_altairrom(UNIT *uptr, int32 value, char *cptr, void *desc) { install_bootrom(); if (ROMLow != defaultROMLow) { printf("\"D ROMLOW %04X\" also executed.\n", defaultROMLow); @@ -4314,36 +5564,42 @@ t_stat cpu_set_altairrom(UNIT *uptr, int32 value, char *cptr, void *desc) { return SCPE_OK; } -t_stat cpu_set_warnrom(UNIT *uptr, int32 value, char *cptr, void *desc) { - if ((!(cpu_unit.flags & UNIT_ROM)) && (MEMSIZE == 64*KB)) { - printf("CPU has currently 64 Kb available for writing.\n"); +static t_stat cpu_set_warnrom(UNIT *uptr, int32 value, char *cptr, void *desc) { + if ((!(cpu_unit.flags & UNIT_ROM)) && (MEMSIZE >= 64*KB)) { + printf("CPU has currently no ROM - no warning to be expected.\n"); } return SCPE_OK; } -t_stat cpu_set_banked(UNIT *uptr, int32 value, char *cptr, void *desc) { +static t_stat cpu_set_banked(UNIT *uptr, int32 value, char *cptr, void *desc) { if (common > defaultROMLow) { printf("Warning: COMMON [%04X] must not be greater than %04X. Reset to %04X.\n", common, defaultROMLow, defaultROMLow); common = defaultROMLow; } - if (MEMSIZE < MAXMEMSIZE) { - printf("\"SET CPU 64K\" also executed.\n"); - MEMSIZE = MAXMEMSIZE; - reset_memory(); + if (MEMSIZE != (MAXBANKS * MAXMEMSIZE)) { + previousCapacity = MEMSIZE; } + MEMSIZE = MAXBANKS * MAXMEMSIZE; + cpu_dev.awidth = 16 + MAXBANKSLOG2; return SCPE_OK; } -t_stat cpu_set_size(UNIT *uptr, int32 value, char *cptr, void *desc) { - if ((cpu_unit.flags & UNIT_BANKED) && (value < MAXMEMSIZE)) { +static t_stat cpu_set_nonbanked(UNIT *uptr, int32 value, char *cptr, void *desc) { + if (MEMSIZE == (MAXBANKS * MAXMEMSIZE)) { + MEMSIZE = previousCapacity ? previousCapacity : 64*KB; + } + cpu_dev.awidth = 16; + return SCPE_OK; +} + +static t_stat cpu_set_size(UNIT *uptr, int32 value, char *cptr, void *desc) { + if (cpu_unit.flags & UNIT_BANKED) { printf("\"SET CPU NONBANKED\" also executed.\n"); cpu_unit.flags &= ~UNIT_BANKED; } - if ((value <= 0) || (value > MAXMEMSIZE) || ((value & 0xfff) != 0)) { - return SCPE_ARG; - } MEMSIZE = value; + cpu_dev.awidth = 16; reset_memory(); return SCPE_OK; } diff --git a/AltairZ80/altairZ80_defs.h b/AltairZ80/altairZ80_defs.h index 83a37004..c693595e 100644 --- a/AltairZ80/altairZ80_defs.h +++ b/AltairZ80/altairZ80_defs.h @@ -1,35 +1,34 @@ -/* altairZ80_defs.h: MITS Altair simulator definitions +/* altairz80_defs.h: MITS Altair simulator definitions - Copyright (c) 2002, Peter Schorn + Copyright (c) 2002, Peter Schorn - 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: + 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 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 - ROBERT M SUPNIK 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. + 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 + PETER SCHORN 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. - Except as contained in this notice, the name of Peter Schorn shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Peter Schorn. + Except as contained in this notice, the name of Peter Schorn shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Peter Schorn. - Based on work by Charles E Owen (c) 1997 + Based on work by Charles E Owen (c) 1997 */ #include "sim_defs.h" /* simulator definitions */ -/* Memory */ -#define MAXMEMSIZE 65536 /* max memory size */ +#define MAXMEMSIZE 65536 /* maximum memory size */ #define ADDRMASK (MAXMEMSIZE - 1) /* address mask */ #define bootrom_size 256 /* size of boot rom */ #define MAXBANKS 8 /* max number of memory banks */ @@ -45,19 +44,19 @@ #define unitNoOffset1 0x37 /* LD A, */ #define unitNoOffset2 0xb4 /* LD a,80h | */ -#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* Stop on Invalid OP? */ +#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* stop on nvalid operation */ #define UNIT_OPSTOP (1 << UNIT_V_OPSTOP) -#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 */ +#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 CPU */ #define UNIT_CHIP (1 << UNIT_V_CHIP) -#define UNIT_V_MSIZE (UNIT_V_UF+2) /* Memory Size */ +#define UNIT_V_MSIZE (UNIT_V_UF+2) /* memory size */ #define UNIT_MSIZE (1 << UNIT_V_MSIZE) -#define UNIT_V_BANKED (UNIT_V_UF+3) /* Banked memory is used */ +#define UNIT_V_BANKED (UNIT_V_UF+3) /* banked memory is used */ #define UNIT_BANKED (1 << UNIT_V_BANKED) #define UNIT_V_ROM (UNIT_V_UF+4) /* ROM exists */ #define UNIT_ROM (1 << UNIT_V_ROM) #define UNIT_V_ALTAIRROM (UNIT_V_UF+5) /* ALTAIR ROM exists */ #define UNIT_ALTAIRROM (1 << UNIT_V_ALTAIRROM) -#define UNIT_V_WARNROM (UNIT_V_UF+6) /* Warn if ROM is written to */ +#define UNIT_V_WARNROM (UNIT_V_UF+6) /* warn if ROM is written to */ #define UNIT_WARNROM (1 << UNIT_V_WARNROM) #define AddressFormat "[%04xh]" diff --git a/AltairZ80/altairZ80_dsk.c b/AltairZ80/altairZ80_dsk.c index a5b1f2ef..8856e9cd 100644 --- a/AltairZ80/altairZ80_dsk.c +++ b/AltairZ80/altairZ80_dsk.c @@ -1,29 +1,29 @@ -/* altairZ80_dsk.c: MITS Altair 88-DISK Simulator +/* altairz80_dsk.c: MITS Altair 88-DISK Simulator - Copyright (c) 2002, Peter Schorn + Copyright (c) 2002-2003, Peter Schorn - 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: + 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 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 - ROBERT M SUPNIK 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. + 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 + PETER SCHORN 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. - Except as contained in this notice, the name of Peter Schorn shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Peter Schorn. + Except as contained in this notice, the name of Peter Schorn shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Peter Schorn. - Based on work by Charles E Owen (c) 1997 + Based on work by Charles E Owen (c) 1997 The 88_DISK is a 8-inch floppy controller which can control up to 16 daisy-chained Pertec FD-400 hard-sectored floppy drives. @@ -108,7 +108,6 @@ */ -#include #include "altairz80_defs.h" #define UNIT_V_DSKWLK (UNIT_V_UF + 0) /* write locked */ @@ -127,18 +126,18 @@ #define TRACE_TRACK_STUCK 8 #define NUM_OF_DSK_MASK (NUM_OF_DSK - 1) -int32 dsk10(int32 port, int32 io, int32 data); -int32 dsk11(int32 port, int32 io, int32 data); -int32 dsk12(int32 port, int32 io, int32 data); -int32 dskseek(UNIT *xptr); -t_stat dsk_boot(int32 unitno, DEVICE *dptr); -t_stat dsk_reset(DEVICE *dptr); -t_stat dsk_svc(UNIT *uptr); -void writebuf(void); -t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc); -void resetDSKWarningFlags(void); -int32 hasVerbose(void); -char* selectInOut(int32 io); +int32 dsk10(const int32 port, const int32 io, const int32 data); +int32 dsk11(const int32 port, const int32 io, const int32 data); +int32 dsk12(const int32 port, const int32 io, const int32 data); +static int32 dskseek(const UNIT *xptr); +static t_stat dsk_boot(int32 unitno, DEVICE *dptr); +static t_stat dsk_reset(DEVICE *dptr); +static t_stat dsk_svc(UNIT *uptr); +static void writebuf(void); +static t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc); +static void resetDSKWarningFlags(void); +static int32 hasVerbose(void); +static char* selectInOut(const int32 io); extern int32 PCX; extern int32 saved_PC; @@ -149,27 +148,27 @@ extern char messageBuffer[]; extern int32 install_bootrom(void); extern UNIT cpu_unit; -/* Global data on status */ +/* global data on status */ -int32 cur_disk = NUM_OF_DSK; /* Currently selected drive (values are 0 .. NUM_OF_DSK) - cur_disk < NUM_OF_DSK implies that the corresponding disk is attached to a file */ -int32 cur_track [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; -int32 cur_sect [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; -int32 cur_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; -int32 cur_flags [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint8 tracks [NUM_OF_DSK] = { MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, - MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, MAX_TRACKS }; -int32 trace_flag = 0; -int32 in9_count = 0; -int32 in9_message = FALSE; -int32 dirty = FALSE; /* TRUE when buffer has unwritten data in it */ -int32 warnLevelDSK = 3; -int32 warnLock [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; -int32 warnAttached[NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; -int32 warnDSK10 = 0; -int32 warnDSK11 = 0; -int32 warnDSK12 = 0; -int8 dskbuf[DSK_SECTSIZE]; /* Data Buffer */ +static int32 current_disk = NUM_OF_DSK; /* currently selected drive (values are 0 .. NUM_OF_DSK) + current_disk < NUM_OF_DSK implies that the corresponding disk is attached to a file */ +static int32 current_track [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; +static int32 current_sector [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; +static int32 current_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; +static int32 current_flag [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; +static uint8 tracks [NUM_OF_DSK] = { MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, + MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, MAX_TRACKS }; +static int32 trace_flag = 0; +static int32 in9_count = 0; +static int32 in9_message = FALSE; +static int32 dirty = FALSE; /* TRUE when buffer has unwritten data in it */ +static int32 warnLevelDSK = 3; +static int32 warnLock [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; +static int32 warnAttached [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0}; +static int32 warnDSK10 = 0; +static int32 warnDSK11 = 0; +static int32 warnDSK12 = 0; +static int8 dskbuf[DSK_SECTSIZE]; /* data Buffer */ /* Altair MITS modified BOOT EPROM, fits in upper 256 byte of memory */ int32 bootrom[bootrom_size] = { @@ -209,7 +208,7 @@ int32 bootrom[bootrom_size] = { /* 88DSK Standard I/O Data Structures */ -UNIT dsk_unit[] = { +static UNIT dsk_unit[] = { { UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) }, { UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) }, { UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) }, @@ -219,15 +218,27 @@ UNIT dsk_unit[] = { { UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) }, { UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) } }; -REG dsk_reg[] = { - { DRDATA (DISK, cur_disk, 4) }, - { DRDATA (DSKWL, warnLevelDSK, 32) }, - { ORDATA (TRACE, trace_flag, 8) }, - { BRDATA (TRACKS, tracks, 10, 8, NUM_OF_DSK), REG_CIRC }, - { DRDATA (IN9, in9_count, 4), REG_RO }, +static REG dsk_reg[] = { + { DRDATA (DISK, current_disk, 4) }, + { BRDATA (CURTRACK, current_track, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO }, + { BRDATA (CURSECTOR, current_sector, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO }, + { BRDATA (CURBYTE, current_byte, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO }, + { BRDATA (CURFLAG, current_flag, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO }, + { BRDATA (TRACKS, tracks, 10, 8, NUM_OF_DSK), REG_CIRC }, + { ORDATA (TRACE, trace_flag, 8) }, + { DRDATA (IN9COUNT, in9_count, 4), REG_RO }, + { DRDATA (IN9MESSAGE, in9_message, 4), REG_RO }, + { DRDATA (DIRTY, dirty, 4), REG_RO }, + { DRDATA (DSKWL, warnLevelDSK, 32) }, + { BRDATA (WARNLOCK, warnLock, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO }, + { BRDATA (WARNATTACHED, warnAttached, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO }, + { DRDATA (WARNDSK10, warnDSK10, 4), REG_RO }, + { DRDATA (WARNDSK11, warnDSK11, 4), REG_RO }, + { DRDATA (WARNDSK12, warnDSK12, 4), REG_RO }, + { BRDATA (DISKBUFFER, dskbuf, 10, 8, DSK_SECTSIZE), REG_CIRC + REG_RO }, { NULL } }; -MTAB dsk_mod[] = { +static MTAB dsk_mod[] = { { UNIT_DSKWLK, 0, "write enabled", "WRITEENABLED", NULL }, { UNIT_DSKWLK, UNIT_DSKWLK, "write locked", "LOCKED", NULL }, /* quiet, no warning messages */ @@ -240,9 +251,9 @@ DEVICE dsk_dev = { "DSK", dsk_unit, dsk_reg, dsk_mod, 8, 10, 31, 1, 8, 8, NULL, NULL, &dsk_reset, - &dsk_boot, NULL, NULL, NULL, 0 }; + &dsk_boot, NULL, NULL, NULL, 0, NULL, NULL }; -void resetDSKWarningFlags(void) { +static void resetDSKWarningFlags(void) { int32 i; for (i = 0; i < NUM_OF_DSK; i++) { warnLock[i] = 0; @@ -253,13 +264,13 @@ void resetDSKWarningFlags(void) { warnDSK12 = 0; } -t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) { +static t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) { resetDSKWarningFlags(); return SCPE_OK; } /* returns TRUE iff there exists a disk with VERBOSE */ -int32 hasVerbose(void) { +static int32 hasVerbose(void) { int32 i; for (i = 0; i < NUM_OF_DSK; i++) { if (((dsk_dev.units + i) -> flags) & UNIT_DSK_VERBOSE) { @@ -269,33 +280,33 @@ int32 hasVerbose(void) { return FALSE; } -char* selectInOut(int32 io) { +static char* selectInOut(const int32 io) { return io == 0 ? "IN" : "OUT"; } -/* Service routines to handle simulator functions */ +/* service routines to handle simulator functions */ /* service routine - actually gets char & places in buffer */ -t_stat dsk_svc(UNIT *uptr) { +static t_stat dsk_svc(UNIT *uptr) { return SCPE_OK; } -/* Reset routine */ +/* reset routine */ -t_stat dsk_reset(DEVICE *dptr) { +static t_stat dsk_reset(DEVICE *dptr) { resetDSKWarningFlags(); - cur_disk = NUM_OF_DSK; - trace_flag = 0; - in9_count = 0; - in9_message = FALSE; + current_disk = NUM_OF_DSK; + trace_flag = 0; + in9_count = 0; + in9_message = FALSE; return SCPE_OK; } /* The boot routine modifies the boot ROM in such a way that subsequently the specified disk is used for boot purposes. */ -t_stat dsk_boot(int32 unitno, DEVICE *dptr) { +static t_stat dsk_boot(int32 unitno, DEVICE *dptr) { if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) { if (install_bootrom()) { printf("ALTAIR boot ROM installed.\n"); @@ -333,50 +344,50 @@ t_stat dsk_boot(int32 unitno, DEVICE *dptr) { simulation requirement that they are reversed in hardware. */ -int32 dsk10(int32 port, int32 io, int32 data) { - int32 cur_flag; +int32 dsk10(const int32 port, const int32 io, const int32 data) { + int32 current_disk_flags; in9_count = 0; if (io == 0) { /* IN: return flags */ - if (cur_disk >= NUM_OF_DSK) { + if (current_disk >= NUM_OF_DSK) { if (hasVerbose() && (warnDSK10 < warnLevelDSK)) { warnDSK10++; /*01*/ message1("Attempt of IN 0x08 on unattached disk - ignored.\n"); } return 0xff; /* no drive selected - can do nothing */ } - return (~cur_flags[cur_disk]) & 0xff; /* Return the COMPLEMENT! */ + return (~current_flag[current_disk]) & 0xff; /* return the COMPLEMENT! */ } /* OUT: Controller set/reset/enable/disable */ - if (dirty) {/* implies that cur_disk < NUM_OF_DSK */ + if (dirty) { /* implies that current_disk < NUM_OF_DSK */ writebuf(); } if (trace_flag & TRACE_IN_OUT) { message2("OUT 0x08: %x\n", data); } - cur_disk = data & NUM_OF_DSK_MASK; /* 0 <= cur_disk < NUM_OF_DSK */ - cur_flag = (dsk_dev.units + cur_disk) -> flags; - if ((cur_flag & UNIT_ATT) == 0) { /* nothing attached? */ - if ( (cur_flag & UNIT_DSK_VERBOSE) && (warnAttached[cur_disk] < warnLevelDSK) ) { - warnAttached[cur_disk]++; -/*02*/message2("Attempt to select unattached DSK%d - ignored.\n", cur_disk); + current_disk = data & NUM_OF_DSK_MASK; /* 0 <= current_disk < NUM_OF_DSK */ + current_disk_flags = (dsk_dev.units + current_disk) -> flags; + if ((current_disk_flags & UNIT_ATT) == 0) { /* nothing attached? */ + if ( (current_disk_flags & UNIT_DSK_VERBOSE) && (warnAttached[current_disk] < warnLevelDSK) ) { + warnAttached[current_disk]++; +/*02*/message2("Attempt to select unattached DSK%d - ignored.\n", current_disk); } - cur_disk = NUM_OF_DSK; + current_disk = NUM_OF_DSK; } else { - cur_sect[cur_disk] = 0xff; /* reset internal counters */ - cur_byte[cur_disk] = 0xff; - cur_flags[cur_disk] = data & 0x80 ? 0 /* Disable drive */ : - (cur_track[cur_disk] == 0 ? 0x5a /* Enable: head move true, track 0 if there */ : - 0x1a); /* Enable: head move true */ + current_sector[current_disk] = 0xff; /* reset internal counters */ + current_byte[current_disk] = 0xff; + current_flag[current_disk] = data & 0x80 ? 0 /* disable drive */ : + (current_track[current_disk] == 0 ? 0x5a /* enable: head move true, track 0 if there */ : + 0x1a);/* enable: head move true */ } return 0; /* ignored since OUT */ } /* Disk Drive Status/Functions */ -int32 dsk11(int32 port, int32 io, int32 data) { - if (cur_disk >= NUM_OF_DSK) { +int32 dsk11(const int32 port, const int32 io, const int32 data) { + if (current_disk >= NUM_OF_DSK) { if (hasVerbose() && (warnDSK11 < warnLevelDSK)) { warnDSK11++; /*03*/message2("Attempt of %s 0x09 on unattached disk - ignored.\n", selectInOut(io)); @@ -384,110 +395,110 @@ int32 dsk11(int32 port, int32 io, int32 data) { return 0; /* no drive selected - can do nothing */ } - /* now cur_disk < NUM_OF_DSK */ - if (io == 0) { /* Read sector position */ + /* now current_disk < NUM_OF_DSK */ + if (io == 0) { /* read sector position */ in9_count++; if ((trace_flag & TRACE_SECTOR_STUCK) && (in9_count > 2 * DSK_SECT) && (!in9_message)) { in9_message = TRUE; - message2("Looping on sector find %d.\n", cur_disk); + message2("Looping on sector find %d.\n", current_disk); } if (trace_flag & TRACE_IN_OUT) { message1("IN 0x09\n"); } - if (dirty) {/* implies that cur_disk < NUM_OF_DSK */ + if (dirty) {/* implies that current_disk < NUM_OF_DSK */ writebuf(); } - if (cur_flags[cur_disk] & 0x04) { /* head loaded? */ - cur_sect[cur_disk]++; - if (cur_sect[cur_disk] >= DSK_SECT) { - cur_sect[cur_disk] = 0; + if (current_flag[current_disk] & 0x04) { /* head loaded? */ + current_sector[current_disk]++; + if (current_sector[current_disk] >= DSK_SECT) { + current_sector[current_disk] = 0; } - cur_byte[cur_disk] = 0xff; - return (((cur_sect[cur_disk] << 1) & 0x3e) /* return 'sector true' bit = 0 (true) */ + current_byte[current_disk] = 0xff; + return (((current_sector[current_disk] << 1) & 0x3e) /* return 'sector true' bit = 0 (true) */ | 0xc0); /* set on 'unused' bits */ } else { - return 0; /* head not loaded - return 0 */ + return 0; /* head not loaded - return 0 */ } } in9_count = 0; - /* Drive functions */ + /* drive functions */ if (trace_flag & TRACE_IN_OUT) { message2("OUT 0x09: %x\n", data); } - if (data & 0x01) { /* Step head in */ + if (data & 0x01) { /* step head in */ if (trace_flag & TRACE_TRACK_STUCK) { - if (cur_track[cur_disk] == (tracks[cur_disk] - 1)) { - message2("Unnecessary step in for disk %d\n", cur_disk); + if (current_track[current_disk] == (tracks[current_disk] - 1)) { + message2("Unnecessary step in for disk %d\n", current_disk); } } - cur_track[cur_disk]++; - if (cur_track[cur_disk] > (tracks[cur_disk] - 1)) { - cur_track[cur_disk] = (tracks[cur_disk] - 1); + current_track[current_disk]++; + if (current_track[current_disk] > (tracks[current_disk] - 1)) { + current_track[current_disk] = (tracks[current_disk] - 1); } - if (dirty) { /* implies that cur_disk < NUM_OF_DSK */ + if (dirty) { /* implies that current_disk < NUM_OF_DSK */ writebuf(); } - cur_sect[cur_disk] = 0xff; - cur_byte[cur_disk] = 0xff; + current_sector[current_disk] = 0xff; + current_byte[current_disk] = 0xff; } - if (data & 0x02) { /* Step head out */ + if (data & 0x02) { /* step head out */ if (trace_flag & TRACE_TRACK_STUCK) { - if (cur_track[cur_disk] == 0) { - message2("Unnecessary step out for disk %d\n", cur_disk); + if (current_track[current_disk] == 0) { + message2("Unnecessary step out for disk %d\n", current_disk); } } - cur_track[cur_disk]--; - if (cur_track[cur_disk] < 0) { - cur_track[cur_disk] = 0; - cur_flags[cur_disk] |= 0x40; /* track 0 if there */ + current_track[current_disk]--; + if (current_track[current_disk] < 0) { + current_track[current_disk] = 0; + current_flag[current_disk] |= 0x40; /* track 0 if there */ } - if (dirty) { /* implies that cur_disk < NUM_OF_DSK */ + if (dirty) { /* implies that current_disk < NUM_OF_DSK */ writebuf(); } - cur_sect[cur_disk] = 0xff; - cur_byte[cur_disk] = 0xff; + current_sector[current_disk] = 0xff; + current_byte[current_disk] = 0xff; } - if (dirty) { /* implies that cur_disk < NUM_OF_DSK */ + if (dirty) { /* implies that current_disk < NUM_OF_DSK */ writebuf(); } - if (data & 0x04) { /* Head load */ - cur_flags[cur_disk] |= 0x04; /* turn on head loaded bit */ - cur_flags[cur_disk] |= 0x80; /* turn on 'read data available' */ + if (data & 0x04) { /* head load */ + current_flag[current_disk] |= 0x04; /* turn on head loaded bit */ + current_flag[current_disk] |= 0x80; /* turn on 'read data available' */ } - if (data & 0x08) { /* Head Unload */ - cur_flags[cur_disk] &= 0xfb; /* turn off 'head loaded' bit */ - cur_flags[cur_disk] &= 0x7f; /* turn off 'read data available' */ - cur_sect[cur_disk] = 0xff; - cur_byte[cur_disk] = 0xff; + if (data & 0x08) { /* head unload */ + current_flag[current_disk] &= 0xfb; /* turn off 'head loaded' bit */ + current_flag[current_disk] &= 0x7f; /* turn off 'read data available' */ + current_sector[current_disk] = 0xff; + current_byte[current_disk] = 0xff; } - /* Interrupts & head current are ignored */ + /* interrupts & head current are ignored */ - if (data & 0x80) { /* write sequence start */ - cur_byte[cur_disk] = 0; - cur_flags[cur_disk] |= 0x01; /* enter new write data on */ + if (data & 0x80) { /* write sequence start */ + current_byte[current_disk] = 0; + current_flag[current_disk] |= 0x01; /* enter new write data on */ } - return 0; /* ignored since OUT */ + return 0; /* ignored since OUT */ } /* Disk Data In/Out */ -INLINE int32 dskseek(UNIT *xptr) { - return fseek(xptr -> fileref, DSK_TRACSIZE * cur_track[cur_disk] + - DSK_SECTSIZE * cur_sect[cur_disk], SEEK_SET); +static INLINE int32 dskseek(const UNIT *xptr) { + return fseek(xptr -> fileref, DSK_TRACSIZE * current_track[current_disk] + + DSK_SECTSIZE * current_sector[current_disk], SEEK_SET); } -int32 dsk12(int32 port, int32 io, int32 data) { - static int32 i; +int32 dsk12(const int32 port, const int32 io, const int32 data) { + int32 i; UNIT *uptr; - if (cur_disk >= NUM_OF_DSK) { + if (current_disk >= NUM_OF_DSK) { if (hasVerbose() && (warnDSK12 < warnLevelDSK)) { warnDSK12++; /*04*/message2("Attempt of %s 0x0a on unattached disk - ignored.\n", selectInOut(io)); @@ -495,64 +506,64 @@ int32 dsk12(int32 port, int32 io, int32 data) { return 0; } - /* now cur_disk < NUM_OF_DSK */ + /* now current_disk < NUM_OF_DSK */ in9_count = 0; - uptr = dsk_dev.units + cur_disk; + uptr = dsk_dev.units + current_disk; if (io == 0) { - if (cur_byte[cur_disk] >= DSK_SECTSIZE) { + if (current_byte[current_disk] >= DSK_SECTSIZE) { /* physically read the sector */ if (trace_flag & TRACE_READ_WRITE) { - message4("IN 0x0a (READ) D%d T%d S%d\n", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]); + message4("IN 0x0a (READ) D%d T%d S%d\n", current_disk, current_track[current_disk], current_sector[current_disk]); } for (i = 0; i < DSK_SECTSIZE; i++) { dskbuf[i] = 0; } dskseek(uptr); fread(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref); - cur_byte[cur_disk] = 0; + current_byte[current_disk] = 0; } - return dskbuf[cur_byte[cur_disk]++] & 0xff; + return dskbuf[current_byte[current_disk]++] & 0xff; } else { - if (cur_byte[cur_disk] >= DSK_SECTSIZE) { - writebuf(); /* from above we have that cur_disk < NUM_OF_DSK */ + if (current_byte[current_disk] >= DSK_SECTSIZE) { + writebuf(); /* from above we have that current_disk < NUM_OF_DSK */ } else { - dirty = TRUE; /* this guarantees for the next call to writebuf that cur_disk < NUM_OF_DSK */ - dskbuf[cur_byte[cur_disk]++] = data & 0xff; + dirty = TRUE; /* this guarantees for the next call to writebuf that current_disk < NUM_OF_DSK */ + dskbuf[current_byte[current_disk]++] = data & 0xff; } return 0; /* ignored since OUT */ } } -/* Precondition: cur_disk < NUM_OF_DSK */ -void writebuf(void) { +/* precondition: current_disk < NUM_OF_DSK */ +static void writebuf(void) { int32 i, rtn; UNIT *uptr; - i = cur_byte[cur_disk]; /* null-fill rest of sector if any */ + i = current_byte[current_disk]; /* null-fill rest of sector if any */ while (i < DSK_SECTSIZE) { dskbuf[i++] = 0; } - uptr = dsk_dev.units + cur_disk; + uptr = dsk_dev.units + current_disk; if (((uptr -> flags) & UNIT_DSKWLK) == 0) { /* write enabled */ if (trace_flag & TRACE_READ_WRITE) { - message4("OUT 0x0a (WRITE) D%d T%d S%d\n", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]); + message4("OUT 0x0a (WRITE) D%d T%d S%d\n", current_disk, current_track[current_disk], current_sector[current_disk]); } if (dskseek(uptr)) { - message4("fseek failed D%d T%d S%d\n", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]); + message4("fseek failed D%d T%d S%d\n", current_disk, current_track[current_disk], current_sector[current_disk]); } rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref); if (rtn != 1) { - message4("fwrite failed T%d S%d Return=%d\n", cur_track[cur_disk], cur_sect[cur_disk], rtn); + message4("fwrite failed T%d S%d Return=%d\n", current_track[current_disk], current_sector[current_disk], rtn); } } - else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[cur_disk] < warnLevelDSK) ) { + else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[current_disk] < warnLevelDSK) ) { /* write locked - print warning message if required */ - warnLock[cur_disk]++; + warnLock[current_disk]++; /*05*/ - message2("Attempt to write to locked DSK%d - ignored.\n", cur_disk); + message2("Attempt to write to locked DSK%d - ignored.\n", current_disk); } - cur_flags[cur_disk] &= 0xfe; /* ENWD off */ - cur_byte[cur_disk] = 0xff; - dirty = FALSE; + current_flag[current_disk] &= 0xfe; /* ENWD off */ + current_byte[current_disk] = 0xff; + dirty = FALSE; } diff --git a/AltairZ80/altairZ80_sio.c b/AltairZ80/altairZ80_sio.c index 77d09e99..489758e4 100644 --- a/AltairZ80/altairZ80_sio.c +++ b/AltairZ80/altairZ80_sio.c @@ -1,29 +1,29 @@ -/* altairZ80_sio: MITS Altair serial I/O card +/* altairz80_sio: MITS Altair serial I/O card - Copyright (c) 2002, Peter Schorn + Copyright (c) 2002-2003, Peter Schorn - 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: + 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 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 - ROBERT M SUPNIK 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. + 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 + PETER SCHORN 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. - Except as contained in this notice, the name of Peter Schorn shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Peter Schorn. + Except as contained in this notice, the name of Peter Schorn shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Peter Schorn. - Based on work by Charles E Owen (c) 1997 + Based on work by Charles E Owen (c) 1997 These functions support a simulated MITS 2SIO interface card. The card had two physical I/O ports which could be connected @@ -49,7 +49,6 @@ to the data port writes the character to the device. */ -#include #include #include "altairz80_defs.h" @@ -77,35 +76,36 @@ #define DELETE_CHAR 0x7f /* delete character */ #define CONTROLZ_CHAR 0x1a /* control Z character */ -void resetSIOWarningFlags(void); -t_stat sio_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc); -t_stat sio_svc(UNIT *uptr); -t_stat sio_reset(DEVICE *dptr); -t_stat sio_attach(UNIT *uptr, char *cptr); -t_stat sio_detach(UNIT *uptr); -t_stat ptr_reset(DEVICE *dptr); -t_stat ptp_reset(DEVICE *dptr); -int32 nulldev (int32 port, int32 io, int32 data); -int32 sr_dev (int32 port, int32 io, int32 data); -int32 simh_dev(int32 port, int32 io, int32 data); -int32 sio0d (int32 port, int32 io, int32 data); -int32 sio0s (int32 port, int32 io, int32 data); -int32 sio1d (int32 port, int32 io, int32 data); -int32 sio1s (int32 port, int32 io, int32 data); -void reset_sio_terminals(int32 useDefault); -t_stat simh_dev_reset(DEVICE *dptr); -t_stat simh_svc(UNIT *uptr); -t_stat simh_dev_set_timeron(UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat simh_dev_set_timeroff(UNIT *uptr, int32 val, char *cptr, void *desc); -int32 simh_in(void); -int32 simh_out(int32 data); -void attachCPM(UNIT *uptr); -void setClockZSDOS(void); -void setClockCPM3(void); -time_t mkCPM3Origin(void); -int32 toBCD(int32 x); -int32 fromBCD(int32 x); +static void resetSIOWarningFlags(void); +static t_stat sio_set_verbose (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat simh_dev_set_timeron (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat simh_dev_set_timeroff (UNIT *uptr, int32 value, char *cptr, void *desc); +static t_stat sio_svc(UNIT *uptr); +static t_stat sio_reset(DEVICE *dptr); +static t_stat sio_attach(UNIT *uptr, char *cptr); +static t_stat sio_detach(UNIT *uptr); +static t_stat ptr_reset(DEVICE *dptr); +static t_stat ptp_reset(DEVICE *dptr); +int32 nulldev (const int32 port, const int32 io, const int32 data); +int32 sr_dev (const int32 port, const int32 io, const int32 data); +int32 simh_dev(const int32 port, const int32 io, const int32 data); +int32 sio0d (const int32 port, const int32 io, const int32 data); +int32 sio0s (const int32 port, const int32 io, const int32 data); +int32 sio1d (const int32 port, const int32 io, const int32 data); +int32 sio1s (const int32 port, const int32 io, const int32 data); +static void reset_sio_terminals(const int32 useDefault); +static t_stat simh_dev_reset(DEVICE *dptr); +static t_stat simh_svc(UNIT *uptr); +static int32 simh_in(const int32 port); +static int32 simh_out(const int32 port, const int32 data); +static void attachCPM(UNIT *uptr); +static void setClockZSDOS(void); +static void setClockCPM3(void); +static time_t mkCPM3Origin(void); +static int32 toBCD(const int32 x); +static int32 fromBCD(const int32 x); void printMessage(void); +static void warnNoRealTimeClock(void); extern t_stat sim_activate(UNIT *uptr, int32 interval); extern t_stat sim_cancel(UNIT *uptr); @@ -124,54 +124,50 @@ extern int32 common; extern uint8 GetBYTEWrapper(register uint32 Addr); extern UNIT cpu_unit; -/* the following variables define state for the SIMH pseudo device */ -/* ZSDOS clock definitions */ -int32 ClockZSDOSDelta = 0; /* delta between real clock and Altair clock */ -int32 setClockZSDOSPos = 0; /* determines state for receiving address of parameter block */ -int32 setClockZSDOSAdr = 0; /* address in M of 6 byte parameter block for setting time */ -int32 getClockZSDOSPos = 0; /* determines state for sending clock information */ +/* SIMH pseudo device status registers */ +/* ZSDOS clock definitions */ +static int32 ClockZSDOSDelta = 0; /* delta between real clock and Altair clock */ +static int32 setClockZSDOSPos = 0; /* determines state for receiving address of parameter block */ +static int32 setClockZSDOSAdr = 0; /* address in M of 6 byte parameter block for setting time */ +static int32 getClockZSDOSPos = 0; /* determines state for sending clock information */ -/* CPM3 clock definitions */ -int32 ClockCPM3Delta = 0; /* delta between real clock and Altair clock */ -int32 setClockCPM3Pos = 0; /* determines state for receiving address of parameter block */ -int32 setClockCPM3Adr = 0; /* address in M of 5 byte parameter block for setting time */ -int32 getClockCPM3Pos = 0; /* determines state for sending clock information */ -int32 daysCPM3SinceOrg = 0; /* days since 1 Jan 1978 */ +/* CPM3 clock definitions */ +static int32 ClockCPM3Delta = 0; /* delta between real clock and Altair clock */ +static int32 setClockCPM3Pos = 0; /* determines state for receiving address of parameter block */ +static int32 setClockCPM3Adr = 0; /* address in M of 5 byte parameter block for setting time */ +static int32 getClockCPM3Pos = 0; /* determines state for sending clock information */ +static int32 daysCPM3SinceOrg = 0; /* days since 1 Jan 1978 */ -int32 timerDelta = 100; /* interrupt every 100 ms */ -int32 tmpTimerDelta; -uint32 timeOfNextInterrupt; -int32 timerInterrupt = FALSE; /* timer interrupt pending */ -int32 timerInterruptHandler = 0x0fc00;/* default address of interrupt handling routine */ -int32 tmpTimerInterruptHandler; -int32 setTimerDeltaPos = 0; /* determines state for receiving timerDelta */ -int32 setTimerInterruptAdrPos = 0; /* determines state for receiving timerInterruptHandler */ -int32 markTimeSP = 0; /* stack pointer for timer stack */ -int32 versionPos = 0; /* determines state for sending device identifier */ -int32 lastCPMStatus = 0; /* result of last attachCPM command */ -int32 lastCommand = 0; /* most recent command processed on port 0xfeh */ -int32 getCommonPos = 0; /* determines state for sending the 'common' register */ -int32 warnLevelSIO = 3; /* display at most 'warnLevelSIO' times the same warning */ -int32 warnUnattachedPTP = 0; /* display a warning message if < warnLevel and SIO set to - VERBOSE and output to PTP without an attached file */ -int32 warnUnattachedPTR = 0; /* display a warning message if < warnLevel and SIO set to - VERBOSE and attempt to read from PTR without an attached file */ -int32 warnPTREOF = 0; /* display a warning message if < warnLevel and SIO set to - VERBOSE and attempt to read from PTR past EOF */ -int32 warnUnassignedPort = 0; /* display a warning message if < warnLevel and SIO set to - VERBOSE andattempt to perform IN or OUT on an unassigned PORT */ -char messageBuffer[256]; +/* interrupt related */ +static uint32 timeOfNextInterrupt; /* time when next interrupt is scheduled */ + int32 timerInterrupt = FALSE; /* timer interrupt pending */ + int32 timerInterruptHandler = 0x0fc00;/* default address of interrupt handling routine */ +static int32 setTimerInterruptAdrPos= 0; /* determines state for receiving timerInterruptHandler */ +static int32 timerDelta = 100; /* interrupt every 100 ms */ +static int32 setTimerDeltaPos = 0; /* determines state for receiving timerDelta */ -void printMessage(void) { - printf(messageBuffer); - if (sim_log) { - fprintf(sim_log, messageBuffer); - } -} +/* stop watch and timer related */ +static uint32 stopWatchDelta = 0; /* stores elapsed time of stop watch */ +static int32 getStopWatchDeltaPos = 0; /* determines the state for receiving stopWatchDelta */ +static uint32 stopWatchNow = 0; /* stores starting time of stop watch */ +static int32 markTimeSP = 0; /* stack pointer for timer stack */ +/* miscellaneous */ +static int32 versionPos = 0; /* determines state for sending device identifier */ +static int32 lastCPMStatus = 0; /* result of last attachCPM command */ +static int32 lastCommand = 0; /* most recent command processed on port 0xfeh */ +static int32 getCommonPos = 0; /* determines state for sending the 'common' register */ - -/* 2SIO Standard I/O Data Structures */ +/* SIO status registers */ +static int32 warnLevelSIO = 3; /* display at most 'warnLevelSIO' times the same warning */ +static int32 warnUnattachedPTP = 0; /* display a warning message if < warnLevel and SIO set to + VERBOSE and output to PTP without an attached file */ +static int32 warnUnattachedPTR = 0; /* display a warning message if < warnLevel and SIO set to + VERBOSE and attempt to read from PTR without an attached file */ +static int32 warnPTREOF = 0; /* display a warning message if < warnLevel and SIO set to + VERBOSE and attempt to read from PTR past EOF */ +static int32 warnUnassignedPort = 0; /* display a warning message if < warnLevel and SIO set to + VERBOSE andattempt to perform IN or OUT on an unassigned PORT */ struct sio_terminal { int32 data; /* data for this terminal */ int32 status; /* status information for this terminal */ @@ -182,16 +178,17 @@ struct sio_terminal { typedef struct sio_terminal SIO_TERMINAL; -SIO_TERMINAL sio_terminals[Terminals] = { {0, 0, 0x10, 0x11, 0x02}, - {0, 0, 0x14, 0x15, 0x00}, - {0, 0, 0x16, 0x17, 0x00}, - {0, 0, 0x18, 0x19, 0x00} }; -TMLN TerminalLines[Terminals] = { {0} }; /* four terminals */ -TMXR altairTMXR = {Terminals, 0, 0 }; /* mux descriptor */ +static SIO_TERMINAL sio_terminals[Terminals] = + { {0, 0, 0x10, 0x11, 0x02}, + {0, 0, 0x14, 0x15, 0x00}, + {0, 0, 0x16, 0x17, 0x00}, + {0, 0, 0x18, 0x19, 0x00} }; +static TMLN TerminalLines[Terminals] = { {0} }; /* four terminals */ +static TMXR altairTMXR = {Terminals, 0, 0 }; /* mux descriptor */ -UNIT sio_unit = { UDATA (&sio_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT }; +static UNIT sio_unit = { UDATA (&sio_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT }; -REG sio_reg[] = { +static REG sio_reg[] = { { HRDATA (DATA0, sio_terminals[0].data, 8) }, { HRDATA (STAT0, sio_terminals[0].status, 8) }, { HRDATA (DATA1, sio_terminals[1].data, 8) }, @@ -207,7 +204,7 @@ REG sio_reg[] = { { DRDATA (WUPORT, warnUnassignedPort, 32) }, { NULL } }; -MTAB sio_mod[] = { +static MTAB sio_mod[] = { { UNIT_ANSI, 0, "TTY", "TTY", NULL }, /* keep bit 8 as is for output */ { UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL }, /* set bit 8 to 0 before output */ { UNIT_UPPER, 0, "ALL", "ALL", NULL }, /* do not change case of input characters */ @@ -223,68 +220,80 @@ DEVICE sio_dev = { "SIO", &sio_unit, sio_reg, sio_mod, 1, 10, 31, 1, 8, 8, NULL, NULL, &sio_reset, - NULL, &sio_attach, &sio_detach, NULL, 0 }; + NULL, &sio_attach, &sio_detach, NULL, 0, NULL, NULL }; -UNIT ptr_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE + UNIT_ROABLE, 0), +static UNIT ptr_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE + UNIT_ROABLE, 0), KBD_POLL_WAIT }; -REG ptr_reg[] = { +static REG ptr_reg[] = { { HRDATA (DATA, ptr_unit.buf, 8) }, { HRDATA (STAT, ptr_unit.u3, 8) }, - { DRDATA (POS, ptr_unit.pos, 31) }, + { DRDATA (POS, ptr_unit.pos, 32) }, { NULL } }; DEVICE ptr_dev = { "PTR", &ptr_unit, ptr_reg, NULL, 1, 10, 31, 1, 8, 8, NULL, NULL, &ptr_reset, - NULL, NULL, NULL, NULL, 0 }; + NULL, NULL, NULL, NULL, 0, NULL, NULL }; -UNIT ptp_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE, 0), +static UNIT ptp_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE, 0), KBD_POLL_WAIT }; -REG ptp_reg[] = { +static REG ptp_reg[] = { { HRDATA (DATA, ptp_unit.buf, 8) }, { HRDATA (STAT, ptp_unit.u3, 8) }, - { DRDATA (POS, ptp_unit.pos, 31) }, + { DRDATA (POS, ptp_unit.pos, 32) }, { NULL } }; DEVICE ptp_dev = { "PTP", &ptp_unit, ptp_reg, NULL, 1, 10, 31, 1, 8, 8, NULL, NULL, &ptp_reset, - NULL, NULL, NULL, NULL, 0 }; + NULL, NULL, NULL, NULL, 0, NULL, NULL }; /* Synthetic device SIMH for communication between Altair and SIMH environment using port 0xfe */ -UNIT simh_unit = { UDATA (&simh_svc, 0, 0), KBD_POLL_WAIT }; +static UNIT simh_unit = { UDATA (&simh_svc, 0, 0), KBD_POLL_WAIT }; -REG simh_reg[] = { - { DRDATA (CZD, ClockZSDOSDelta, 31) }, +static REG simh_reg[] = { + { DRDATA (CZD, ClockZSDOSDelta, 32) }, { DRDATA (SCZP, setClockZSDOSPos, 8), REG_RO }, + { HRDATA (SCZA, setClockZSDOSAdr, 16), REG_RO }, { DRDATA (GCZP, getClockZSDOSPos, 8), REG_RO }, - { HRDATA (SCZA, setClockZSDOSAdr, 17), REG_RO }, - { DRDATA (CC3D, ClockCPM3Delta, 31) }, - { DRDATA (TIMD, timerDelta, 31) }, + + { DRDATA (CC3D, ClockCPM3Delta, 32) }, + { DRDATA (SC3DP, setClockCPM3Pos, 8), REG_RO }, + { HRDATA (SC3DA, setClockCPM3Adr, 16), REG_RO }, + { DRDATA (GC3DP, getClockCPM3Pos, 8), REG_RO }, + { DRDATA (D3DO, daysCPM3SinceOrg, 32), REG_RO }, + + { DRDATA (TOFNI, timeOfNextInterrupt, 32), REG_RO }, { DRDATA (TIMI, timerInterrupt, 3) }, - { HRDATA (TIMH, timerInterruptHandler, 17) }, - { DRDATA (SCC3P, setClockCPM3Pos, 8), REG_RO }, - { DRDATA (GCC3P, getClockCPM3Pos, 8), REG_RO }, - { HRDATA (SCC3A, setClockCPM3Adr, 17), REG_RO }, + { HRDATA (TIMH, timerInterruptHandler, 16) }, + { DRDATA (STIAP, setTimerInterruptAdrPos,8), REG_RO }, + { DRDATA (TIMD, timerDelta, 32) }, + { DRDATA (STDP, setTimerDeltaPos, 8), REG_RO }, + + { DRDATA (STPDT, stopWatchDelta, 32), REG_RO }, + { DRDATA (STPOS, getStopWatchDeltaPos, 8), REG_RO }, + { DRDATA (STPNW, stopWatchNow, 32), REG_RO }, { DRDATA (MTSP, markTimeSP, 8), REG_RO }, - { DRDATA (VP, versionPos, 8), REG_RO }, - { DRDATA (CP, getCommonPos, 8), REG_RO }, - { DRDATA (LC, lastCommand, 8), REG_RO }, + + { DRDATA (VPOS, versionPos, 8), REG_RO }, + { DRDATA (LCPMS, lastCPMStatus, 8), REG_RO }, + { DRDATA (LCMD, lastCommand, 8), REG_RO }, + { DRDATA (CPOS, getCommonPos, 8), REG_RO }, { NULL } }; -MTAB simh_mod[] = { +static MTAB simh_mod[] = { /* quiet, no warning messages */ { UNIT_SIMH_VERBOSE, 0, "QUIET", "QUIET", NULL }, /* verbose, display warning messages */ { UNIT_SIMH_VERBOSE, UNIT_SIMH_VERBOSE, "VERBOSE", "VERBOSE", NULL }, - /* quiet, no warning messages */ + /* timer generated interrupts are off */ { UNIT_SIMH_TIMERON, 0, "TIMEROFF", "TIMEROFF", &simh_dev_set_timeroff }, - /* verbose, display warning messages */ + /* timer generated interrupts are on */ { UNIT_SIMH_TIMERON, UNIT_SIMH_TIMERON, "TIMERON", "TIMERON", &simh_dev_set_timeron }, { 0 } }; @@ -292,22 +301,30 @@ DEVICE simh_device = { "SIMH", &simh_unit, simh_reg, simh_mod, 1, 10, 31, 1, 16, 4, NULL, NULL, &simh_dev_reset, - NULL, NULL, NULL, NULL, 0 }; + NULL, NULL, NULL, NULL, 0, NULL, NULL }; +char messageBuffer[256]; -void resetSIOWarningFlags(void) { +void printMessage(void) { + printf(messageBuffer); + if (sim_log) { + fprintf(sim_log, messageBuffer); + } +} + +static void resetSIOWarningFlags(void) { warnUnattachedPTP = 0; warnUnattachedPTR = 0; warnPTREOF = 0; warnUnassignedPort = 0; } -t_stat sio_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) { +static t_stat sio_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) { resetSIOWarningFlags(); return SCPE_OK; } -t_stat sio_attach(UNIT *uptr, char *cptr) { +static t_stat sio_attach(UNIT *uptr, char *cptr) { int32 i; for (i = 0; i < Terminals; i++) { altairTMXR.ldsc[i] = &TerminalLines[i]; @@ -316,31 +333,31 @@ t_stat sio_attach(UNIT *uptr, char *cptr) { return tmxr_attach(&altairTMXR, uptr, cptr); /* attach mux */ } -void reset_sio_terminals(int32 useDefault) { +static void reset_sio_terminals(const int32 useDefault) { int32 i; for (i = 0; i < Terminals; i++) { - sio_terminals[i].status = useDefault ? sio_terminals[i].defaultStatus : 0; /* Status */ - sio_terminals[i].data = 0x00; /* Data */ + sio_terminals[i].status = useDefault ? sio_terminals[i].defaultStatus : 0; /* status */ + sio_terminals[i].data = 0x00; /* data */ } } -/* Detach */ -t_stat sio_detach(UNIT *uptr) { +/* detach */ +static t_stat sio_detach(UNIT *uptr) { reset_sio_terminals(TRUE); return tmxr_detach(&altairTMXR, uptr); } -/* Service routines to handle simulator functions */ +/* service routines to handle simulator functions */ /* service routine - actually gets char & places in buffer */ -t_stat sio_svc(UNIT *uptr) { +static t_stat sio_svc(UNIT *uptr) { int32 temp; sim_activate(&sio_unit, sio_unit.wait); /* continue poll */ if (sio_unit.flags & UNIT_ATT) { - if (sim_poll_kbd() == SCPE_STOP) { /* listen for ^E */ + if (sim_poll_kbd() == SCPE_STOP) { /* listen for ^E */ return SCPE_STOP; } temp = tmxr_poll_conn(&altairTMXR); /* poll connection */ @@ -354,16 +371,16 @@ t_stat sio_svc(UNIT *uptr) { if ((temp = sim_poll_kbd()) < SCPE_KFLAG) { return temp; /* no char or error? */ } - sio_terminals[0].data = temp & 0xff; /* Save char */ - sio_terminals[0].status |= 0x01; /* Set status */ + sio_terminals[0].data = temp & 0xff; /* save character */ + sio_terminals[0].status |= 0x01; /* set status */ } return SCPE_OK; } -/* Reset routines */ +/* reset routines */ -t_stat sio_reset(DEVICE *dptr) { +static t_stat sio_reset(DEVICE *dptr) { int32 i; resetSIOWarningFlags(); if (sio_unit.flags & UNIT_ATT) { @@ -381,7 +398,7 @@ t_stat sio_reset(DEVICE *dptr) { return SCPE_OK; } -t_stat ptr_reset(DEVICE *dptr) { +static t_stat ptr_reset(DEVICE *dptr) { resetSIOWarningFlags(); ptr_unit.buf = 0; ptr_unit.u3 = 0; @@ -393,10 +410,10 @@ t_stat ptr_reset(DEVICE *dptr) { return SCPE_OK; } -t_stat ptp_reset(DEVICE *dptr) { +static t_stat ptp_reset(DEVICE *dptr) { resetSIOWarningFlags(); - ptp_unit.buf = 0; - ptp_unit.u3 = 0x02; + ptp_unit.buf = 0; + ptp_unit.u3 = 0x02; sim_cancel(&ptp_unit); /* deactivate unit */ return SCPE_OK; } @@ -415,7 +432,7 @@ t_stat ptp_reset(DEVICE *dptr) { 2) SIO not attached to a port (i.e. "regular" console I/O) */ -int32 sio0s(int32 port, int32 io, int32 data) { +int32 sio0s(const int32 port, const int32 io, const int32 data) { int32 ti; for (ti = 0; ti < Terminals; ti++) { if (sio_terminals[ti].statusPort == port) { @@ -449,7 +466,7 @@ int32 sio0s(int32 port, int32 io, int32 data) { } } -int32 sio0d(int32 port, int32 io, int32 data) { +int32 sio0d(const int32 port, const int32 io, const int32 data) { int32 ti; for (ti = 0; ti < Terminals; ti++) { if (sio_terminals[ti].dataPort == port) { @@ -474,22 +491,20 @@ int32 sio0d(int32 port, int32 io, int32 data) { return (sio_unit.flags & UNIT_UPPER) ? toupper(sio_terminals[ti].data) : sio_terminals[ti].data; } else { /* OUT */ - if (sio_unit.flags & UNIT_ANSI) { - data &= 0x7f; - } + int32 d = sio_unit.flags & UNIT_ANSI ? data & 0x7f : data; if (sio_unit.flags & UNIT_ATT) { - tmxr_putc_ln(altairTMXR.ldsc[ti], data); + tmxr_putc_ln(altairTMXR.ldsc[ti], d); } else { - sim_putchar(data); + sim_putchar(d); } return 0; /* ignored since OUT */ } } -/* Port 2 controls the PTR/PTP devices */ +/* port 2 controls the PTR/PTP devices */ -int32 sio1s(int32 port, int32 io, int32 data) { +int32 sio1s(const int32 port, const int32 io, const int32 data) { if (io == 0) { /* reset I bit iff PTR unit not attached or no more data available. */ /* O bit is always set since write always possible. */ @@ -500,7 +515,7 @@ int32 sio1s(int32 port, int32 io, int32 data) { } return 0x02; } - return (ptr_unit.u3 != 0) ? 0x02 : 0x03; + return ptr_unit.u3 ? 0x02 : 0x03; } else { /* OUT */ if (data == 0x03) { @@ -515,7 +530,7 @@ int32 sio1s(int32 port, int32 io, int32 data) { } } -int32 sio1d(int32 port, int32 io, int32 data) { +int32 sio1d(const int32 port, const int32 io, const int32 data) { int32 temp; if (io == 0) { /* IN */ if (ptr_unit.u3) { /* no more data available */ @@ -552,7 +567,7 @@ int32 sio1d(int32 port, int32 io, int32 data) { } } -int32 nulldev(int32 port, int32 io, int32 data) { +int32 nulldev(const int32 port, const int32 io, const int32 data) { if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnassignedPort < warnLevelSIO)) { warnUnassignedPort++; if (io == 0) { @@ -565,83 +580,88 @@ int32 nulldev(int32 port, int32 io, int32 data) { return io == 0 ? 0xff : 0; } -int32 sr_dev(int32 port, int32 io, int32 data) { +int32 sr_dev(const int32 port, const int32 io, const int32 data) { return io == 0 ? SR : 0; } -int32 toBCD(int32 x) { +static int32 toBCD(const int32 x) { return (x / 10) * 16 + (x % 10); } -int32 fromBCD(int32 x) { +static int32 fromBCD(const int32 x) { return 10 * ((0xf0 & x) >> 4) + (0x0f & x); } -/* Z80 or 8080 programs communicate with the SIMH pseudo device via port 0xfe. - The principles are as follows: +/* Z80 or 8080 programs communicate with the SIMH pseudo device via port 0xfe. + The following principles apply: - 1) For commands that do not require parameters and do not return results - ld a, - out (0feh),a - Special case is the reset command which needs to be send 128 times to make - sure that the internal state is properly reset. + 1) For commands that do not require parameters and do not return results + ld a, + out (0feh),a + Special case is the reset command which needs to be send 128 times to make + sure that the internal state is properly reset. - 2) For commands that require parameters and do not return results - ld a, - out (0feh),a - ld a, - out (0feh),a - ld a, - out (0feh),a - ... - Note: The calling program must send all parameter bytes. Otherwise - the pseudo device is left in an unexpected state. + 2) For commands that require parameters and do not return results + ld a, + out (0feh),a + ld a, + out (0feh),a + ld a, + out (0feh),a + ... + Note: The calling program must send all parameter bytes. Otherwise + the pseudo device is left in an unexpected state. - 3) For commands that do not require parameters and return results - ld a, - out (0feh),a - in a,(0feh) ; contains first byte of result - in a,(0feh) ; contains second byte of result - ... - Note: The calling program must request all bytes of the result. Otherwise - the pseudo device is left in an unexpected state. + 3) For commands that do not require parameters and return results + ld a, + out (0feh),a + in a,(0feh) ; contains first byte of result + in a,(0feh) ; contains second byte of result + ... + Note: The calling program must request all bytes of the result. Otherwise + the pseudo device is left in an unexpected state. - 4) Commands requiring parameters and returning results do not exist currently. + 4) Commands requiring parameters and returning results do not exist currently. */ -#define splimit 10 -#define printTimeCmd 0 /* print the current time in milliseconds */ -#define startTimerCmd 1 /* start a new timer on the top of the timer stack */ -#define stopTimerCmd 2 /* stop timer on top of timer stack and show time difference */ -#define resetPTRCmd 3 /* reset the PTR device */ -#define attachPTRCmd 4 /* attach the PTR device */ -#define detachPTRCmd 5 /* detach the PTR device */ -#define getSIMHVersionCMD 6 /* get the current version of the SIMH pseudo device */ -#define getClockZSDOSCmd 7 /* get the current time in ZSDOS format */ -#define setClockZSDOSCmd 8 /* set the current time in ZSDOS format */ -#define getClockCPM3Cmd 9 /* get the current time in CP/M 3 format */ -#define setClockCPM3Cmd 10 /* set the current time in CP/M 3 format */ -#define getBankSelectCmd 11 /* get the selected bank */ -#define setBankSelectCmd 12 /* set the selected bank */ -#define getCommonCmd 13 /* get the base address of the common memory segment */ -#define resetSIMHInterfaceCmd 14 /* reset the SIMH pseudo device */ -#define showTimerCmd 15 /* show time difference to timer on top of stack */ -#define attachPTPCmd 16 /* attach PTP to the file with name at beginning of CP/M command line */ -#define detachPTPCmd 17 /* detach PTP */ -#define hasBankedMemoryCmd 18 /* determines whether machine has banked memory */ -#define setZ80CPUCmd 19 /* set the CPU to a Z80 */ -#define set8080CPUCmd 20 /* set the CPU to an 8080 */ -#define startTimerInterruptsCmd 21 /* statr timer interrupts */ -#define stopTimerInterruptsCmd 22 /* stop timer interrupts */ -#define setTimerDeltaCmd 23 /* set the timer interval in which interrupts occur */ -#define setTimerInterruptAdrCmd 24 /* set the address to call by timer interrupts */ -#define cpmCommandLineLength 128 -struct tm *currentTime = NULL; -uint32 markTime[splimit]; -char version[] = "SIMH002"; +enum simhPseudoDeviceCommands { /* do not change order or remove commands, add only at the end */ + printTimeCmd, /* 0 print the current time in milliseconds */ + startTimerCmd, /* 1 start a new timer on the top of the timer stack */ + stopTimerCmd, /* 2 stop timer on top of timer stack and show time difference */ + resetPTRCmd, /* 3 reset the PTR device */ + attachPTRCmd, /* 4 attach the PTR device */ + detachPTRCmd, /* 5 detach the PTR device */ + getSIMHVersionCmd, /* 6 get the current version of the SIMH pseudo device */ + getClockZSDOSCmd, /* 7 get the current time in ZSDOS format */ + setClockZSDOSCmd, /* 8 set the current time in ZSDOS format */ + getClockCPM3Cmd, /* 9 get the current time in CP/M 3 format */ + setClockCPM3Cmd, /* 10 set the current time in CP/M 3 format */ + getBankSelectCmd, /* 11 get the selected bank */ + setBankSelectCmd, /* 12 set the selected bank */ + getCommonCmd, /* 13 get the base address of the common memory segment */ + resetSIMHInterfaceCmd, /* 14 reset the SIMH pseudo device */ + showTimerCmd, /* 15 show time difference to timer on top of stack */ + attachPTPCmd, /* 16 attach PTP to the file with name at beginning of CP/M command line*/ + detachPTPCmd, /* 17 detach PTP */ + hasBankedMemoryCmd, /* 18 determines whether machine has banked memory */ + setZ80CPUCmd, /* 19 set the CPU to a Z80 */ + set8080CPUCmd, /* 20 set the CPU to an 8080 */ + startTimerInterruptsCmd,/* 21 start timer interrupts */ + stopTimerInterruptsCmd, /* 22 stop timer interrupts */ + setTimerDeltaCmd, /* 23 set the timer interval in which interrupts occur */ + setTimerInterruptAdrCmd,/* 24 set the address to call by timer interrupts */ + resetStopWatchCmd, /* 25 reset the millisecond stop watch */ + readStopWatchCmd /* 26 read the millisecond stop watch */ +}; -t_stat simh_dev_reset(DEVICE *dptr) { +#define cpmCommandLineLength 128 +#define splimit 10 /* stack depth of timer stack */ +static uint32 markTime[splimit]; /* timer stack */ +static struct tm *currentTime = NULL; +static char version[] = "SIMH002"; + +static t_stat simh_dev_reset(DEVICE *dptr) { currentTime = NULL; ClockZSDOSDelta = 0; setClockZSDOSPos = 0; @@ -649,6 +669,7 @@ t_stat simh_dev_reset(DEVICE *dptr) { ClockCPM3Delta = 0; setClockCPM3Pos = 0; getClockCPM3Pos = 0; + getStopWatchDeltaPos = 0; getCommonPos = 0; setTimerDeltaPos = 0; setTimerInterruptAdrPos = 0; @@ -663,24 +684,30 @@ t_stat simh_dev_reset(DEVICE *dptr) { return SCPE_OK; } -t_stat simh_dev_set_timeron(UNIT *uptr, int32 val, char *cptr, void *desc) { +static void warnNoRealTimeClock(void) { + if (simh_unit.flags & UNIT_SIMH_VERBOSE) { + printf("Sorry - no real time clock available.\n"); + } +} + +static t_stat simh_dev_set_timeron(UNIT *uptr, int32 value, char *cptr, void *desc) { if (rtc_avail) { timeOfNextInterrupt = sim_os_msec() + timerDelta; return sim_activate(&simh_unit, simh_unit.wait); /* activate unit */ } else { - printf("Sorry - no real time clock available.\n"); + warnNoRealTimeClock(); return SCPE_ARG; } } -t_stat simh_dev_set_timeroff(UNIT *uptr, int32 val, char *cptr, void *desc) { +static t_stat simh_dev_set_timeroff(UNIT *uptr, int32 value, char *cptr, void *desc) { timerInterrupt = FALSE; sim_cancel(&simh_unit); return SCPE_OK; } -t_stat simh_svc(UNIT *uptr) { +static t_stat simh_svc(UNIT *uptr) { uint32 n = sim_os_msec(); if (n >= timeOfNextInterrupt) { timerInterrupt = TRUE; @@ -695,8 +722,8 @@ t_stat simh_svc(UNIT *uptr) { return SCPE_OK; } -/* The CP/M commandline is used as the name of a file and UNIT* uptr is attached to it */ -void attachCPM(UNIT *uptr) { +/* The CP/M commandline is used as the name of a file and UNIT* uptr is attached to it. */ +static void attachCPM(UNIT *uptr) { char cpmCommandLine[cpmCommandLineLength]; uint32 i, len = (GetBYTEWrapper(0x80) & 0x7f) - 1; /* 0x80 contains length of commandline, discard first char */ for (i = 0; i < len; i++) { @@ -716,7 +743,7 @@ void attachCPM(UNIT *uptr) { } /* setClockZSDOSAdr points to 6 byte block in M: YY MM DD HH MM SS in BCD notation */ -void setClockZSDOS(void) { +static void setClockZSDOS(void) { struct tm newTime; int32 year = fromBCD(GetBYTEWrapper(setClockZSDOSAdr)); newTime.tm_year = year < 50 ? year + 100 : year; @@ -731,7 +758,7 @@ void setClockZSDOS(void) { #define secondsPerMinute 60 #define secondsPerHour (60 * secondsPerMinute) #define secondsPerDay (24 * secondsPerHour) -time_t mkCPM3Origin(void) { +static time_t mkCPM3Origin(void) { struct tm date; date.tm_year = 77; date.tm_mon = 11; @@ -747,7 +774,7 @@ time_t mkCPM3Origin(void) { 2 BCD byte: HH 3 BCD byte: MM 4 BCD byte: SS */ -void setClockCPM3(void) { +static void setClockCPM3(void) { ClockCPM3Delta = mkCPM3Origin() + (GetBYTEWrapper(setClockCPM3Adr) + GetBYTEWrapper(setClockCPM3Adr + 1) * 256) * secondsPerDay + fromBCD(GetBYTEWrapper(setClockCPM3Adr + 2)) * secondsPerHour + @@ -755,12 +782,13 @@ void setClockCPM3(void) { fromBCD(GetBYTEWrapper(setClockCPM3Adr + 4)) - time(NULL); } -int32 simh_in(void) { +static int32 simh_in(const int32 port) { int32 result; switch(lastCommand) { case attachPTRCmd: case attachPTPCmd: result = lastCPMStatus; + lastCommand = 0; break; case getClockZSDOSCmd: if (currentTime) { @@ -768,40 +796,67 @@ int32 simh_in(void) { case 0: result = toBCD(currentTime -> tm_year > 99 ? currentTime -> tm_year - 100 : currentTime -> tm_year); + getClockZSDOSPos = 1; + break; + case 1: + result = toBCD(currentTime -> tm_mon + 1); + getClockZSDOSPos = 2; + break; + case 2: + result = toBCD(currentTime -> tm_mday); + getClockZSDOSPos = 3; + break; + case 3: + result = toBCD(currentTime -> tm_hour); + getClockZSDOSPos = 4; + break; + case 4: + result = toBCD(currentTime -> tm_min); + getClockZSDOSPos = 5; + break; + case 5: + result = toBCD(currentTime -> tm_sec); + getClockZSDOSPos = lastCommand = 0; break; - case 1: result = toBCD(currentTime -> tm_mon + 1); break; - case 2: result = toBCD(currentTime -> tm_mday); break; - case 3: result = toBCD(currentTime -> tm_hour); break; - case 4: result = toBCD(currentTime -> tm_min); break; - case 5: result = toBCD(currentTime -> tm_sec); break; - default: result = 0; } - getClockZSDOSPos++; } else { - result = 0; + result = getClockZSDOSPos = lastCommand = 0; } break; case getClockCPM3Cmd: if (currentTime) { switch(getClockCPM3Pos) { - case 0: result = daysCPM3SinceOrg & 0xff; break; - case 1: result = (daysCPM3SinceOrg >> 8) & 0xff; break; - case 2: result = toBCD(currentTime -> tm_hour); break; - case 3: result = toBCD(currentTime -> tm_min); break; - case 4: result = toBCD(currentTime -> tm_sec); break; - default: result = 0; + case 0: + result = daysCPM3SinceOrg & 0xff; + getClockCPM3Pos = 1; + break; + case 1: + result = (daysCPM3SinceOrg >> 8) & 0xff; + getClockCPM3Pos = 2; + break; + case 2: + result = toBCD(currentTime -> tm_hour); + getClockCPM3Pos = 3; + break; + case 3: + result = toBCD(currentTime -> tm_min); + getClockCPM3Pos = 4; + break; + case 4: + result = toBCD(currentTime -> tm_sec); + getClockCPM3Pos = lastCommand = 0; + break; } - getClockCPM3Pos++; } else { - result = 0; + result = getClockCPM3Pos = lastCommand = 0; } break; - case getSIMHVersionCMD: + case getSIMHVersionCmd: result = version[versionPos++]; if (result == 0) { - versionPos = 0; + versionPos = lastCommand = 0; } break; case getBankSelectCmd: @@ -814,6 +869,7 @@ int32 simh_in(void) { message1("Get selected bank ignored for non-banked memory."); } } + lastCommand = 0; break; case getCommonCmd: if (getCommonPos == 0) { @@ -822,48 +878,56 @@ int32 simh_in(void) { } else { result = (common >> 8) & 0xff; - getCommonPos = 0; + getCommonPos = lastCommand = 0; } break; case hasBankedMemoryCmd: result = cpu_unit.flags & UNIT_BANKED ? MAXBANKS : 0; + lastCommand = 0; + break; + case readStopWatchCmd: + if (getStopWatchDeltaPos == 0) { + result = stopWatchDelta & 0xff; + getStopWatchDeltaPos = 1; + } + else { + result = (stopWatchDelta >> 8) & 0xff; + getStopWatchDeltaPos = lastCommand = 0; + } break; default: - result = 0; + if (simh_unit.flags & UNIT_SIMH_VERBOSE) { + message2("Unnecessary IN from SIMH pseudo device on port %03xh ignored.\n", + port); + } + result = lastCommand = 0; } return result; } -int32 simh_out(int32 data) { - uint32 delta; +static int32 simh_out(const int32 port, const int32 data) { time_t now; switch(lastCommand) { case setClockZSDOSCmd: - switch(setClockZSDOSPos) { - case 0: - setClockZSDOSAdr = data; - setClockZSDOSPos++; - break; - case 1: - setClockZSDOSAdr += (data << 8); - setClockZSDOS(); - lastCommand = 0; - break; - default:; + if (setClockZSDOSPos == 0) { + setClockZSDOSAdr = data; + setClockZSDOSPos = 1; + } + else { + setClockZSDOSAdr |= (data << 8); + setClockZSDOS(); + setClockZSDOSPos = lastCommand = 0; } break; case setClockCPM3Cmd: - switch(setClockCPM3Pos) { - case 0: - setClockCPM3Adr = data; - setClockCPM3Pos++; - break; - case 1: - setClockCPM3Adr += (data << 8); - setClockCPM3(); - lastCommand = 0; - break; - default:; + if (setClockCPM3Pos == 0) { + setClockCPM3Adr = data; + setClockCPM3Pos = 1; + } + else { + setClockCPM3Adr |= (data << 8); + setClockCPM3(); + setClockCPM3Pos = lastCommand = 0; } break; case setBankSelectCmd: @@ -876,29 +940,23 @@ int32 simh_out(int32 data) { lastCommand = 0; break; case setTimerDeltaCmd: - switch(setTimerDeltaPos) { - case 0: - tmpTimerDelta = data; - setTimerDeltaPos++; - break; - case 1: - timerDelta = tmpTimerDelta + (data << 8); - lastCommand = 0; - break; - default:; + if (setTimerDeltaPos == 0) { + timerDelta = data; + setTimerDeltaPos = 1; + } + else { + timerDelta |= (data << 8); + setTimerDeltaPos = lastCommand = 0; } break; case setTimerInterruptAdrCmd: - switch(setTimerInterruptAdrPos) { - case 0: - tmpTimerInterruptHandler = data; - setTimerInterruptAdrPos++; - break; - case 1: - timerInterruptHandler = tmpTimerInterruptHandler + (data << 8); - lastCommand = 0; - break; - default:; + if (setTimerInterruptAdrPos == 0) { + timerInterruptHandler = data; + setTimerInterruptAdrPos = 1; + } + else { + timerInterruptHandler |= (data << 8); + setTimerInterruptAdrPos = lastCommand = 0; } break; default: @@ -908,8 +966,11 @@ int32 simh_out(int32 data) { if (rtc_avail) { message2("Current time in milliseconds = %d.\n", sim_os_msec()); } + else { + warnNoRealTimeClock(); + } break; - case startTimerCmd: /* create a new timer on top of stack */ + case startTimerCmd: /* create a new timer on top of stack */ if (rtc_avail) { if (markTimeSP < splimit) { markTime[markTimeSP++] = sim_os_msec(); @@ -918,17 +979,23 @@ int32 simh_out(int32 data) { message1("Timer stack overflow.\n"); } } + else { + warnNoRealTimeClock(); + } break; - case stopTimerCmd: /* stop timer on top of stack and show time difference */ + case stopTimerCmd: /* stop timer on top of stack and show time difference */ if (rtc_avail) { if (markTimeSP > 0) { - delta = sim_os_msec() - markTime[--markTimeSP]; + uint32 delta = sim_os_msec() - markTime[--markTimeSP]; message2("Timer stopped. Elapsed time in milliseconds = %d.\n", delta); } else { message1("No timer active.\n"); } } + else { + warnNoRealTimeClock(); + } break; case resetPTRCmd: /* reset ptr device */ ptr_reset(NULL); @@ -939,7 +1006,7 @@ int32 simh_out(int32 data) { case detachPTRCmd: /* detach ptr */ detach_unit(&ptr_unit); break; - case getSIMHVersionCMD: + case getSIMHVersionCmd: versionPos = 0; break; case getClockZSDOSCmd: @@ -962,25 +1029,27 @@ int32 simh_out(int32 data) { setClockCPM3Pos = 0; break; case getBankSelectCmd: - break; case setBankSelectCmd: - break; case getCommonCmd: + case hasBankedMemoryCmd: break; case resetSIMHInterfaceCmd: markTimeSP = 0; lastCommand = 0; break; - case showTimerCmd: /* show time difference to timer on top of stack */ + case showTimerCmd: /* show time difference to timer on top of stack */ if (rtc_avail) { if (markTimeSP > 0) { - delta = sim_os_msec() - markTime[markTimeSP - 1]; + uint32 delta = sim_os_msec() - markTime[markTimeSP - 1]; message2("Timer running. Elapsed in milliseconds = %d.\n", delta); } else { message1("No timer active.\n"); } } + else { + warnNoRealTimeClock(); + } break; case attachPTPCmd: /* attach ptp to the file with name at beginning of CP/M command line */ attachCPM(&ptp_unit); @@ -988,8 +1057,6 @@ int32 simh_out(int32 data) { case detachPTPCmd: /* detach ptp */ detach_unit(&ptp_unit); break; - case hasBankedMemoryCmd: - break; case setZ80CPUCmd: cpu_unit.flags |= UNIT_CHIP; break; @@ -1012,9 +1079,17 @@ int32 simh_out(int32 data) { case setTimerInterruptAdrCmd: setTimerInterruptAdrPos = 0; break; + case resetStopWatchCmd: + stopWatchNow = rtc_avail ? sim_os_msec() : 0; + break; + case readStopWatchCmd: + getStopWatchDeltaPos = 0; + stopWatchDelta = rtc_avail ? sim_os_msec() - stopWatchNow : 0; + break; default: if (simh_unit.flags & UNIT_SIMH_VERBOSE) { - message2("Unknown command (%i) to SIMH pseudo device ignored.\n", data); + message3("Unknown command (%i) to SIMH pseudo device on port %03xh ignored.\n", + data, port); } } } @@ -1022,6 +1097,6 @@ int32 simh_out(int32 data) { } /* port 0xfe is a device for communication SIMH <--> Altair machine */ -int32 simh_dev(int32 port, int32 io, int32 data) { - return io == 0 ? simh_in() : simh_out(data); +int32 simh_dev(const int32 port, const int32 io, const int32 data) { + return io == 0 ? simh_in(port) : simh_out(port, data); } diff --git a/AltairZ80/altairZ80_sys.c b/AltairZ80/altairZ80_sys.c index 6c3a7aa1..9cc29210 100644 --- a/AltairZ80/altairZ80_sys.c +++ b/AltairZ80/altairZ80_sys.c @@ -1,30 +1,30 @@ /* altairz80_sys.c: MITS Altair system interface - Copyright (c) 2002, Peter Schorn + Copyright (c) 2002-2003, Peter Schorn - 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: + 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 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 - ROBERT M SUPNIK 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. + 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 + PETER SCHORN 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. - Except as contained in this notice, the name of Peter Schorn shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Peter Schorn. + Except as contained in this notice, the name of Peter Schorn shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Peter Schorn. - Based on work by Charles E Owen (c) 1997 - Disassembler from Marat Fayzullin ((c) 1995, 1996, 1997 - Commercial use prohibited) + Based on work by Charles E Owen (c) 1997 + Disassembler from Marat Fayzullin ((c) 1995, 1996, 1997 - Commercial use prohibited) */ #include @@ -40,27 +40,24 @@ extern DEVICE simh_device; extern DEVICE ptr_dev; extern DEVICE ptp_dev; extern int32 saved_PC; -extern char *get_range(char *cptr, t_addr *lo, t_addr *hi, int rdx, - t_addr max, char term); -extern t_value get_uint(char *cptr, int radix, t_value max, t_stat *status); extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value); extern void PutBYTEForced(register uint32 Addr, register uint32 Value); extern uint8 GetBYTEWrapper(register uint32 Addr); -extern int32 addressIsInROM(uint32 Addr); -extern int32 addressExists(uint32 Addr); -extern uint32 ROMLow; -extern uint32 ROMHigh; +extern int32 addressIsInROM(const uint32 Addr); +extern int32 addressExists(const uint32 Addr); +extern void printROMMessage(const uint32 cntROM); int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag); int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw); -int32 checkbase(char ch, char *numString); -int32 numok(char ch, char **numString, int32 minvalue, int32 maxvalue, int32 requireSign, int32 *result); -int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star, int32 *at, +static int32 checkbase(char ch, const char *numString); +static int32 numok(char ch, const char **numString, const int32 minvalue, + const int32 maxvalue, const int32 requireSign, int32 *result); +static int32 match(const char *pattern, const char *input, char *xyFirst, char *xy, int32 *number, int32 *star, int32 *at, int32 *hat, int32 *dollar); -int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]); +static int32 parse_X80(const char *cptr, const int32 addr, uint32 *val, char *const Mnemonics[]); int32 parse_sym(char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw); -int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr); -int32 checkXY(char xy); +static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const int32 addr); +static int32 checkXY(const char xy); /* SCP data structures sim_name simulator name string @@ -78,14 +75,12 @@ DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &simh_device, &ptr_dev, &ptp_dev, char memoryAccessMessage[80]; const char *sim_stop_messages[] = { - "Unknown error", - "Unknown I/O Instruction", "HALT instruction", "Breakpoint", memoryAccessMessage, "Invalid Opcode" }; -static char *Mnemonics8080[] = { +static char *const Mnemonics8080[] = { /*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ "NOP", "LXI B,#h", "STAX B", "INX B", "INR B", "DCR B", "MVI B,*h", "RLC", /* 00-07 */ "DB 09h", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */ @@ -121,7 +116,7 @@ static char *Mnemonics8080[] = { "RM", "SPHL", "JM #h", "EI", "CM #h", "DB FDh", "CPI *h", "RST 7" /* f8-ff */ }; -static char *MnemonicsZ80[256] = { +static char *const MnemonicsZ80[256] = { /*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ "NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA", /* 00-07 */ "EX AF,AF'", "ADD HL,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA", /* 08-0f */ @@ -157,7 +152,7 @@ static char *MnemonicsZ80[256] = { "RET M", "LD SP,HL", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h" /* f8-ff */ }; -static char *MnemonicsCB[256] = { +static char *const MnemonicsCB[256] = { /*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ "RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (HL)", "RLC A", /* 00-07 */ "RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (HL)", "RRC A", /* 08-0f */ @@ -193,7 +188,7 @@ static char *MnemonicsCB[256] = { "SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(HL)", "SET 7,A" /* f8-ff */ }; -static char *MnemonicsED[256] = { +static char *const MnemonicsED[256] = { /*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ "DB EDh,00h", "DB EDh,01h", "DB EDh,02h", "DB EDh,03h", "DB EDh,04h", "DB EDh,05h", "DB EDh,06h", "DB EDh,07h", /* 00-07 */ "DB EDh,08h", "DB EDh,09h", "DB EDh,0Ah", "DB EDh,0Bh", "DB EDh,0Ch", "DB EDh,0Dh", "DB EDh,0Eh", "DB EDh,0Fh", /* 08-0f */ @@ -229,32 +224,32 @@ static char *MnemonicsED[256] = { "DB EDh,F8h", "DB EDh,F9h", "DB EDh,FAh", "DB EDh,FBh", "DB EDh,FCh", "DB EDh,FDh", "DB EDh,FEh", "DB EDh,FFh" /* f8-ff */ }; -static char *MnemonicsXX[256] = { +static char *const MnemonicsXX[256] = { /*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ "NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA", /* 00-07 */ "EX AF,AF'", "ADD I%,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA", /* 08-0f */ "DJNZ $h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA", /* 10-17 */ "JR $h", "ADD I%,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA", /* 18-1f */ - "JR NZ,$h", "LD I%,#h", "LD (#h),I%", "INC I%", "INC I%h", "DEC I%h", "LD I%h,*h", "DAA", /* 20-27 */ - "JR Z,$h", "ADD I%,I%", "LD I%,(#h)", "DEC I%", "INC I%l", "DEC I%l", "LD I%l,*h", "CPL", /* 28-2f */ + "JR NZ,$h", "LD I%,#h", "LD (#h),I%", "INC I%", "INC I%H", "DEC I%H", "LD I%H,*h", "DAA", /* 20-27 */ + "JR Z,$h", "ADD I%,I%", "LD I%,(#h)", "DEC I%", "INC I%L", "DEC I%L", "LD I%L,*h", "CPL", /* 28-2f */ "JR NC,$h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (I%+^h)", "DEC (I%+^h)", "LD (I%+^h),*h", "SCF", /* 30-37 */ "JR C,$h", "ADD I%,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF", /* 38-3f */ - "LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,I%h", "LD B,I%l", "LD B,(I%+^h)", "LD B,A", /* 40-47 */ - "LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,I%h", "LD C,I%l", "LD C,(I%+^h)", "LD C,A", /* 48-4f */ - "LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,I%h", "LD D,I%l", "LD D,(I%+^h)", "LD D,A", /* 50-57 */ - "LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,I%h", "LD E,I%l", "LD E,(I%+^h)", "LD E,A", /* 58-5f */ - "LD I%h,B", "LD I%h,C", "LD I%h,D", "LD I%h,E", "LD I%h,I%h", "LD I%h,I%l", "LD H,(I%+^h)", "LD I%h,A", /* 60-67 */ - "LD I%l,B", "LD I%l,C", "LD I%l,D", "LD I%l,E", "LD I%l,I%h", "LD I%l,I%l", "LD L,(I%+^h)", "LD I%l,A", /* 68-6f */ + "LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,I%H", "LD B,I%L", "LD B,(I%+^h)", "LD B,A", /* 40-47 */ + "LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,I%H", "LD C,I%L", "LD C,(I%+^h)", "LD C,A", /* 48-4f */ + "LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,I%H", "LD D,I%L", "LD D,(I%+^h)", "LD D,A", /* 50-57 */ + "LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,I%H", "LD E,I%L", "LD E,(I%+^h)", "LD E,A", /* 58-5f */ + "LD I%H,B", "LD I%H,C", "LD I%H,D", "LD I%H,E", "LD I%H,I%H", "LD I%H,I%L", "LD H,(I%+^h)", "LD I%H,A", /* 60-67 */ + "LD I%L,B", "LD I%L,C", "LD I%L,D", "LD I%L,E", "LD I%L,I%H", "LD I%L,I%L", "LD L,(I%+^h)", "LD I%L,A", /* 68-6f */ "LD (I%+^h),B", "LD (I%+^h),C", "LD (I%+^h),D", "LD (I%+^h),E", "LD (I%+^h),H", "LD (I%+^h),L", "HALT", "LD (I%+^h),A", /* 70-77 */ - "LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,I%h", "LD A,I%l", "LD A,(I%+^h)", "LD A,A", /* 78-7f */ - "ADD A,B", "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,I%h", "ADD A,I%l", "ADD A,(I%+^h)", "ADD A,A", /* 80-87 */ - "ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,I%h", "ADC A,I%l", "ADC A,(I%+^h)", "ADC A,A", /* 88-8f */ - "SUB B", "SUB C", "SUB D", "SUB E", "SUB I%h", "SUB I%l", "SUB (I%+^h)", "SUB A", /* 90-97 */ - "SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,I%h", "SBC A,I%l", "SBC A,(I%+^h)", "SBC A,A", /* 98-9f */ - "AND B", "AND C", "AND D", "AND E", "AND I%h", "AND I%l", "AND (I%+^h)", "AND A", /* a0-a7 */ - "XOR B", "XOR C", "XOR D", "XOR E", "XOR I%h", "XOR I%l", "XOR (I%+^h)", "XOR A", /* a8-af */ - "OR B", "OR C", "OR D", "OR E", "OR I%h", "OR I%l", "OR (I%+^h)", "OR A", /* b0-b7 */ - "CP B", "CP C", "CP D", "CP E", "CP I%h", "CP I%l", "CP (I%+^h)", "CP A", /* b8-bf */ + "LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,I%H", "LD A,I%L", "LD A,(I%+^h)", "LD A,A", /* 78-7f */ + "ADD A,B", "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,I%H", "ADD A,I%L", "ADD A,(I%+^h)", "ADD A,A", /* 80-87 */ + "ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,I%H", "ADC A,I%L", "ADC A,(I%+^h)", "ADC A,A", /* 88-8f */ + "SUB B", "SUB C", "SUB D", "SUB E", "SUB I%H", "SUB I%L", "SUB (I%+^h)", "SUB A", /* 90-97 */ + "SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,I%H", "SBC A,I%L", "SBC A,(I%+^h)", "SBC A,A", /* 98-9f */ + "AND B", "AND C", "AND D", "AND E", "AND I%H", "AND I%L", "AND (I%+^h)", "AND A", /* a0-a7 */ + "XOR B", "XOR C", "XOR D", "XOR E", "XOR I%H", "XOR I%L", "XOR (I%+^h)", "XOR A", /* a8-af */ + "OR B", "OR C", "OR D", "OR E", "OR I%H", "OR I%L", "OR (I%+^h)", "OR A", /* b0-b7 */ + "CP B", "CP C", "CP D", "CP E", "CP I%H", "CP I%L", "CP (I%+^h)", "CP A", /* b8-bf */ "RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD A,*h", "RST 00h", /* c8-cf */ "RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC A,*h", "RST 08h", /* c8-cf */ "RET NC", "POP DE", "JP NC,#h", "OUT (*h),A", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h", /* d0-d7 */ @@ -265,7 +260,7 @@ static char *MnemonicsXX[256] = { "RET M", "LD SP,I%", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h" /* f8-ff */ }; -static char *MnemonicsXCB[256] = { +static char *const MnemonicsXCB[256] = { /*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ "RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (I%@h)", "RLC A", /* 00-07 */ "RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (I%@h)", "RRC A", /* 08-0f */ @@ -301,7 +296,7 @@ static char *MnemonicsXCB[256] = { "SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(I%@h)", "SET 7,A" /* f8-ff */ }; -/* Symbolic disassembler +/* symbolic disassembler Inputs: *val = instructions to disassemble @@ -316,9 +311,9 @@ static char *MnemonicsXCB[256] = { */ -int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr) { - char R[128], H[10], C= '\0', *T, *P; - uint8 J = 0, Offset; +static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const int32 addr) { + char R[128], H[10], C = '\0', *T, *P; + uint8 J = 0, Offset = 0; uint16 B = 0; if (useZ80Mnemonics) { @@ -333,8 +328,7 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr) { break; case 0xdd: case 0xfd: - C = (val[B] == 0xdd) ? 'X' : 'Y'; - B++; + C = (val[B++] == 0xdd) ? 'X' : 'Y'; if (val[B] == 0xcb) { B++; Offset = val[B++]; @@ -411,7 +405,7 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr) { return(B); } -/* Symbolic output +/* symbolic output Inputs: *of = output stream @@ -440,7 +434,7 @@ int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw) { /* numString checks determines the base of the number (ch, *numString) and returns FALSE if the number is bad */ -int32 checkbase(char ch, char *numString) { +static int32 checkbase(char ch, const char *numString) { int32 decimal = (ch <= '9'); if (toupper(ch) == 'H') { return FALSE; @@ -453,7 +447,8 @@ int32 checkbase(char ch, char *numString) { return toupper(ch) == 'H' ? 16 : (decimal ? 10 : FALSE); } -int32 numok(char ch, char **numString, int32 minvalue, int32 maxvalue, int32 requireSign, int32 *result) { +static int32 numok(char ch, const char **numString, const int32 minvalue, + const int32 maxvalue, const int32 requireSign, int32 *result) { int32 sign = 1, value = 0, base; if (requireSign) { if (ch == '+') { @@ -481,17 +476,19 @@ int32 numok(char ch, char **numString, int32 minvalue, int32 maxvalue, int32 req return (minvalue <= value) && (value <= maxvalue); } -int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star, - int32 *at, int32 *hat, int32 *dollar) { +static int32 match(const char *pattern, const char *input, char *xyFirst, char *xy, int32 *number, int32 *star, + int32 *at, int32 *hat, int32 *dollar) { char pat = *pattern++; char inp = *input++; while ((pat) && (inp)) { switch(pat) { + case '_': /* patterns containting '_' should never match */ + return FALSE; case ',': if (inp == ' ') { inp = *input++; continue; - } + } /* otherwise fall through */ case ' ': if (inp != pat) { return FALSE; @@ -502,11 +499,21 @@ int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star, inp = *input++; } continue; - break; case '%': inp = toupper(inp); if ((inp == 'X') || (inp == 'Y')) { - *xy = inp; + if (*xyFirst) { /* make sure that second '%' corresponds to first */ + if (*xyFirst == inp) { + *xy = inp; + } + else { + return FALSE; + } + } + else { /* take note of first '%' for later */ + *xyFirst = inp; + *xy = inp; + } } else { return FALSE; @@ -566,25 +573,16 @@ int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star, return (pat == 0) && (inp == 0); } -INLINE int32 checkXY(char xy) { - if (xy == 'X') { - return 0xdd; - } - else if (xy == 'Y') { - return 0xfd; - } - else { - printf("X or Y expected.\n"); - return FALSE; - } +static INLINE int32 checkXY(const char xy) { + return xy == 'X' ? 0xdd : 0xfd; /* else is 'Y' */ } -int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) { - char xy; +static int32 parse_X80(const char *cptr, const int32 addr, uint32 *val, char *const Mnemonics[]) { + char xyFirst = 0, xy; int32 op, number, star, at, hat, dollar; for (op = 0; op < 256; op++) { number = star = at = dollar = -129; - if (match(Mnemonics[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) { + if (match(Mnemonics[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) { val[0] = op; if (number >= 0) { val[1] = (0xff) & number; @@ -598,7 +596,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) { else if (at > -129) { if ((-128 <= at) && (at <= 127)) { val[1] = (int8)(at); - return -1; + return -1; /* one additional byte returned */ } else { return SCPE_ARG; @@ -624,7 +622,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) { } for (op = 0; op < 256; op++) { - if (match(MnemonicsCB[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) { + if (match(MnemonicsCB[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) { val[0] = 0xcb; val[1] = op; return -1; /* one additional byte returned */ @@ -633,7 +631,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) { for (op = 0; op < 256; op++) { number = -1; - if (match(MnemonicsED[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) { + if (match(MnemonicsED[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) { val[0] = 0xed; val[1] = op; if (number >= 0) { @@ -649,8 +647,9 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) { for (op = 0; op < 256; op++) { number = star = hat = -1; - xy = ' '; - if (match(MnemonicsXX[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) { + xy = 0; + if (match(MnemonicsXX[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) { + /* all matches must have contained a '%' character */ if (!(val[0] = checkXY(xy))) { return SCPE_ARG; } @@ -681,8 +680,9 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) { for (op = 0; op < 256; op++) { at = -129; - xy = ' '; - if (match(MnemonicsXCB[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) { + xy = 0; + if (match(MnemonicsXCB[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) { + /* all matches must have contained a '%' character */ if (!(val[0] = checkXY(xy))) { return SCPE_ARG; } @@ -702,7 +702,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) { } -/* Symbolic input +/* symbolic input Inputs: *cptr = pointer to input string @@ -714,7 +714,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) { status = error status */ int32 parse_sym(char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw) { - while (isspace(*cptr)) cptr++; /* absorb spaces */ + while (isspace(*cptr)) cptr++; /* absorb spaces */ if ((sw & (SWMASK('A') | SWMASK('C'))) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ if (cptr[0] == 0) { return SCPE_ARG; /* must have one char */ @@ -773,9 +773,7 @@ int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag) { } /* end while */ printf("%d bytes [%d page%s] loaded at %x.\n", cnt, (cnt + 255) >> 8, ((cnt + 255) >> 8) == 1 ? "" : "s", org); - if (cntROM) { - printf("Warning: %d bytes written to ROM [%04X - %04X].\n", cntROM, ROMLow, ROMHigh); - } + printROMMessage(cntROM); if (cntNonExist) { printf("Warning: %d bytes written to non-existing memory (for this configuration).\n", cntNonExist); } diff --git a/AltairZ80/altairz80_hdsk.c b/AltairZ80/altairz80_hdsk.c index 2560b8a7..9794098b 100644 --- a/AltairZ80/altairz80_hdsk.c +++ b/AltairZ80/altairz80_hdsk.c @@ -1,30 +1,29 @@ -/* altairZ80_hdsk.c: simulated hard disk device to increase capacity +/* altairz80_hdsk.c: simulated hard disk device to increase capacity - Copyright (c) 2002, Peter Schorn + Copyright (c) 2002-2003, Peter Schorn - 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: + 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 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 - ROBERT M SUPNIK 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. + 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 + PETER SCHORN 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. - Except as contained in this notice, the name of Peter Schorn shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Peter Schorn. + Except as contained in this notice, the name of Peter Schorn shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Peter Schorn. */ -#include #include "altairz80_defs.h" #define UNIT_V_HDSKWLK (UNIT_V_UF + 0) /* write locked */ @@ -54,32 +53,32 @@ extern int32 saved_PC; extern int32 install_bootrom(void); extern void printMessage(void); +extern void PutBYTEBasic(const uint32 Addr, const uint32 Bank, const uint32 Value); extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value); -extern void protect(int32 l, int32 h); +extern void protect(const int32 l, const int32 h); extern uint8 GetBYTEWrapper(register uint32 Addr); extern int32 bootrom[bootrom_size]; -t_stat hdsk_svc(UNIT *uptr); -t_stat hdsk_boot(int32 unitno, DEVICE *dptr); -int32 hdsk_hasVerbose(void); -int32 hdsk_io(int32 port, int32 io, int32 data); -int32 hdsk_in(void); -int32 hdsk_out(int32 data); -int32 checkParameters(void); -int32 doSeek(void); -int32 doRead(void); -int32 doWrite(void); +static t_stat hdsk_svc(UNIT *uptr); +static t_stat hdsk_boot(int32 unitno, DEVICE *dptr); +static int32 hdsk_hasVerbose(void); +int32 hdsk_io(const int32 port, const int32 io, const int32 data); +static int32 hdsk_in(const int32 port); +static int32 hdsk_out(const int32 data); +static int32 checkParameters(void); +static int32 doSeek(void); +static int32 doRead(void); +static int32 doWrite(void); -uint8 hdskbuf[HDSK_SECTOR_SIZE]; /* Data Buffer */ -int32 hdskLastCommand = hdsk_none; -int32 hdskCommandPosition = 0; -int32 selectedDisk; -int32 selectedSector; -int32 selectedTrack; -int32 selectedDMA; -int32 hdskTrace; +static int32 hdskLastCommand = hdsk_none; +static int32 hdskCommandPosition = 0; +static int32 selectedDisk; +static int32 selectedSector; +static int32 selectedTrack; +static int32 selectedDMA; +static int32 hdskTrace; -UNIT hdsk_unit[] = { +static UNIT hdsk_unit[] = { { UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) }, { UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) }, { UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) }, @@ -89,7 +88,7 @@ UNIT hdsk_unit[] = { { UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) }, { UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) } }; -REG hdsk_reg[] = { +static REG hdsk_reg[] = { { DRDATA (HDCMD, hdskLastCommand, 32), REG_RO }, { DRDATA (HDPOS, hdskCommandPosition, 32), REG_RO }, { DRDATA (HDDSK, selectedDisk, 32), REG_RO }, @@ -99,7 +98,7 @@ REG hdsk_reg[] = { { DRDATA (HDTRACE, hdskTrace, 8), }, { NULL } }; -MTAB hdsk_mod[] = { +static MTAB hdsk_mod[] = { { UNIT_HDSKWLK, 0, "write enabled", "WRITEENABLED", NULL }, { UNIT_HDSKWLK, UNIT_HDSKWLK, "write locked", "LOCKED", NULL }, /* quiet, no warning messages */ @@ -112,13 +111,13 @@ DEVICE hdsk_dev = { "HDSK", hdsk_unit, hdsk_reg, hdsk_mod, 8, 10, 31, 1, 8, 8, NULL, NULL, NULL, - &hdsk_boot, NULL, NULL, NULL, 0 }; + &hdsk_boot, NULL, NULL, NULL, 0, NULL, NULL }; -t_stat hdsk_svc(UNIT *uptr) { +static t_stat hdsk_svc(UNIT *uptr) { return SCPE_OK; } -int32 hdskBoot[bootrom_size] = { +static const int32 hdskBoot[bootrom_size] = { 0xf3, 0x06, 0x80, 0x3e, 0x0e, 0xd3, 0xfe, 0x05, /* 5c00-5c07 */ 0xc2, 0x05, 0x5c, 0x3e, 0x16, 0xd3, 0xfe, 0x3e, /* 5c08-5c0f */ 0x12, 0xd3, 0xfe, 0xdb, 0xfe, 0xb7, 0xca, 0x20, /* 5c10-5c17 */ @@ -153,7 +152,7 @@ int32 hdskBoot[bootrom_size] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5cf8-5cff */ }; -t_stat hdsk_boot(int32 unitno, DEVICE *dptr) { +static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) { int32 i; if (MEMSIZE < 24*KB) { printf("Need at least 24KB RAM to boot from hard disk.\n"); @@ -165,7 +164,7 @@ t_stat hdsk_boot(int32 unitno, DEVICE *dptr) { } /* check whether we are really modifying an LD A,<> instruction */ if (bootrom[unitNoOffset1 - 1] == LDAInstruction) { - bootrom[unitNoOffset1] = (unitno+NUM_OF_DSK) & 0xff; /* LD A, */ + bootrom[unitNoOffset1] = (unitno + NUM_OF_DSK) & 0xff; /* LD A, */ } else { /* Attempt to modify non LD A,<> instructions is refused. */ printf("Incorrect boot ROM offset detected.\n"); @@ -173,7 +172,7 @@ t_stat hdsk_boot(int32 unitno, DEVICE *dptr) { } } for (i = 0; i < bootrom_size; i++) { - M[i + hdsk_boot_address][0] = hdskBoot[i] & 0xff; + PutBYTEBasic(i + hdsk_boot_address, 0, hdskBoot[i] & 0xff); } saved_PC = hdsk_boot_address; protect(hdsk_boot_address, hdsk_boot_address + bootrom_size - 1); @@ -181,7 +180,7 @@ t_stat hdsk_boot(int32 unitno, DEVICE *dptr) { } /* returns TRUE iff there exists a disk with VERBOSE */ -int32 hdsk_hasVerbose(void) { +static int32 hdsk_hasVerbose(void) { int32 i; for (i = 0; i < HDSK_NUMBER; i++) { if (((hdsk_dev.units + i) -> flags) & UNIT_HDSK_VERBOSE) { @@ -221,7 +220,7 @@ l ld a,(hl) ; get byte of parameter block */ /* check the parameters and return TRUE iff parameters are correct or have been repaired */ -int32 checkParameters(void) { +static int32 checkParameters(void) { int32 currentFlag; if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) { if (hdsk_hasVerbose()) { @@ -259,7 +258,7 @@ int32 checkParameters(void) { return TRUE; } -int32 doSeek(void) { +static int32 doSeek(void) { UNIT *uptr = hdsk_dev.units + selectedDisk; if (fseek(uptr -> fileref, HDSK_TRACK_SIZE * selectedTrack + HDSK_SECTOR_SIZE * selectedSector, SEEK_SET)) { @@ -274,8 +273,9 @@ int32 doSeek(void) { } } -int32 doRead(void) { +static int32 doRead(void) { int32 i; + uint8 hdskbuf[HDSK_SECTOR_SIZE]; /* data buffer */ UNIT *uptr = hdsk_dev.units + selectedDisk; if (doSeek()) { return CPM_ERROR; @@ -296,8 +296,9 @@ int32 doRead(void) { return CPM_OK; } -int32 doWrite(void) { +static int32 doWrite(void) { int32 i; + uint8 hdskbuf[HDSK_SECTOR_SIZE]; /* data buffer */ UNIT *uptr = hdsk_dev.units + selectedDisk; if (((uptr -> flags) & UNIT_HDSKWLK) == 0) { /* write enabled */ if (doSeek()) { @@ -324,7 +325,7 @@ int32 doWrite(void) { return CPM_OK; } -int32 hdsk_in(void) { +static int32 hdsk_in(const int32 port) { int32 result; if ((hdskCommandPosition == 6) && ((hdskLastCommand == hdsk_read) || (hdskLastCommand == hdsk_write))) { result = checkParameters() ? ((hdskLastCommand == hdsk_read) ? doRead() : doWrite()) : CPM_ERROR; @@ -333,12 +334,13 @@ int32 hdsk_in(void) { return result; } else if (hdsk_hasVerbose()) { - message3("Illegal IN command detected (cmd=%d, pos=%d).\n", hdskLastCommand, hdskCommandPosition); + message4("Illegal IN command detected (port=%03xh, cmd=%d, pos=%d).\n", + port, hdskLastCommand, hdskCommandPosition); } return CPM_OK; } -int32 hdsk_out(int32 data) { +static int32 hdsk_out(const int32 data) { switch(hdskLastCommand) { case hdsk_read: case hdsk_write: @@ -379,6 +381,6 @@ int32 hdsk_out(int32 data) { return 0; /* ignored, since OUT */ } -int32 hdsk_io(int32 port, int32 io, int32 data) { - return io == 0 ? hdsk_in() : hdsk_out(data); +int32 hdsk_io(const int32 port, const int32 io, const int32 data) { + return io == 0 ? hdsk_in(port) : hdsk_out(data); } diff --git a/GRI/gri_cpu.c b/GRI/gri_cpu.c index 8113b3f3..f6166100 100644 --- a/GRI/gri_cpu.c +++ b/GRI/gri_cpu.c @@ -1,6 +1,6 @@ /* gri_cpu.c: GRI-909 CPU simulator - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,10 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + cpu GRI-909 CPU + + 14-Mar-03 RMS Fixed bug in SC queue tracking + The system state for the GRI-909 is: AX<0:15> arithmetic input @@ -167,6 +171,7 @@ uint32 stop_opr = 1; /* stop ill operator */ int16 scq[SCQ_SIZE] = { 0 }; /* PC queue */ int32 scq_p = 0; /* PC queue ptr */ REG *scq_r = NULL; /* PC queue reg ptr */ + extern int32 sim_interval; extern int32 sim_int_char; extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ @@ -340,7 +345,7 @@ REG cpu_reg[] = { { FLDATA (ION, dev_done, INT_V_ON) }, { FLDATA (INODEF, dev_done, INT_V_NODEF) }, { FLDATA (BKP, bkp, 0) }, - { BRDATA (SCQ, scq, 8, 15, SCQ_SIZE), REG_RO+REG_CIRC }, + { BRDATA (SCQ, scq, 8, 15, SCQ_SIZE), REG_RO + REG_CIRC }, { ORDATA (SCQP, scq_p, 6), REG_HRO }, { FLDATA (STOP_OPR, stop_opr, 0) }, { ORDATA (WRU, sim_int_char, 8) }, @@ -475,7 +480,7 @@ else if ((src != U_MEM) && (dst != U_MEM)) { /* reg-reg? */ /* Memory reference. The second SC increment occurs after the first execution cycle. For direct, defer, and immediate defer, this is after the first memory read and before the bus transfer; but for - immediate, it is before the bus transfer. + immediate, it is after the bus transfer. */ else { SC = (SC + 1) & AMASK; /* incr SC */ @@ -512,6 +517,7 @@ else { SC = (SC + 1) & AMASK; /* incr SC */ /* Simulation halted */ AO = ao_update (); /* update AO */ +scq_r->qptr = scq_p; /* update sc q ptr */ return reason; } @@ -871,7 +877,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) return SCPE_ARG; diff --git a/GRI/gri_defs.h b/GRI/gri_defs.h index f74c96cb..2888bed1 100644 --- a/GRI/gri_defs.h +++ b/GRI/gri_defs.h @@ -1,6 +1,6 @@ /* gri_defs.h: GRI-909 simulator definitions - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 25-Apr-03 RMS Revised for extended file support 19-Sep-02 RMS Fixed declarations in gdev structure There are several discrepancies between the original GRI-909 Reference @@ -65,7 +66,7 @@ #define MAXMEMSIZE 32768 /* max memory size */ #define AMASK 077777 /* logical addr mask */ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) /* Architectural constants */ diff --git a/GRI/gri_doc.txt b/GRI/gri_doc.txt index dcbd7b44..aeab0072 100644 --- a/GRI/gri_doc.txt +++ b/GRI/gri_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: GRI-909 Simulator Usage -Date: 15-Nov-2002 +Date: 20-Apr-2003 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2002, written by Robert M Supnik - Copyright (c) 1993-2002, Robert M Supnik + Original code published in 1993-2003, written by Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -103,7 +103,7 @@ control registers for the interrupt system. name size comments - SC 14 sequence counter + SC 15 sequence counter AX 16 arithmetic operator input register 1 AY 16 arithmetic operator input register 2 AO 16 arithmetic operator output register @@ -126,7 +126,7 @@ control registers for the interrupt system. ION 1 interrupts enabled INODEF 1 interrupts not deferred BKP 1 breakpoint request - SCQ[0:63] 16 SC prior to last jump or interrupt; + SCQ[0:63] 15 SC prior to last jump or interrupt; most recent SC change first STOP_OPR 1 stop on undefined operator WRU 8 interrupt character @@ -136,8 +136,8 @@ control registers for the interrupt system. 2.2.1 S42-004 High Speed Reader (HSR) The paper tape reader (HSR) reads data from or a disk file. The POS -register specifies the number of the next data item to be read. Thus, -by changing POS, the user can backspace or advance the reader. +register specifies the number of the next data item to be read. +Thus, by changing POS, the user can backspace or advance the reader. The paper tape reader implements these registers: diff --git a/GRI/gri_stddev.c b/GRI/gri_stddev.c index f30b429f..425a8b7b 100644 --- a/GRI/gri_stddev.c +++ b/GRI/gri_stddev.c @@ -1,6 +1,6 @@ /* gri_stddev.c: GRI-909 standard devices - Copyright (c) 2001-2002, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -29,6 +29,7 @@ hsp S42-006 high speed punch rtc real time clock + 25-Apr-03 RMS Revised for extended file support 22-Dec-02 RMS Added break support 01-Nov-02 RMS Added 7b/8B support to terminal */ @@ -73,7 +74,7 @@ REG tti_reg[] = { { ORDATA (BUF, tti_unit.buf, 8) }, { FLDATA (IRDY, dev_done, INT_V_TTI) }, { FLDATA (IENB, ISR, INT_V_TTI) }, - { DRDATA (POS, tti_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { FLDATA (UC, tti_unit.flags, UNIT_V_KSR), REG_HRO }, { NULL } }; @@ -103,7 +104,7 @@ REG tto_reg[] = { { ORDATA (BUF, tto_unit.buf, 8) }, { FLDATA (ORDY, dev_done, INT_V_TTO) }, { FLDATA (IENB, ISR, INT_V_TTO) }, - { DRDATA (POS, tto_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT }, { NULL } }; @@ -134,7 +135,7 @@ REG hsr_reg[] = { { ORDATA (BUF, hsr_unit.buf, 8) }, { FLDATA (IRDY, dev_done, INT_V_HSR) }, { FLDATA (IENB, ISR, INT_V_HSR) }, - { DRDATA (POS, hsr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, hsr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, hsr_unit.wait, 24), REG_NZ + PV_LEFT }, { FLDATA (STOP_IOE, hsr_stopioe, 0) }, { NULL } }; @@ -159,7 +160,7 @@ REG hsp_reg[] = { { ORDATA (BUF, hsp_unit.buf, 8) }, { FLDATA (ORDY, dev_done, INT_V_HSP) }, { FLDATA (IENB, ISR, INT_V_HSP) }, - { DRDATA (POS, hsp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, hsp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, hsp_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, hsp_stopioe, 0) }, { NULL } }; @@ -223,7 +224,7 @@ return 0; /* Service routines */ -t_stat tti_svc (UNIT *uhsr) +t_stat tti_svc (UNIT *uptr) { int32 c; @@ -240,7 +241,7 @@ tti_unit.pos = tti_unit.pos + 1; return SCPE_OK; } -t_stat tto_svc (UNIT *uhsr) +t_stat tto_svc (UNIT *uptr) { int32 c; t_stat r; @@ -257,7 +258,7 @@ return SCPE_OK; /* Reset routines */ -t_stat tti_reset (DEVICE *dhsr) +t_stat tti_reset (DEVICE *dptr) { tti_unit.buf = 0; /* clear buffer */ dev_done = dev_done & ~INT_TTI; /* clear ready */ @@ -265,7 +266,7 @@ sim_activate (&tti_unit, tti_unit.wait); /* activate unit */ return SCPE_OK; } -t_stat tto_reset (DEVICE *dhsr) +t_stat tto_reset (DEVICE *dptr) { tto_unit.buf = 0; /* clear buffer */ dev_done = dev_done | INT_TTO; /* set ready */ @@ -310,7 +311,7 @@ if (((op & PT_IRDY) && (dev_done & INT_HSR)) || return 0; } -t_stat hsr_svc (UNIT *uhsr) +t_stat hsr_svc (UNIT *uptr) { int32 temp; @@ -329,7 +330,7 @@ hsr_unit.pos = hsr_unit.pos + 1; return SCPE_OK; } -t_stat hsp_svc (UNIT *uhsr) +t_stat hsp_svc (UNIT *uptr) { dev_done = dev_done | INT_HSP; /* set ready */ if ((hsp_unit.flags & UNIT_ATT) == 0) /* attached? */ @@ -344,7 +345,7 @@ return SCPE_OK; /* Reset routines */ -t_stat hsr_reset (DEVICE *dhsr) +t_stat hsr_reset (DEVICE *dptr) { hsr_unit.buf = 0; /* clear buffer */ dev_done = dev_done & ~INT_HSR; /* clear ready */ @@ -352,7 +353,7 @@ sim_cancel (&hsr_unit); /* deactivate unit */ return SCPE_OK; } -t_stat hsp_reset (DEVICE *dhsr) +t_stat hsp_reset (DEVICE *dptr) { hsp_unit.buf = 0; /* clear buffer */ dev_done = dev_done | INT_HSP; /* set ready */ @@ -377,7 +378,7 @@ if ((op & RTC_OV) && (dev_done & INT_RTC)) return 1; return 0; } -t_stat rtc_svc (UNIT *uhsr) +t_stat rtc_svc (UNIT *uptr) { M[RTC_CTR] = (M[RTC_CTR] + 1) & DMASK; /* incr counter */ if (M[RTC_CTR] == 0) dev_done = dev_done | INT_RTC; /* ovflo? set ready */ @@ -385,7 +386,7 @@ sim_activate (&rtc_unit, sim_rtc_calb (rtc_tps)); /* reactivate */ return SCPE_OK; } -t_stat rtc_reset (DEVICE *dhsr) +t_stat rtc_reset (DEVICE *dptr) { dev_done = dev_done & ~INT_RTC; /* clear ready */ sim_cancel (&rtc_unit); /* stop clock */ diff --git a/GRI/gri_sys.c b/GRI/gri_sys.c index 8280bac2..6bde9909 100644 --- a/GRI/gri_sys.c +++ b/GRI/gri_sys.c @@ -1,6 +1,6 @@ /* gri_sys.c: GRI-909 simulator interface - Copyright (c) 2001-2002, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -80,7 +80,8 @@ const char *sim_stop_messages[] = { t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) { -int32 c, org; +int32 c; +uint32 org; t_stat r; char gbuf[CBUFSIZE]; @@ -114,7 +115,7 @@ return SCPE_OK; /* Symbol tables */ -#define F_V_FL 16 +#define F_V_FL 16 /* class flag */ #define F_M_FL 017 #define F_V_FO 000 /* function out */ #define F_V_FOI 001 /* FO, impl reg */ diff --git a/H316/h316_cpu.c b/H316/h316_cpu.c index e520e329..202f126b 100644 --- a/H316/h316_cpu.c +++ b/H316/h316_cpu.c @@ -1,6 +1,6 @@ /* h316_cpu.c: Honeywell 316/516 CPU simulator - Copyright (c) 1999-2002, Robert M. Supnik + Copyright (c) 1999-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -195,7 +195,7 @@ #define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = PC #define PCQ_TOP pcq[pcq_p] #define UNIT_V_MSIZE (UNIT_V_UF) /* dummy mask */ -#define UNIT_MSIZE (1 << UNIT_V_MSIZE) +#define UNIT_MSIZE (1u << UNIT_V_MSIZE) #define m7 0001000 /* for generics */ #define m8 0000400 #define m9 0000200 @@ -229,17 +229,20 @@ int32 pcq_p = 0; /* PC queue ptr */ REG *pcq_r = NULL; /* PC queue reg ptr */ int32 dlog = 0; /* debug log */ int32 turnoff = 0; + extern int32 sim_int_char; +extern int32 sim_interval; extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern FILE *sim_log; -extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, - UNIT *uptr, int32 sw); 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_noext (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); + +extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, + UNIT *uptr, int32 sw); /* CPU data structures @@ -276,7 +279,7 @@ REG cpu_reg[] = { { FLDATA (STOP_INST, stop_inst, 0) }, { FLDATA (STOP_DEV, stop_dev, 1) }, { DRDATA (INDMAX, ind_max, 8), REG_NZ + PV_LEFT }, - { BRDATA (PCQ, pcq, 8, 15, PCQ_SIZE), REG_RO+REG_CIRC }, + { BRDATA (PCQ, pcq, 8, 15, PCQ_SIZE), REG_RO + REG_CIRC }, { ORDATA (PCQP, pcq_p, 6), REG_HRO }, { ORDATA (WRU, sim_int_char, 8) }, { FLDATA (DLOG, dlog, 0), REG_HIDDEN }, @@ -323,10 +326,9 @@ int32 (*iotab[64])() = { t_stat sim_instr (void) { -extern int32 sim_interval; extern UNIT clk_unit; int32 AR, BR, MB, Y, t1, t2, t3, skip; -unsigned int32 ut; +uint32 ut; t_stat reason; t_stat Ea (int32 inst, int32 *addr); void Write (int32 val, int32 addr); @@ -377,6 +379,7 @@ else { if (sim_brk_summ && MB = Read (Y); /* fetch instr */ PC = NEWA (Y, Y + 1); /* incr PC */ dev_ready = dev_ready | INT_NODEF; } + sim_interval = sim_interval - 1; if (dlog && sim_log && !turnoff) { /* cycle log? */ int32 op = I_GETOP (MB) & 017; /* core opcode */ @@ -389,6 +392,7 @@ if (dlog && sim_log && !turnoff) { /* cycle log? */ /* Memory reference instructions */ switch (I_GETOP (MB)) { /* case on <1:6> */ + case 001: case 021: case 041: case 061: /* JMP */ if (reason = Ea (MB, &Y)) break; /* eff addr */ PCQ_ENTRY; /* save PC */ @@ -401,6 +405,7 @@ case 001: case 021: case 041: case 061: /* JMP */ else turnoff = 0; } /* no, log */ if (extoff_pending) ext = extoff_pending = 0; /* cond ext off */ break; + case 002: case 022: case 042: case 062: /* LDA */ if (reason = Ea (MB, &Y)) break; /* eff addr */ if (dp) { /* double prec? */ @@ -409,10 +414,12 @@ case 002: case 022: case 042: case 062: /* LDA */ sc = 0; } else AR = Read (Y); /* no, get word */ break; + case 003: case 023: case 043: case 063: /* ANA */ if (reason = Ea (MB, &Y)) break; /* eff addr */ AR = AR & Read (Y); break; + case 004: case 024: case 044: case 064: /* STA */ if (reason = Ea (MB, &Y)) break; /* eff addr */ if (dp) { /* double prec? */ @@ -421,10 +428,12 @@ case 004: case 024: case 044: case 064: /* STA */ sc = 0; } else Write (AR, Y); /* no, store word */ break; + case 005: case 025: case 045: case 065: /* ERA */ if (reason = Ea (MB, &Y)) break; /* eff addr */ AR = AR ^ Read (Y); break; + case 006: case 026: case 046: case 066: /* ADD */ if (reason = Ea (MB, &Y)) break; /* eff addr */ if (dp) { /* double prec? */ @@ -435,6 +444,7 @@ case 006: case 026: case 046: case 066: /* ADD */ sc = 0; } else AR = Add16 (AR, Read (Y)); /* no, 16b add */ break; + case 007: case 027: case 047: case 067: /* SUB */ if (reason = Ea (MB, &Y)) break; /* eff addr */ if (dp) { /* double prec? */ @@ -455,32 +465,38 @@ case 010: case 030: case 050: case 070: /* JST */ PCQ_ENTRY; PC = NEWA (PC, Y + 1); /* set new PC */ break; + case 011: case 031: case 051: case 071: /* CAS */ if (reason = Ea (MB, &Y)) break; /* eff addr */ MB = Read (Y); if (AR == MB) PC = NEWA (PC, PC + 1); else if (SEXT (AR) < SEXT (MB)) PC = NEWA (PC, PC + 2); break; + case 012: case 032: case 052: case 072: /* IRS */ if (reason = Ea (MB, &Y)) break; /* eff addr */ MB = (Read (Y) + 1) & DMASK; /* incr, rewrite */ Write (MB, Y); if (MB == 0) PC = NEWA (PC, PC + 1); /* skip if zero */ break; + case 013: case 033: case 053: case 073: /* IMA */ if (reason = Ea (MB, &Y)) break; /* eff addr */ MB = Read (Y); Write (AR, Y); /* A to mem */ AR = MB; /* mem to A */ break; + case 015: case 055: /* STX */ if (reason = Ea (MB & ~IDX, &Y)) break; /* eff addr */ Write (XR, Y); /* store XR */ break; + case 035: case 075: /* LDX */ if (reason = Ea (MB & ~IDX, &Y)) break; /* eff addr */ XR = Read (Y); /* load XR */ break; + case 016: case 036: case 056: case 076: /* MPY */ if (cpu_unit.flags & UNIT_HSA) { /* installed? */ if (reason = Ea (MB, &Y)) break; /* eff addr */ @@ -489,6 +505,7 @@ case 016: case 036: case 056: case 076: /* MPY */ sc = 0; } else reason = stop_inst; break; + case 017: case 037: case 057: case 077: /* DIV */ if (cpu_unit.flags & UNIT_HSA) { /* installed? */ if (reason = Ea (MB, &Y)) break; /* eff addr */ @@ -512,6 +529,7 @@ case 014: /* OCP */ reason = t2 >> IOT_V_REASON; turnoff = 0; break; + case 034: /* SKS */ t2 = iotab[MB & DEVMASK] (ioSKS, I_GETFNC (MB), AR); reason = t2 >> IOT_V_REASON; @@ -519,6 +537,7 @@ case 034: /* SKS */ PC = NEWA (PC, PC + 1); turnoff = 0; } break; + case 054: /* INA */ if (MB & INCLRA) AR = 0; t2 = iotab[MB & DEVMASK] (ioINA, I_GETFNC (MB), AR); @@ -528,6 +547,7 @@ case 054: /* INA */ turnoff = 0; } AR = t2 & DMASK; /* data */ break; + case 074: /* OTA */ t2 = iotab[MB & DEVMASK] (ioOTA, I_GETFNC (MB), AR); reason = t2 >> IOT_V_REASON; @@ -606,6 +626,7 @@ case 020: sc = 0; /* clear sc */ if ((t1 = (-MB) & SHFMASK) == 0) break; /* shift count */ switch (I_GETFNC (MB)) { /* case shift fnc */ + case 000: /* LRL */ if (t1 > 32) ut = 0; /* >32? all 0 */ else { @@ -614,6 +635,7 @@ case 020: ut = ut >> t1; } /* log right */ PUTDBL_U (ut); /* store A,B */ break; + case 001: /* LRS */ if (t1 > 31) t1 = 31; /* limit to 31 */ t2 = GETDBL_S (SEXT (AR), BR); /* get A'B signed */ @@ -621,6 +643,7 @@ case 020: t2 = t2 >> t1; /* arith right */ PUTDBL_S (t2); /* store A,B */ break; + case 002: /* LRR */ t2 = t1 % 32; /* mod 32 */ ut = GETDBL_U (AR, BR); /* get A'B */ @@ -628,6 +651,7 @@ case 020: C = (ut >> 31) & 1; /* C = A<1> */ PUTDBL_U (ut); /* store A,B */ break; + case 003: /* "long right arot" */ if (reason = stop_inst) break; /* stop on undef? */ for (t2 = 0; t2 < t1; t2++) { /* bit by bit */ @@ -636,22 +660,26 @@ case 020: ((BR & MMASK) >> 1); AR = ((AR & SIGN) | (C << 15)) | (AR >> 1); } break; + case 004: /* LGR */ if (t1 > 16) AR = 0; /* > 16? all 0 */ else { C = (AR >> (t1 - 1)) & 1; /* C = last out */ AR = (AR >> t1) & DMASK; } /* log right */ break; + case 005: /* ARS */ if (t1 > 16) t1 = 16; /* limit to 16 */ C = ((SEXT (AR)) >> (t1 - 1)) & 1; /* C = last out */ AR = ((SEXT (AR)) >> t1) & DMASK; /* arith right */ break; + case 006: /* ARR */ t2 = t1 % 16; /* mod 16 */ AR = ((AR >> t2) | (AR << (16 - t2))) & DMASK; C = (AR >> 15) & 1; /* C = A<1> */ break; + case 007: /* "short right arot" */ if (reason = stop_inst) break; /* stop on undef? */ for (t2 = 0; t2 < t1; t2++) { /* bit by bit */ @@ -669,6 +697,7 @@ case 020: ut = ut << t1; } /* log left */ PUTDBL_U (ut); /* store A,B */ break; + case 011: /* LLS */ if (t1 > 31) t1 = 31; /* limit to 31 */ t2 = GETDBL_S (SEXT (AR), BR); /* get A'B */ @@ -677,6 +706,7 @@ case 020: if ((t2 >> (31 - t1)) != /* shf out = sgn? */ ((AR & SIGN)? -1: 0)) C = 1; break; + case 012: /* LLR */ t2 = t1 % 32; /* mod 32 */ ut = GETDBL_U (AR, BR); /* get A'B */ @@ -684,6 +714,7 @@ case 020: C = ut & 1; /* C = B<16> */ PUTDBL_U (ut); /* store A,B */ break; + case 013: /* "long left arot" */ if (reason = stop_inst) break; /* stop on undef? */ for (t2 = 0; t2 < t1; t2++) { /* bit by bit */ @@ -693,12 +724,14 @@ case 020: if ((AR & SIGN) != ((AR >> 1) & SIGN)) C = 1; AR = AR & DMASK; } break; + case 014: /* LGL */ if (t1 > 16) AR = 0; /* > 16? all 0 */ else { C = (AR >> (16 - t1)) & 1; /* C = last out */ AR = (AR << t1) & DMASK; } /* log left */ break; + case 015: /* ALS */ if (t1 > 16) t1 = 16; /* limit to 16 */ t2 = SEXT (AR); /* save AR */ @@ -706,11 +739,13 @@ case 020: if ((t2 >> (16 - t1)) != /* shf out + sgn */ ((AR & SIGN)? -1: 0)) C = 1; break; + case 016: /* ALR */ t2 = t1 % 16; /* mod 16 */ AR = ((AR << t2) | (AR >> (16 - t2))) & DMASK; C = AR & 1; /* C = A<16> */ break; + case 017: /* "short left arot" */ if (reason = stop_inst) break; /* stop on undef? */ for (t2 = 0; t2 < t1; t2++) { /* bit by bit */ @@ -826,6 +861,7 @@ return; int32 Add16 (int32 v1, int32 v2) { int32 r = v1 + v2; + C = 0; if (((v1 ^ ~v2) & (v1 ^ r)) & SIGN) C = 1; return (r & DMASK); @@ -834,6 +870,7 @@ return (r & DMASK); int32 Add31 (int32 v1, int32 v2) { int32 r = v1 + v2; + C = 0; if (((v1 ^ ~v2) & (v1 ^ r)) & (1u << 30)) C = 1; return r; @@ -1037,7 +1074,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0) || (((cpu_unit.flags & UNIT_EXT) == 0) && (val > (NX_AMASK + 1)))) diff --git a/H316/h316_defs.h b/H316/h316_defs.h index cc2061bf..240174c2 100644 --- a/H316/h316_defs.h +++ b/H316/h316_defs.h @@ -1,6 +1,6 @@ /* h316_defs.h: Honeywell 316/516 simulator definitions - Copyright (c) 1999-2002, Robert M. Supnik + Copyright (c) 1999-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,8 @@ Except as contained in this notice, the name of Robert M Supnik shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + + 25-Apr-03 RMS Revised for extended file support */ #include "sim_defs.h" /* simulator defns */ @@ -40,7 +42,7 @@ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ #define X_AMASK (MAXMEMSIZE - 1) /* ext address mask */ #define NX_AMASK ((MAXMEMSIZE / 2) - 1) /* nx address mask */ -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) /* Architectural constants */ @@ -56,8 +58,8 @@ #define UNIT_V_EXT (UNIT_V_UF + 1) /* extended mem */ #define UNIT_V_HSA (UNIT_V_UF + 2) /* high speed arith */ -#define UNIT_EXT (1 << UNIT_V_EXT) -#define UNIT_HSA (1 << UNIT_V_HSA) +#define UNIT_EXT (1u << UNIT_V_EXT) +#define UNIT_HSA (1u << UNIT_V_HSA) /* Instruction format */ diff --git a/H316/h316_doc.txt b/H316/h316_doc.txt index e3dc3275..36080cf5 100644 --- a/H316/h316_doc.txt +++ b/H316/h316_doc.txt @@ -1,7 +1,7 @@ To: Users From: Bob Supnik Subj: H316 Simulator Usage -Date: 15-Mar-2003 +Date: 20-Apr-2003 COPYRIGHT NOTICE @@ -152,7 +152,7 @@ Error handling is as follows: 0 out of tape end of file 1 report error and stop - 0 out of tape or paper + 0 out of tape or paper OS I/O error x report error and stop diff --git a/H316/h316_lp.c b/H316/h316_lp.c index bf8370e5..7c17b74e 100644 --- a/H316/h316_lp.c +++ b/H316/h316_lp.c @@ -1,6 +1,6 @@ /* h316_lp.c: Honeywell 316/516 line printer - Copyright (c) 1999-2002, Robert M. Supnik + Copyright (c) 1999-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,34 +25,10 @@ lpt line printer + 25-Apr-03 RMS Revised for extended file support 30-May-02 RMS Widened POS to 32b -*/ -#include "h316_defs.h" -#define LPT_WIDTH 120 /* width */ -#define LPT_SCAN (LPT_WIDTH / 2) /* words/scan */ -#define LPT_DRUM 64 /* drum rows */ -#define LPT_SVCSH 01 /* shuttle */ -#define LPT_SVCPA 02 /* paper advance */ - -extern int32 dev_ready, dev_enable; -extern int32 stop_inst; -int32 lpt_wdpos = 0; /* word position */ -int32 lpt_drpos = 0; /* drum position */ -int32 lpt_crpos = 0; /* carriage position */ -int32 lpt_svcst = 0; /* service state */ -int32 lpt_svcch = 0; /* service channel */ -int32 lpt_xfer = 0; /* transfer flag */ -int32 lpt_prdn = 1; /* printing done */ -char lpt_buf[LPT_WIDTH + 1] = { 0 }; /* line buffer */ -int32 lpt_xtime = 5; /* transfer time */ -int32 lpt_etime = 50; /* end of scan time */ -int32 lpt_ptime = 5000; /* paper adv time */ -int32 lpt_stopioe = 0; /* stop on error */ -t_stat lpt_svc (UNIT *uptr); -t_stat lpt_reset (DEVICE *dptr); - -/* The Series 16 line printer is an unbuffered Analex shuttle printer. + The Series 16 line printer is an unbuffered Analex shuttle printer. Because it was unbuffered, the CPU had to scan out an entire line's worth of characters (60 words) for every character on the print drum (64 characters). Because it was a shuttle printer, the entire @@ -81,8 +57,36 @@ t_stat lpt_reset (DEVICE *dptr); lpt_svcch channel for paper advance (0 = no adv) lpt_xfer transfer ready flag lpt_prdn printing done flag +*/ - LPT data structures +#include "h316_defs.h" + +#define LPT_WIDTH 120 /* width */ +#define LPT_SCAN (LPT_WIDTH / 2) /* words/scan */ +#define LPT_DRUM 64 /* drum rows */ +#define LPT_SVCSH 01 /* shuttle */ +#define LPT_SVCPA 02 /* paper advance */ + +extern int32 dev_ready, dev_enable; +extern int32 stop_inst; + +int32 lpt_wdpos = 0; /* word position */ +int32 lpt_drpos = 0; /* drum position */ +int32 lpt_crpos = 0; /* carriage position */ +int32 lpt_svcst = 0; /* service state */ +int32 lpt_svcch = 0; /* service channel */ +int32 lpt_xfer = 0; /* transfer flag */ +int32 lpt_prdn = 1; /* printing done */ +char lpt_buf[LPT_WIDTH + 1] = { 0 }; /* line buffer */ +int32 lpt_xtime = 5; /* transfer time */ +int32 lpt_etime = 50; /* end of scan time */ +int32 lpt_ptime = 5000; /* paper adv time */ +int32 lpt_stopioe = 0; /* stop on error */ + +t_stat lpt_svc (UNIT *uptr); +t_stat lpt_reset (DEVICE *dptr); + +/* LPT data structures lpt_dev LPT device descriptor lpt_unit LPT unit descriptor @@ -103,7 +107,7 @@ REG lpt_reg[] = { { ORDATA (SVCST, lpt_svcst, 2) }, { ORDATA (SVCCH, lpt_svcch, 2) }, { BRDATA (BUF, lpt_buf, 8, 8, 120) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (XTIME, lpt_xtime, 24), PV_LEFT }, { DRDATA (ETIME, lpt_etime, 24), PV_LEFT }, { DRDATA (PTIME, lpt_ptime, 24), PV_LEFT }, @@ -115,7 +119,6 @@ DEVICE lpt_dev = { 1, 10, 31, 1, 8, 8, NULL, NULL, &lpt_reset, NULL, NULL, NULL }; - /* IO routine */ @@ -127,7 +130,7 @@ switch (inst) { /* case on opcode */ case ioOCP: /* OCP */ switch (fnc) { /* case on fnc */ case 000: case 002: case 004: /* paper adv */ - lpt_svcst = lpt_svcst | LPT_SVCPA; /* set state */ + lpt_svcst = lpt_svcst | LPT_SVCPA; /* set state */ lpt_svcch = fnc >> 1; /* save channel */ sim_activate (&lpt_unit, lpt_ptime); CLR_READY (INT_LPT); /* clear int */ @@ -141,6 +144,7 @@ case ioOCP: /* OCP */ default: return IOBADFNC (dat); } break; + case ioSKS: /* SKS */ switch (fnc) { /* case on fnc */ case 000: /* if xfer rdy */ @@ -180,6 +184,7 @@ case ioSKS: /* SKS */ default: return IOBADFNC (dat); } break; + case ioOTA: /* OTA */ if (fnc) return IOBADFNC (dat); /* only fnc 0 */ if (lpt_xfer) { /* xfer ready? */ diff --git a/H316/h316_stddev.c b/H316/h316_stddev.c index 72161164..2ff32fbe 100644 --- a/H316/h316_stddev.c +++ b/H316/h316_stddev.c @@ -28,6 +28,7 @@ tty 316/516-33 teleprinter clk/options 316/516-12 real time clocks/internal options + 25-Apr-03 RMS Revised for extended file support 01-Mar-03 RMS Added SET/SHOW CLK FREQ support 22-Dec-02 RMS Added break support 01-Nov-02 RMS Added 7b/8b support to terminal @@ -87,7 +88,7 @@ REG ptr_reg[] = { { ORDATA (BUF, ptr_unit.buf, 8) }, { FLDATA (READY, dev_ready, INT_V_PTR) }, { FLDATA (ENABLE, dev_enable, INT_V_PTR) }, - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptr_stopioe, 0) }, { NULL } }; @@ -114,7 +115,7 @@ REG ptp_reg[] = { { FLDATA (READY, dev_ready, INT_V_PTP) }, { FLDATA (ENABLE, dev_enable, INT_V_PTP) }, { FLDATA (POWER, ptp_power, 0) }, - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, { DRDATA (PWRTIME, ptp_ptime, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptp_stopioe, 0) }, @@ -147,9 +148,9 @@ REG tty_reg[] = { { FLDATA (MODE, tty_mode, 0) }, { FLDATA (READY, dev_ready, INT_V_TTY) }, { FLDATA (ENABLE, dev_enable, INT_V_TTY) }, - { DRDATA (KPOS, tty_unit[TTI].pos, 32), PV_LEFT }, + { DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT }, { DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT }, - { DRDATA (TPOS, tty_unit[TTO].pos, 32), PV_LEFT }, + { DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT }, { DRDATA (TTIME, tty_unit[TTO].wait, 24), REG_NZ + PV_LEFT }, { NULL } }; @@ -164,7 +165,7 @@ DEVICE tty_dev = { 2, 10, 31, 1, 8, 8, NULL, NULL, &tty_reset, NULL, NULL, NULL }; - + /* CLK data structures clk_dev CLK device descriptor diff --git a/H316/h316_sys.c b/H316/h316_sys.c index 283a66e1..a280d4a1 100644 --- a/H316/h316_sys.c +++ b/H316/h316_sys.c @@ -1,6 +1,6 @@ /* h316_sys.c: Honeywell 316/516 simulator interface - Copyright (c) 1999-2002, Robert M Supnik + Copyright (c) 1999-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/HP2100/hp2100_cpu.c b/HP2100/hp2100_cpu.c index ea33b049..b28972c4 100644 --- a/HP2100/hp2100_cpu.c +++ b/HP2100/hp2100_cpu.c @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 12-Mar-03 RMS Added logical name support 02-Feb-03 RMS Fixed last cycle bug in DMA output (found by Mike Gemeny) 22-Nov-02 RMS Added 21MX IOP support 24-Oct-02 RMS Fixed bugs in IOP and extended instructions @@ -2493,7 +2494,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > PASIZE) || ((val & 07777) != 0) || (!(uptr->flags & UNIT_21MX) && (val > 32768))) @@ -2567,9 +2568,11 @@ for (i = 0; cdptr = sim_devices[i]; i++) { dibp = (DIB *) dptr->ctxt; if (dibp && !(dptr->flags & DEV_DIS) && (chkp != dibp) && (dno == dibp->devno)) { - printf ("%s device number conflict, devno = %d\n", dptr->name, dno); + printf ("%s device number conflict, devno = %d\n", + sim_dname (dptr), dno); if (sim_log) fprintf (sim_log, - "%s device number conflict, devno = %d\n", dptr->name, dno); + "%s device number conflict, devno = %d\n", + sim_dname (dptr), dno); return TRUE; } } } } return FALSE; } diff --git a/HP2100/hp2100_defs.h b/HP2100/hp2100_defs.h index 660a0a18..3c7940df 100644 --- a/HP2100/hp2100_defs.h +++ b/HP2100/hp2100_defs.h @@ -1,6 +1,6 @@ /* hp2100_defs.h: HP 2100 simulator definitions - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 25-Apr-03 RMS Revised for extended file support 24-Oct-02 RMS Added indirect address interrupt 08-Feb-02 RMS Added DMS definitions 01-Feb-02 RMS Added terminal multiplexor support @@ -52,7 +53,7 @@ /* Memory */ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) #define VA_N_SIZE 15 /* virtual addr size */ #define VASIZE (1 << VA_N_SIZE) #define VAMASK (VASIZE - 1) /* virt addr mask */ diff --git a/HP2100/hp2100_dp.c b/HP2100/hp2100_dp.c index 5187f9f3..64a7ad0b 100644 --- a/HP2100/hp2100_dp.c +++ b/HP2100/hp2100_dp.c @@ -1,6 +1,6 @@ /* hp2100_dp.c: HP 2100 12557A/13210A disk simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,8 @@ dp 12557A 2871 disk subsystem 13210A 7900 disk subsystem + 25-Apr-03 RMS Revised for extended file support + Fixed bug(s) in boot (found by Terry Newton) 10-Nov-02 RMS Added BOOT command, fixed numerous bugs 15-Jan-02 RMS Fixed INIT handling (found by Bill McDermith) 10-Jan-02 RMS Fixed f(x)write call (found by Bill McDermith) @@ -239,7 +241,7 @@ REG dpc_reg[] = { DP_NUMDRV, PV_LEFT | REG_HRO) }, { URDATA (UFNC, dpc_unit[0].FNC, 8, 8, 0, DP_NUMDRV, REG_HRO) }, - { URDATA (CAPAC, dpc_unit[0].capac, 10, 31, 0, + { URDATA (CAPAC, dpc_unit[0].capac, 10, T_ADDR_W, 0, DP_NUMDRV, PV_LEFT | REG_HRO) }, { ORDATA (DEVNO, dpc_dib.devno, 6), REG_HRO }, { NULL } }; @@ -311,6 +313,7 @@ return dat; int32 dpcio (int32 inst, int32 IR, int32 dat) { int32 i, devc, fnc, drv; +int32 devd = dpd_dib.devno; devc = IR & I_DEVMASK; /* get device no */ switch (inst) { /* case on opcode */ @@ -340,22 +343,25 @@ case ioCTL: /* control clear/set */ sim_cancel (&dpd_unit); /* cancel dch */ dpd_xfer = 0; /* clr dch xfer */ dpc_busy = 0; } /* clr cch busy */ - else if (!CTL (devc)) { /* set and was clr? */ + else { /* STC */ setCTL (devc); /* set ctl */ - setCMD (devc); /* set cmd */ - drv = CW_GETDRV (dpc_obuf); /* get fnc, drv */ - fnc = CW_GETFNC (dpc_obuf); /* from cmd word */ - switch (fnc) { /* case on fnc */ - case FNC_SEEK: case FNC_CHK: /* seek, check */ - case FNC_STA: case FNC_AR: /* rd sta, addr rec */ - dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */ - break; - case FNC_RD: case FNC_WD: /* read, write */ - case FNC_REF: case FNC_INIT: /* refine, init */ - dp_goc (fnc, drv, dpc_ctime); /* sched drive */ - break; - } /* end case */ - } /* end else */ + if (!CMD (devc)) { /* is cmd clr? */ + setCMD (devc); /* set cmd */ + drv = CW_GETDRV (dpc_obuf); /* get fnc, drv */ + fnc = CW_GETFNC (dpc_obuf); /* from cmd word */ + switch (fnc) { /* case on fnc */ + case FNC_STA: /* rd sta */ + if (dp_ctype) { clrFLG (devd); } /* 13210? clr dch flag */ + case FNC_SEEK: case FNC_CHK: /* seek, check */ + case FNC_AR: /* addr rec */ + dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */ + break; + case FNC_RD: case FNC_WD: /* read, write */ + case FNC_REF: case FNC_INIT: /* refine, init */ + dp_goc (fnc, drv, dpc_ctime); /* sched drive */ + break; } /* end case */ + } + } /* end else */ break; default: break; } @@ -469,7 +475,7 @@ case FNC_AR1: /* arec, need hd/sec */ break; case FNC_STA: /* read status */ - if (CMD (devd)) { /* dch active? */ + if (CMD (devd) || dp_ctype) { /* dch act or 13210? */ if (dpc_unit[drv].flags & UNIT_ATT) { /* attached? */ dpd_ibuf = dpc_sta[drv] & ~STA_ERR; /* clear err */ if (dp_ctype) dpd_ibuf = /* 13210? */ @@ -480,6 +486,7 @@ case FNC_STA: /* read status */ dpd_ibuf = dpd_ibuf | STA_ERR; setFLG (devd); /* set dch flg */ clrCMD (devd); /* clr dch cmd */ + clrCMD (devc); /* clr cch cmd */ dpc_sta[drv] = dpc_sta[drv] & /* clr sta flags */ ~(STA_ATN | STA_1ST | STA_OVR | STA_RWU | STA_ACU | STA_EOC | @@ -545,7 +552,9 @@ case FNC_SEEK3: /* waiting for flag */ if (dpc_busy || FLG (devc)) { /* ctrl busy? wait */ uptr->FNC = FNC_SEEK3; /* next state */ sim_activate (uptr, dpc_xtime); } - else setFLG (devc); /* set cch flg */ + else { + setFLG (devc); /* set cch flg */ + clrCMD (devc); } /* clear cmd */ return SCPE_OK; case FNC_REF: /* refine sector */ diff --git a/HP2100/hp2100_dq.c b/HP2100/hp2100_dq.c index b40e54cd..47edee33 100644 --- a/HP2100/hp2100_dq.c +++ b/HP2100/hp2100_dq.c @@ -1,6 +1,6 @@ /* hp2100_dq.c: HP 2100 12565A disk simulator - Copyright (c) 1993-2002, Bill McDermith + Copyright (c) 1993-2003, Bill McDermith Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ dq 12565A 2883 disk system + 25-Apr-03 RMS Fixed bug in status check 10-Nov-02 RMS Added boot command, rebuilt like 12559/13210 09-Jan-02 WOM Copied dp driver and mods for 2883 @@ -303,25 +304,26 @@ case ioCTL: /* control clear/set */ sim_cancel (&dqd_unit); /* cancel dch */ dqd_xfer = 0; /* clr dch xfer */ dqc_busy = 0; } /* clr busy */ - else if (!CTL (devc)) { /* set and was clr? */ - setCMD (devc); /* set cmd, ctl */ - setCTL (devc); - drv = CW_GETDRV (dqc_obuf); /* get fnc, drv */ - fnc = CW_GETFNC (dqc_obuf); /* from cmd word */ - switch (fnc) { /* case on fnc */ - case FNC_SEEK: case FNC_RCL: /* seek, recal */ - case FNC_CHK: /* check */ - dqc_sta[drv] = 0; /* clear status */ - case FNC_STA: case FNC_LA: /* rd sta, load addr */ - dq_god (fnc, drv, dqc_dtime); /* sched dch xfer */ - break; - case FNC_RD: case FNC_WD: /* read, write */ - case FNC_RA: case FNC_WA: /* rd addr, wr addr */ - case FNC_AS: /* address skip */ - dq_goc (fnc, drv, dqc_ctime); /* sched drive */ - break; - } /* end case */ - } /* end else */ + else { /* STC */ + setCTL (devc); /* set ctl */ + if (!CMD (devc)) { /* cmd clr? */ + setCMD (devc); /* set cmd, ctl */ + drv = CW_GETDRV (dqc_obuf); /* get fnc, drv */ + fnc = CW_GETFNC (dqc_obuf); /* from cmd word */ + switch (fnc) { /* case on fnc */ + case FNC_SEEK: case FNC_RCL: /* seek, recal */ + case FNC_CHK: /* check */ + dqc_sta[drv] = 0; /* clear status */ + case FNC_STA: case FNC_LA: /* rd sta, load addr */ + dq_god (fnc, drv, dqc_dtime); /* sched dch xfer */ + break; + case FNC_RD: case FNC_WD: /* read, write */ + case FNC_RA: case FNC_WA: /* rd addr, wr addr */ + case FNC_AS: /* address skip */ + dq_goc (fnc, drv, dqc_ctime); /* sched drive */ + break; } /* end case */ + } /* end if !CMD */ + } /* end else */ break; default: break; } @@ -451,6 +453,7 @@ case FNC_STA: /* read status */ if (drv) dqd_ibuf = dqd_ibuf | STA_DID; setFLG (devd); /* set dch flg */ clrCMD (devd); /* clr dch cmd */ + clrCMD (devc); /* clr cch cmd */ dqc_sta[drv] = dqc_sta[drv] & /* clr sta flags */ ~(STA_DTE | STA_FLG | STA_AER | STA_EOC | STA_ERR); } diff --git a/HP2100/hp2100_dr.c b/HP2100/hp2100_dr.c index c472f00a..b913b363 100644 --- a/HP2100/hp2100_dr.c +++ b/HP2100/hp2100_dr.c @@ -1,6 +1,6 @@ /* hp2100_dr.c: HP 2100 12606B/12610B fixed head disk/drum simulator - Copyright (c) 1993-2000, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -284,7 +284,7 @@ da = ((trk * DR_NUMSC) + sec) * DR_NUMWD; if (drc_cw & CW_WR) { /* write? */ if ((da < uptr->capac) && (sec < DR_NUMSC)) { *(((uint16 *) uptr->filebuf) + da + drd_ptr) = drd_obuf; - if (((t_addr) (da + drd_ptr)) >= uptr->hwmark) + if (((uint32) (da + drd_ptr)) >= uptr->hwmark) uptr->hwmark = da + drd_ptr + 1; } drd_ptr = dr_incda (trk, sec, drd_ptr); /* inc disk addr */ if (CMD (devd)) { /* dch active? */ diff --git a/HP2100/hp2100_fp.c b/HP2100/hp2100_fp.c index 8e552c60..8a9ce4b2 100644 --- a/HP2100/hp2100_fp.c +++ b/HP2100/hp2100_fp.c @@ -1,6 +1,6 @@ /* hp2100_fp.c: HP 2100 floating point instructions - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/HP2100/hp2100_ipl.c b/HP2100/hp2100_ipl.c index e5c95cb1..ede40ccf 100644 --- a/HP2100/hp2100_ipl.c +++ b/HP2100/hp2100_ipl.c @@ -25,6 +25,7 @@ ipli, iplo 12556B interprocessor link pair + 09-May-03 RMS Added network device flag 31-Jan-03 RMS Links are full duplex (found by Mike Gemeny) */ @@ -113,7 +114,7 @@ DEVICE ipli_dev = { 1, 10, 31, 1, 16, 16, &tmxr_ex, &tmxr_dep, &ipl_reset, &ipl_boot, &ipl_attach, &ipl_detach, - &ipli_dib, DEV_DISABLE | DEV_DIS }; + &ipli_dib, DEV_NET | DEV_DISABLE | DEV_DIS }; /* IPLO data structures @@ -139,7 +140,7 @@ DEVICE iplo_dev = { 1, 10, 31, 1, 16, 16, &tmxr_ex, &tmxr_dep, &ipl_reset, &ipl_boot, &ipl_attach, &ipl_detach, - &iplo_dib, DEV_DISABLE | DEV_DIS }; + &iplo_dib, DEV_NET | DEV_DISABLE | DEV_DIS }; /* Interprocessor link I/O routines */ diff --git a/HP2100/hp2100_lps.c b/HP2100/hp2100_lps.c index 7820981b..cca3e6ed 100644 --- a/HP2100/hp2100_lps.c +++ b/HP2100/hp2100_lps.c @@ -1,6 +1,6 @@ /* hp2100_lps.c: HP 2100 12653A line printer simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,7 @@ lps 12653A 2767 line printer (based on 12556B microcircuit interface) + 25-Apr-03 RMS Revised for extended file support 24-Oct-02 RMS Added microcircuit test features 30-May-02 RMS Widened POS to 32b 03-Dec-01 RMS Changed DEVNO to use extended SET/SHOW @@ -72,7 +73,7 @@ REG lps_reg[] = { { FLDATA (CTL, lps_dib.ctl, 0) }, { FLDATA (FLG, lps_dib.flg, 0) }, { FLDATA (FBF, lps_dib.fbf, 0) }, - { DRDATA (POS, lps_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lps_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (CTIME, lps_ctime, 31), PV_LEFT }, { DRDATA (PTIME, lps_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lps_stopioe, 0) }, @@ -159,7 +160,7 @@ if (fputc (c, lps_unit.fileref) == EOF) { perror ("LPS I/O error"); clearerr (lps_unit.fileref); return SCPE_IOERR; } -lps_unit.pos = ftell (lps_unit.fileref); /* update pos */ +lps_unit.pos = lps_unit.pos + 1; /* update pos */ return SCPE_OK; } diff --git a/HP2100/hp2100_lpt.c b/HP2100/hp2100_lpt.c index e75087b8..bd7bba70 100644 --- a/HP2100/hp2100_lpt.c +++ b/HP2100/hp2100_lpt.c @@ -1,6 +1,6 @@ /* hp2100_lpt.c: HP 2100 12845A line printer simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ lpt 12845A line printer + 25-Apr-03 RMS Revised for extended file support 24-Oct-02 RMS Cloned from 12653A */ @@ -74,7 +75,7 @@ REG lpt_reg[] = { { FLDATA (FLG, lpt_dib.flg, 0) }, { FLDATA (FBF, lpt_dib.fbf, 0) }, { DRDATA (LCNT, lpt_lcnt, 7) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (CTIME, lpt_ctime, 31), PV_LEFT }, { DRDATA (PTIME, lpt_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lpt_stopioe, 0) }, diff --git a/HP2100/hp2100_ms.c b/HP2100/hp2100_ms.c index 9436d260..e607cc88 100644 --- a/HP2100/hp2100_ms.c +++ b/HP2100/hp2100_ms.c @@ -1,6 +1,6 @@ /* hp2100_ms.c: HP 2100 13181A/13183A magnetic tape simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,9 @@ ms 13181A 7970B 800bpi nine track magnetic tape 13183A 7970E 1600bpi nine track magnetic tape + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support + 28-Feb-03 RMS Revised for magtape library 18-Oct-02 RMS Added BOOT command, added 13183A support 30-Sep-02 RMS Revamped error handling 29-Aug-02 RMS Added end of medium support @@ -200,7 +203,7 @@ REG msc_reg[] = { { FLDATA (CTL, msc_dib.ctl, 0) }, { FLDATA (FLG, msc_dib.flg, 0) }, { FLDATA (FBF, msc_dib.fbf, 0) }, - { URDATA (POS, msc_unit[0].pos, 10, 32, 0, MS_NUMDR, PV_LEFT) }, + { URDATA (POS, msc_unit[0].pos, 10, T_ADDR_W, 0, MS_NUMDR, PV_LEFT) }, { URDATA (FNC, msc_unit[0].FNC, 8, 8, 0, MS_NUMDR, REG_HRO) }, { URDATA (UST, msc_unit[0].UST, 8, 12, 0, MS_NUMDR, REG_HRO) }, { DRDATA (CTIME, msc_ctime, 24), REG_NZ + PV_LEFT }, @@ -215,6 +218,8 @@ REG msc_reg[] = { MTAB msc_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { MTAB_XTD | MTAB_VDV, 0, NULL, "13181A", &ms_settype, NULL, NULL }, { MTAB_XTD | MTAB_VDV, 1, NULL, "13183A", diff --git a/HP2100/hp2100_mt.c b/HP2100/hp2100_mt.c index 7ec655eb..320dc7ee 100644 --- a/HP2100/hp2100_mt.c +++ b/HP2100/hp2100_mt.c @@ -25,6 +25,8 @@ mt 12559A 3030 nine track magnetic tape + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support 28-Feb-03 RMS Revised for magtape library 30-Sep-02 RMS Revamped error handling 28-Aug-02 RMS Added end of medium support @@ -138,6 +140,8 @@ REG mtd_reg[] = { MTAB mtd_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO", &hp_setdev, &hp_showdev, &mtd_dev }, { 0 } }; @@ -169,7 +173,7 @@ REG mtc_reg[] = { { FLDATA (FBF, mtc_dib.fbf, 0) }, { FLDATA (DTF, mtc_dtf, 0) }, { FLDATA (FSVC, mtc_1st, 0) }, - { DRDATA (POS, mtc_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, mtc_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (CTIME, mtc_ctime, 24), REG_NZ + PV_LEFT }, { DRDATA (GTIME, mtc_gtime, 24), REG_NZ + PV_LEFT }, { DRDATA (XTIME, mtc_xtime, 24), REG_NZ + PV_LEFT }, diff --git a/HP2100/hp2100_mux.c b/HP2100/hp2100_mux.c index 887f2ba1..0d0bb4d3 100644 --- a/HP2100/hp2100_mux.c +++ b/HP2100/hp2100_mux.c @@ -1,6 +1,6 @@ /* hp2100_mux.c: HP 2100 12920A terminal multiplexor simulator - Copyright (c) 2002, Robert M Supnik + Copyright (c) 2002-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ mux,muxl,muxc 12920A terminal multiplexor + 09-May-03 RMS Added network device flag 01-Nov-02 RMS Added 7B/8B support 22-Aug-02 RMS Updated for changes to sim_tmxr @@ -231,7 +232,7 @@ DEVICE muxu_dev = { 1, 10, 31, 1, 8, 8, &tmxr_ex, &tmxr_dep, &mux_reset, NULL, &mux_attach, &mux_detach, - &muxu_dib, DEV_DISABLE }; + &muxu_dib, DEV_NET | DEV_DISABLE }; /* MUXL data structures diff --git a/HP2100/hp2100_stddev.c b/HP2100/hp2100_stddev.c index e687a86c..e048401d 100644 --- a/HP2100/hp2100_stddev.c +++ b/HP2100/hp2100_stddev.c @@ -1,6 +1,6 @@ /* hp2100_stddev.c: HP2100 standard devices simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,6 +28,7 @@ tty 12531C buffered teleprinter interface clk 12539C time base generator + 25-Apr-03 RMS Added extended file support 22-Dec-02 RMS Added break support 01-Nov-02 RMS Revised BOOT command for IBL ROMs Fixed bug in TTY reset, TTY starts in input mode @@ -133,7 +134,7 @@ REG ptr_reg[] = { { FLDATA (CTL, ptr_dib.ctl, 0) }, { FLDATA (FLG, ptr_dib.flg, 0) }, { FLDATA (FBF, ptr_dib.fbf, 0) }, - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptr_stopioe, 0) }, { ORDATA (DEVNO, ptr_dib.devno, 6), REG_HRO }, @@ -170,7 +171,7 @@ REG ptp_reg[] = { { FLDATA (CTL, ptp_dib.ctl, 0) }, { FLDATA (FLG, ptp_dib.flg, 0) }, { FLDATA (FBF, ptp_dib.fbf, 0) }, - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptp_stopioe, 0) }, { ORDATA (DEVNO, ptp_dib.devno, 6), REG_HRO }, @@ -214,11 +215,11 @@ REG tty_reg[] = { { FLDATA (CTL, tty_dib.ctl, 0) }, { FLDATA (FLG, tty_dib.flg, 0) }, { FLDATA (FBF, tty_dib.fbf, 0) }, - { DRDATA (KPOS, tty_unit[TTI].pos, 32), PV_LEFT }, + { DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT }, { DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT }, - { DRDATA (TPOS, tty_unit[TTO].pos, 32), PV_LEFT }, + { DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT }, { DRDATA (TTIME, tty_unit[TTO].wait, 24), REG_NZ + PV_LEFT }, - { DRDATA (PPOS, tty_unit[TTP].pos, 32), PV_LEFT }, + { DRDATA (PPOS, tty_unit[TTP].pos, T_ADDR_W), PV_LEFT }, { FLDATA (STOP_IOE, ttp_stopioe, 0) }, { ORDATA (DEVNO, tty_dib.devno, 6), REG_HRO }, { NULL } }; diff --git a/HP2100/hp2100_sys.c b/HP2100/hp2100_sys.c index cebf7d88..f0fce56a 100644 --- a/HP2100/hp2100_sys.c +++ b/HP2100/hp2100_sys.c @@ -1,6 +1,6 @@ /* hp2100_sys.c: HP 2100 simulator interface - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/I1401/i1401_cd.c b/I1401/i1401_cd.c index a6c6c990..666c2b50 100644 --- a/I1401/i1401_cd.c +++ b/I1401/i1401_cd.c @@ -1,6 +1,6 @@ /* i1401_cd.c: IBM 1402 card reader/punch - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -35,6 +35,7 @@ Cards are represented as ASCII text streams terminated by newlines. This allows cards to be created and edited as normal files. + 25-Apr-03 RMS Revised for extended file support 30-May-02 RMS Widened POS to 32b 30-Jan-02 RMS New zero footprint card bootstrap from Van Snyder 29-Nov-01 RMS Added read only unit support @@ -70,7 +71,7 @@ REG cdr_reg[] = { { FLDATA (ERR, ind[IN_READ], 0) }, { FLDATA (S1, s1sel, 0) }, { FLDATA (S2, s2sel, 0) }, - { DRDATA (POS, cdr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, cdr_unit.wait, 24), PV_LEFT }, { BRDATA (BUF, rbuf, 8, 8, CDR_WIDTH) }, { NULL } }; @@ -95,7 +96,7 @@ REG cdp_reg[] = { { FLDATA (ERR, ind[IN_PNCH], 0) }, { FLDATA (S4, s4sel, 0) }, { FLDATA (S8, s8sel, 0) }, - { DRDATA (POS, cdp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT }, { NULL } }; DEVICE cdp_dev = { @@ -119,10 +120,10 @@ UNIT stack_unit[] = { { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) } }; REG stack_reg[] = { - { DRDATA (POS0, stack_unit[0].pos, 32), PV_LEFT }, - { DRDATA (POS1, stack_unit[1].pos, 32), PV_LEFT }, - { DRDATA (POS28, stack_unit[2].pos, 32), PV_LEFT }, - { DRDATA (POS4, stack_unit[4].pos, 32), PV_LEFT }, + { DRDATA (POS0, stack_unit[0].pos, T_ADDR_W), PV_LEFT }, + { DRDATA (POS1, stack_unit[1].pos, T_ADDR_W), PV_LEFT }, + { DRDATA (POS28, stack_unit[2].pos, T_ADDR_W), PV_LEFT }, + { DRDATA (POS4, stack_unit[4].pos, T_ADDR_W), PV_LEFT }, { NULL } }; DEVICE stack_dev = { diff --git a/I1401/i1401_cpu.c b/I1401/i1401_cpu.c index efead22f..209cfaf1 100644 --- a/I1401/i1401_cpu.c +++ b/I1401/i1401_cpu.c @@ -1,6 +1,6 @@ /* i1401_cpu.c: IBM 1401 CPU simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,12 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 16-Mar-03 RMS Fixed mnemonic, instruction lengths, and reverse + scan length check bug for MCS + Fixed MCE bug, BS off by 1 if zero suppress + Fixed chaining bug, D lost if return to SCP + Fixed H branch, branch occurs after continue + Added check for invalid 8 character MCW, LCA 03-Jun-03 RMS Added 1311 support 22-May-02 RMS Added multiply and divide 30-Dec-01 RMS Added old PC queue @@ -142,7 +148,9 @@ uint8 M[MAXMEMSIZE] = { 0 }; /* main memory */ int32 saved_IS = 0; /* saved IS */ int32 AS = 0; /* AS */ int32 BS = 0; /* BS */ +int32 D = 0; /* modifier */ int32 as_err = 0, bs_err = 0; /* error flags */ +int32 hb_pend = 0; /* halt br pending */ uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */ int32 pcq_p = 0; /* PC queue ptr */ REG *pcq_r = NULL; /* PC queue reg ptr */ @@ -194,6 +202,7 @@ REG cpu_reg[] = { { DRDATA (BS, BS, 14), PV_LEFT }, { FLDATA (ASERR, as_err, 0) }, { FLDATA (BSERR, bs_err, 0) }, + { ORDATA (D, D, 7) }, { FLDATA (SSA, ssa, 0) }, { FLDATA (SSB, ind[IN_SSB], 0) }, { FLDATA (SSC, ind[IN_SSC], 0) }, @@ -208,8 +217,9 @@ REG cpu_reg[] = { { FLDATA (OVF, ind[IN_OVF], 0) }, { FLDATA (IOCHK, iochk, 0) }, { FLDATA (PRCHK, prchk, 0) }, + { FLDATA (HBPEND, hb_pend, 0) }, { BRDATA (ISQ, pcq, 10, 14, PCQ_SIZE), REG_RO+REG_CIRC }, - { ORDATA (ISQP, pcq_p, 6), REG_HRO }, + { DRDATA (ISQP, pcq_p, 6), REG_HRO }, { ORDATA (WRU, sim_int_char, 8) }, { NULL } }; @@ -271,7 +281,7 @@ const int32 op_table[64] = { L1 | L8 | BREQ | BBE, /* branch if bit eq */ 0, /* illegal */ L1 | L4 | L7 | AREQ | BREQ, /* 30: move zones */ - L7 | AREQ | BREQ, /* move supress zero */ + L1 | L4 | L7 | AREQ | BREQ, /* move supress zero */ 0, /* illegal */ L1 | L4 | L7 | AREQ | BREQ | NOWM, /* set word mark */ L7 | AREQ | BREQ | MDV, /* divide */ @@ -305,7 +315,7 @@ const int32 op_table[64] = { L1 | L4 | L7 | AREQ | MLS, /* 70: store B addr */ 0, /* illegal */ L1 | L4 | L7 | AREQ | BREQ, /* zero and add */ - HNOP | L1 | L4, /* halt */ + HNOP | L1 | L4 | L7, /* halt */ L1 | L4 | L7 | AREQ | BREQ, /* clear word mark */ 0, /* illegal */ 0, /* illegal */ @@ -456,8 +466,8 @@ static const int32 mtf_mod[] = { BCD_B, BCD_E, BCD_M, BCD_R, BCD_U, -1 }; t_stat sim_instr (void) { extern int32 sim_interval; -int32 IS, D, ilnt, flags; -int32 op, xa, t, wm, dev, unit; +int32 IS, ilnt, flags; +int32 op, xa, t, wm, ioind, dev, unit; int32 a, b, i, asave, bsave; int32 carry, lowprd, sign, ps; int32 quo, ahigh, qs; @@ -466,16 +476,21 @@ t_stat reason, r1, r2; /* Restore saved state */ + IS = saved_IS; if (as_err) AS = AS | BA; /* flag bad addresses */ if (bs_err) BS = BS | BA; as_err = bs_err = 0; /* reset error flags */ -D = 0; reason = 0; /* Main instruction fetch/decode loop */ while (reason == 0) { /* loop until halted */ + +if (hb_pend) { /* halt br pending? */ + hb_pend = 0; /* clear flag */ + BRANCH; } /* execute branch */ + saved_IS = IS; /* commit prev instr */ if (sim_interval <= 0) { /* check clock queue */ if (reason = sim_process_event ()) break; } @@ -500,7 +515,7 @@ if (op == OP_SAR) BS = AS; /* SAR? save ASTAR */ PP (IS); if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* WM? 1 char inst */ -D = t; /* could be D char */ +D = ioind = t; /* could be D char, % */ AS = hun_table[t]; /* could be A addr */ PP (IS); /* if %xy, BA is set */ @@ -519,7 +534,7 @@ if ((t = M[IS]) & WM) { /* WM? 3 char inst */ AS = AS + one_table[t]; /* finish A addr */ unit = (t == BCD_ZERO)? 0: t; /* save char as unit */ xa = (AS >> V_INDEX) & M_INDEX; /* get index reg */ -if (xa && (D != BCD_PERCNT) && (cpu_unit.flags & XSA)) { /* indexed? */ +if (xa && (ioind != BCD_PERCNT) && (cpu_unit.flags & XSA)) { /* indexed? */ AS = AS + hun_table[M[xa] & CHAR] + ten_table[M[xa + 1] & CHAR] + one_table[M[xa + 2] & CHAR]; AS = (AS & INDEXMASK) % MAXMEMSIZE; } @@ -570,7 +585,7 @@ switch (op) { /* case on opcode */ until A WM MCM: copy A to B, preserving B WM, fetch fetch until record or group mark - MSZ: copy A to B, clearing B WM, until A WM; fetch fetch + MCS: copy A to B, clearing B WM, until A WM; fetch fetch reverse scan and suppress leading zeroes MN: copy A char digit to B char digit, fetch fetch preserving B zone and WM @@ -580,21 +595,23 @@ switch (op) { /* case on opcode */ case OP_MCW: /* move char */ if (ilnt >= 8) { /* I/O form? */ - reason = iodisp (dev, unit, MD_NORM, D); + if (ioind != BCD_PERCNT) reason = STOP_INVL; + else reason = iodisp (dev, unit, MD_NORM, D); break; } if (ADDR_ERR (AS)) { /* check A addr */ reason = STOP_INVA; break; } do { - M[BS] = (M[BS] & WM) | (M[AS] & CHAR); /* move char */ wm = M[AS] | M[BS]; + M[BS] = (M[BS] & WM) | (M[AS] & CHAR); /* move char */ MM (AS); MM (BS); } /* decr pointers */ while ((wm & WM) == 0); /* stop on A,B WM */ break; case OP_LCA: /* load char */ if (ilnt >= 8) { /* I/O form? */ - reason = iodisp (dev, unit, MD_WM, D); + if (ioind != BCD_PERCNT) reason = STOP_INVL; + else reason = iodisp (dev, unit, MD_WM, D); break; } if (ADDR_ERR (AS)) { /* check A addr */ reason = STOP_INVA; @@ -607,18 +624,18 @@ case OP_LCA: /* load char */ case OP_MCM: /* move to rec/group */ do { - M[BS] = (M[BS] & WM) | (M[AS] & CHAR); /* move char */ t = M[AS]; + M[BS] = (M[BS] & WM) | (M[AS] & CHAR); /* move char */ PP (AS); PP (BS); } /* incr pointers */ while (((t & CHAR) != BCD_RECMRK) && (t != (BCD_GRPMRK + WM))); break; -case OP_MSZ: /* move suppress zero */ +case OP_MCS: /* move suppress zero */ bsave = BS; /* save B start */ qzero = 1; /* set suppress */ do { - M[BS] = M[AS] & ((BS != bsave)? CHAR: DIGIT); /* copy char */ wm = M[AS]; + M[BS] = M[AS] & ((BS != bsave)? CHAR: DIGIT); /* copy char */ MM (AS); MM (BS); } /* decr pointers */ while ((wm & WM) == 0); /* stop on A WM */ if (reason) break; /* addr err? stop */ @@ -631,7 +648,8 @@ case OP_MSZ: /* move suppress zero */ else if (((t == BCD_DECIMAL) && (cpu_unit.flags & EPE)) || (t <= BCD_NINE)) qzero = 0; else qzero = 1; } - while (BS <= bsave); + while (BS < bsave); + PP (BS); /* BS end is B+1 */ break; case OP_MN: /* move numeric */ @@ -644,10 +662,7 @@ case OP_MZ: /* move zone */ MM (AS); MM (BS); /* decr pointers */ break; -/* Compare - - A and B are checked in fetch -*/ +/* Compare - A and B are checked in fetch */ case OP_C: /* compare */ if (ilnt != 1) { /* if not chained */ @@ -993,7 +1008,9 @@ case OP_MCE: /* edit */ while ((b & WM) == 0); M[BS] = M[BS] & ~WM; /* clear B WM */ - if (!qdollar && !(qdecimal && qzero)) break; /* rescan again? */ + if (!qdollar && !(qdecimal && qzero)) { /* rescan again? */ + BS++; /* BS = addr WM + 1 */ + break; } if (qdecimal && qzero) qdollar = 0; /* no digits? clr $ */ /* Edit pass 3 (extended print only) - from right to left */ @@ -1111,7 +1128,7 @@ case OP_DIV: reason = STOP_WRAP; /* address wrap? */ break; } div_sign (M[asave], b, qs - 1, bsave - 1); /* set signs */ - BS = (BS - 2) - (asave - (AS + 1)); /* final bs */ + BS = (BS - 2) - (asave - (AS + 1)); /* final bs */ break; } bsave = BS + (asave - ahigh); /* end subdivd */ qs = (BS - 2) - (ahigh - (AS + 1)); /* quo start */ @@ -1208,7 +1225,7 @@ case OP_NOP: /* nop */ break; case OP_H: /* halt */ - if (ilnt >= 4) { BRANCH; } /* branch if called */ + if (ilnt == 4) hb_pend = 1; /* set pending branch */ reason = STOP_HALT; /* stop simulator */ saved_IS = IS; /* commit instruction */ break; @@ -1355,10 +1372,12 @@ t_stat cpu_reset (DEVICE *dptr) { int32 i; -for (i = 0; i < 64; i++) ind[i] = 0; -ind[IN_UNC] = 1; -AS = 0; as_err = 1; -BS = 0; bs_err = 1; +for (i = 0; i < 64; i++) ind[i] = 0; /* clr indicators */ +ind[IN_UNC] = 1; /* ind[0] always on */ +AS = 0; as_err = 1; /* clear AS */ +BS = 0; bs_err = 1; /* clear BS */ +D = 0; /* clear D */ +hb_pend = 0; /* no halt br */ pcq_r = find_reg ("ISQ", NULL, dptr); if (pcq_r) pcq_r->qptr = 0; else return SCPE_IERR; @@ -1389,7 +1408,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val % 1000) != 0)) return SCPE_ARG; diff --git a/I1401/i1401_dat.h b/I1401/i1401_dat.h index 4de65ee1..02e6ac00 100644 --- a/I1401/i1401_dat.h +++ b/I1401/i1401_dat.h @@ -1,3 +1,28 @@ +/* i1401_dat.h: IBM 1401 character conversion tables + + Copyright (c) 1993-2003, Robert M. Supnik + + 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 + ROBERT M SUPNIK 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. + + Except as contained in this notice, the name of Robert M Supnik shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Robert M Supnik. +*/ /* ASCII to BCD conversion */ diff --git a/I1401/i1401_defs.h b/I1401/i1401_defs.h index 2ef6e87d..a7c95304 100644 --- a/I1401/i1401_defs.h +++ b/I1401/i1401_defs.h @@ -1,6 +1,6 @@ /* i1401_defs.h: IBM 1401 simulator definitions - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,7 +23,8 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - 03-Jun-03 RMS Added 1311 support + 16-Mar-03 RMS Fixed mnemonic for MCS + 03-Jun-02 RMS Added 1311 support 14-Apr-99 RMS Converted t_addr to unsigned This simulator is based on the 1401 simulator written by Len Fehskens @@ -79,7 +80,7 @@ #define LPT_WIDTH 132 /* line print width */ #define CCT_LNT 132 /* car ctrl length */ #define INQ_WIDTH 80 /* inq term width */ -#define ADDR_ERR(x) (((t_addr) (x)) >= MEMSIZE) +#define ADDR_ERR(x) (((uint32) (x)) >= MEMSIZE) /* Binary address format @@ -205,7 +206,7 @@ #define OP_BWZ 025 /* branch wm or zone */ #define OP_BBE 026 /* branch bit equal */ #define OP_MZ 030 /* move zone */ -#define OP_MSZ 031 /* move suppr zeroes */ +#define OP_MCS 031 /* move suppr zeroes */ #define OP_SWM 033 /* set word mark */ #define OP_DIV 034 /* divide */ #define OP_SS 042 /* select stacker */ diff --git a/I1401/i1401_doc.txt b/I1401/i1401_doc.txt index 0880c940..fc69dc66 100644 --- a/I1401/i1401_doc.txt +++ b/I1401/i1401_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: IBM 1401 Simulator Usage -Date: 15-Nov-2002 +Date: 20-Apr-2003 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2002, written by Robert M Supnik - Copyright (c) 1993-2002, Robert M Supnik + Original code published in 1993-2003, written by Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -161,7 +161,7 @@ interrupt system. OVF 1 overflow indicator IOCHK 1 I/O check switch PRCHK 1 process check switch - ISQ 1 IS prior to last branch; + ISQ[0:63] 14 IS prior to last branch; most recent IS change first WRU 8 interrupt character @@ -184,26 +184,30 @@ the POS register specifies the number of the next data item to be read or written. Thus, by changing POS, the user can backspace or advance these devices. -The reader/punch registers are: +The card reader registers are: - device name size comments + name size comments - CDR LAST 1 last card indicator - ERR 1 error indicator - S1 1 stacker 1 select flag - S2 1 stacker 2 select flag - POS 32 position - TIME 24 delay window for stacker select - BUF[0:79] 8 reader buffer + LAST 1 last card indicator + ERR 1 error indicator + S1 1 stacker 1 select flag + S2 1 stacker 2 select flag + POS 32 position + TIME 24 delay window for stacker select + BUF[0:79] 8 reader buffer - CDP ERR 1 error indicator - S4 1 stacker 4 select flag - S8 1 stacker 8 select flag +The card punch registers are: - STKR POS0 32 position, normal reader stack - POS1 32 position, reader stacker 1 - POS2 32 position, shared stacker 2/8 - POS4 32 position, punch stacker 4 + ERR 1 error indicator + S4 1 stacker 4 select flag + S8 1 stacker 8 select flag + +The stacker registers are: + + POS0 32 position, normal reader stack + POS1 32 position, reader stacker 1 + POS2 32 position, shared stacker 2/8 + POS4 32 position, punch stacker 4 Error handling is as follows: @@ -423,7 +427,7 @@ devices can only accept single character input, without word marks. 2.7 Character Sets -The IBM 1401 used a 6b character code called BCD (binary coded decimal). +The IBM 1401 uses a 6b character code called BCD (binary coded decimal). Some of the characters have no equivalent in ASCII and require different representations: diff --git a/I1401/i1401_dp.c b/I1401/i1401_dp.c index 760fbcd2..1e2a0686 100644 --- a/I1401/i1401_dp.c +++ b/I1401/i1401_dp.c @@ -1,6 +1,6 @@ /* i1401_dp.c: IBM 1311 disk simulator - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/I1401/i1401_iq.c b/I1401/i1401_iq.c index 6866dd7d..5e8c5691 100644 --- a/I1401/i1401_iq.c +++ b/I1401/i1401_iq.c @@ -1,6 +1,6 @@ /* i1401_iq.c: IBM 1407 inquiry terminal - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/I1401/i1401_lp.c b/I1401/i1401_lp.c index f7eaac41..696b6f32 100644 --- a/I1401/i1401_lp.c +++ b/I1401/i1401_lp.c @@ -1,6 +1,6 @@ /* i1401_lp.c: IBM 1403 line printer simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ lpt 1403 line printer + 25-Apr-03 RMS Revised for extended file support 30-May-02 RMS Widened POS to 32b 13-Apr-01 RMS Revised for register arrays */ @@ -87,7 +88,7 @@ UNIT lpt_unit = { REG lpt_reg[] = { { FLDATA (ERR, ind[IN_LPT], 0) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { BRDATA (CCT, cct, 8, 32, CCT_LNT) }, { DRDATA (LINES, lines, 8), PV_LEFT }, { DRDATA (CCTP, cctptr, 8), PV_LEFT }, diff --git a/I1401/i1401_mt.c b/I1401/i1401_mt.c index 8427b2db..881e00fa 100644 --- a/I1401/i1401_mt.c +++ b/I1401/i1401_mt.c @@ -25,6 +25,9 @@ mt 7-track magtape + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support + 15-Mar-03 RMS Fixed end-of-record on load read yet again 28-Feb-03 RMS Modified for magtape library 31-Oct-02 RMS Added error record handling 10-Oct-02 RMS Fixed end-of-record on load read writes WM plus GM @@ -101,17 +104,19 @@ UNIT mt_unit[] = { REG mt_reg[] = { { FLDATA (END, ind[IN_END], 0) }, { FLDATA (ERR, ind[IN_TAP], 0) }, - { DRDATA (POS1, mt_unit[1].pos, 32), PV_LEFT + REG_RO }, - { DRDATA (POS2, mt_unit[2].pos, 32), PV_LEFT + REG_RO }, - { DRDATA (POS3, mt_unit[3].pos, 32), PV_LEFT + REG_RO }, - { DRDATA (POS4, mt_unit[4].pos, 32), PV_LEFT + REG_RO }, - { DRDATA (POS5, mt_unit[5].pos, 32), PV_LEFT + REG_RO }, - { DRDATA (POS6, mt_unit[6].pos, 32), PV_LEFT + REG_RO }, + { DRDATA (POS1, mt_unit[1].pos, T_ADDR_W), PV_LEFT + REG_RO }, + { DRDATA (POS2, mt_unit[2].pos, T_ADDR_W), PV_LEFT + REG_RO }, + { DRDATA (POS3, mt_unit[3].pos, T_ADDR_W), PV_LEFT + REG_RO }, + { DRDATA (POS4, mt_unit[4].pos, T_ADDR_W), PV_LEFT + REG_RO }, + { DRDATA (POS5, mt_unit[5].pos, T_ADDR_W), PV_LEFT + REG_RO }, + { DRDATA (POS6, mt_unit[6].pos, T_ADDR_W), PV_LEFT + REG_RO }, { NULL } }; MTAB mt_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { 0 } }; DEVICE mt_dev = { @@ -173,6 +178,12 @@ return mt_map_status (st); mod = modifier character Outputs: status = status + + Fine point: after a read, the system writes a group mark just + beyond the end of the record. However, first it checks for a + GM + WM; if present, the GM + WM is not changed. Otherwise, + an MCW read sets a GM, preserving the current WM; while an LCA + read sets a GM and clears the WM. */ t_stat mt_io (int32 unit, int32 flag, int32 mod) @@ -211,8 +222,9 @@ case BCD_R: /* read */ if (ADDR_ERR (BS)) { /* check next BS */ BS = BA | (BS % MAXMEMSIZE); return STOP_WRAP; } } - if (flag == MD_WM) M[BS] = WM | BCD_GRPMRK; /* load? set WM */ - else M[BS] = (M[BS] & WM) | BCD_GRPMRK; /* move? save WM */ + if (M[BS] != (BCD_GRPMRK + WM)) { /* not GM+WM at end? */ + if (flag == MD_WM) M[BS] = BCD_GRPMRK; /* LCA: clear WM */ + else M[BS] = (M[BS] & WM) | BCD_GRPMRK; } /* MCW: save WM */ BS++; /* adv BS */ if (ADDR_ERR (BS)) { /* check final BS */ BS = BA | (BS % MAXMEMSIZE); diff --git a/I1401/i1401_sys.c b/I1401/i1401_sys.c index c9cf3c8e..27e61090 100644 --- a/I1401/i1401_sys.c +++ b/I1401/i1401_sys.c @@ -1,6 +1,6 @@ /* i1401_sys.c: IBM 1401 simulator interface - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 16-Mar-03 RMS Fixed mnemonic for MCS 03-Jun-02 RMS Added 1311 support 18-May-02 RMS Added -D feature from Van Snyder 26-Jan-02 RMS Fixed H, NOP with no trailing wm (found by Van Snyder) @@ -158,7 +159,7 @@ const char *opcode[64] = { NULL, "R", "W", "WR", "P", "RP", "WP", "WRP", "RF", "WF", NULL, "MA", "MUL", NULL, NULL, NULL, NULL, "CS", "S", NULL, "MTF", "BWZ", "BBE", NULL, - "MZ", "MSZ", NULL, "SWM", "DIV", NULL, NULL, NULL, + "MZ", "MCS", NULL, "SWM", "DIV", NULL, NULL, NULL, NULL, NULL, "SS", "LCA", "MCW", "NOP", NULL, "MCM", "SAR", NULL, "ZS", NULL, NULL, NULL, NULL, NULL, NULL, "A", "B", "C", "MN", "MCE", "CC", NULL, diff --git a/I1620/i1620_cd.c b/I1620/i1620_cd.c index 6305ea7e..4c3ecb86 100644 --- a/I1620/i1620_cd.c +++ b/I1620/i1620_cd.c @@ -1,6 +1,6 @@ /* i1620_cd.c: IBM 1622 card reader/punch - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,8 @@ cdr 1622 card reader cdp 1622 card punch + 25-Apr-03 RMS Revised for extended file support + Cards are represented as ASCII text streams terminated by newlines. This allows cards to be created and edited as normal files. */ @@ -62,7 +64,7 @@ UNIT cdr_unit = { REG cdr_reg[] = { { FLDATA (LAST, ind[IN_LAST], 0) }, - { DRDATA (POS, cdr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT }, { NULL } }; DEVICE cdr_dev = { @@ -82,7 +84,7 @@ UNIT cdp_unit = { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }; REG cdp_reg[] = { - { DRDATA (POS, cdp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT }, { NULL } }; DEVICE cdp_dev = { diff --git a/I1620/i1620_cpu.c b/I1620/i1620_cpu.c index f0e4a7e9..08d540e9 100644 --- a/I1620/i1620_cpu.c +++ b/I1620/i1620_cpu.c @@ -1,6 +1,6 @@ /* i1620_cpu.c: IBM 1620 CPU simulator - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,7 @@ This CPU module incorporates code and comments from the 1620 simulator by Geoff Kuenning, with his permission. + 25-Apr-03 RMS Changed t_addr to uint32 throughout 18-Oct-02 RMS Fixed bugs in invalid result testing (found by Hans Pufal) The simulated register state for the IBM 1620 is: @@ -760,7 +761,7 @@ case OP_BCXM: break; } reason = add_field (GET_IDXADDR (idx), QAR, FALSE, TRUE, &sta); if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL; - if ((ind[IN_EZ] == 0) && (sta == ADD_NOCRY)) { /* ~z, ~c, ~schg? */ + if ((ind[IN_EZ] == 0) && (sta == ADD_NOCRY)) { /* ~z, ~c, ~sign chg? */ BRANCH (PAR); } /* branch */ break; @@ -954,10 +955,10 @@ cnt = 0; /* count depth */ do { indir = indir & M[alast]; /* get indirect */ if (cvt_addr (alast, lnt, FALSE, &addr)) /* cvt addr to bin */ return STOP_INVPDG; /* bad? */ - idx = get_idx (ADDR_S (alast, 1)); /* get index addr */ + idx = get_idx (ADDR_S (alast, 1)); /* get index reg num */ if (indexok && (idx > 0)) { /* indexable? */ - idxa = GET_IDXADDR (idx); /* get idx addr */ - if (cvt_addr (idxa, ADDR_LEN, TRUE, &idxv)) /* cvt idx */ + idxa = GET_IDXADDR (idx); /* get idx reg addr */ + if (cvt_addr (idxa, ADDR_LEN, TRUE, &idxv)) /* cvt idx reg */ return STOP_INVPDG; addr = addr + idxv; /* add in index */ if (addr < 0) addr = addr + 100000; } /* -? 10's comp */ @@ -1009,10 +1010,10 @@ return SCPE_OK; t_stat get_idx (uint32 aidx) { -int32 i, idx = 0; +int32 i, idx; if (idxe == 0) return -1; /* indexing off? */ -for (i = 0; i < 3; i++) { /* 3 flags worth */ +for (i = idx = 0; i < 3; i++) { /* 3 flags worth */ if (M[aidx] & FLAG) idx = idx | (1 << i); /* test flag */ MM (aidx); } /* next digit */ return idx; @@ -1040,7 +1041,7 @@ return; t_stat xmt_field (uint32 d, uint32 s, uint32 skp) { -t_addr cnt = 0; +uint32 cnt = 0; uint8 t; do { t = M[d] = M[s] & (FLAG | DIGIT); /* copy src to dst */ @@ -1054,7 +1055,7 @@ return SCPE_OK; t_stat xmt_record (uint32 d, uint32 s, t_bool cpy) { -t_addr cnt = 0; +uint32 cnt = 0; while ((M[s] & REC_MARK) != REC_MARK) { /* until rec mark */ M[d] = M[s] & (FLAG | DIGIT); /* copy src to dst */ @@ -1083,7 +1084,7 @@ return SCPE_OK; t_stat xmt_divd (uint32 d, uint32 s) { -t_addr cnt = 0; +uint32 cnt = 0; M[d] = M[s] & DIGIT; /* first w/o flag */ do { MM (d); MM (s); /* decr mem addrs */ @@ -1097,7 +1098,7 @@ return SCPE_OK; t_stat xmt_tns (uint32 d, uint32 s) { -t_addr cnt = 0; +uint32 cnt = 0; uint8 t, z; t = M[s] & DIGIT; /* get units */ @@ -1120,7 +1121,7 @@ return SCPE_OK; t_stat xmt_tnf (uint32 d, uint32 s) { -t_addr cnt = 0; +uint32 cnt = 0; uint8 t; t = M[s]; /* get 1st digit */ @@ -1242,7 +1243,7 @@ t_stat mul_field (uint32 mpc, uint32 mpy) int32 i; uint32 pro; /* prod pointer */ uint32 mpyd, mpyf; /* mpy digit, flag */ -t_addr cnt = 0; /* counter */ +uint32 cnt = 0; /* counter */ uint8 sign; /* final sign */ t_stat r; @@ -1299,7 +1300,7 @@ uint32 mpcd, mpcf; /* mpc digit, flag */ uint32 prwp; /* prod working ptr */ uint32 prod; /* product digit */ uint32 cry; /* carry */ -t_addr mpcc, cryc; /* counters */ +uint32 mpcc, cryc; /* counters */ mptb = MUL_TABLE + ((mpyd <= 4)? (mpyd * 2): /* set mpy table 100's, */ (((mpyd - 5) * 2) + 100)); /* 1's digits */ @@ -1535,7 +1536,7 @@ t_stat div_one_digit (uint32 dvd, uint32 dvr, uint32 max, uint32 dvrp, dvrd, dvrf; /* dvr ptr, dig, flag */ uint32 dvdp, dvdd; /* dvd ptr, dig */ uint32 qd, cry; /* quo dig, carry */ -t_addr cnt; +uint32 cnt; for (qd = 0; qd < max; qd++) { /* devel quo dig */ dvrp = dvr; /* divisor ptr */ @@ -1592,7 +1593,7 @@ return SCPE_OK; t_stat or_field (uint32 d, uint32 s) { -t_addr cnt = 0; +uint32 cnt = 0; int32 t; ind[IN_EZ] = 1; /* assume result zero */ @@ -1607,7 +1608,7 @@ return SCPE_OK; t_stat and_field (uint32 d, uint32 s) { -t_addr cnt = 0; +uint32 cnt = 0; int32 t; ind[IN_EZ] = 1; /* assume result zero */ @@ -1622,7 +1623,7 @@ return SCPE_OK; t_stat xor_field (uint32 d, uint32 s) { -t_addr cnt = 0; +uint32 cnt = 0; int32 t; ind[IN_EZ] = 1; /* assume result zero */ @@ -1637,7 +1638,7 @@ return SCPE_OK; t_stat com_field (uint32 d, uint32 s) { -t_addr cnt = 0; +uint32 cnt = 0; int32 t; ind[IN_EZ] = 1; /* assume result zero */ @@ -1667,7 +1668,7 @@ return SCPE_OK; t_stat oct_to_dec (uint32 tbl, uint32 s) { -t_addr cnt = 0, tblc; +uint32 cnt = 0, tblc; uint32 i, sd, sf, tf, sign; t_stat r; @@ -1715,7 +1716,7 @@ t_stat dec_to_oct (uint32 d, uint32 tbl, int32 *ez) { uint32 sign, octd, t; t_bool first = TRUE; -t_addr ctr = 0; +uint32 ctr = 0; t_stat r; sign = M[PROD_AREA + PROD_AREA_LEN - 1] & FLAG; /* input sign */ @@ -1794,7 +1795,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val % 1000) != 0)) return SCPE_ARG; diff --git a/I1620/i1620_defs.h b/I1620/i1620_defs.h index b61368f5..b07cde33 100644 --- a/I1620/i1620_defs.h +++ b/I1620/i1620_defs.h @@ -1,6 +1,6 @@ /* i1620_defs.h: IBM 1620 simulator definitions - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/I1620/i1620_doc.txt b/I1620/i1620_doc.txt index e3d23fca..3b64d70b 100644 --- a/I1620/i1620_doc.txt +++ b/I1620/i1620_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: IBM 1620 Simulator Usage -Date: 15-Nov-2002 +Date: 15-Apr-2003 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2002, written by Robert M Supnik - Copyright (c) 1993-2002, Robert M Supnik + Original code published in 1993-2003, written by Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -138,10 +138,10 @@ standard on the Model 2. If memory size is being reduced, and the memory being truncated contains non-zero data, the simulator asks for confirmation. Data in the truncated -portion of memory is lost. Initially, memory size is 16K, and all special -features are enabled. +portion of memory is lost. Initially, the CPU is a Model I, memory size is +20K, and indirect addressing, editing instructions, and divide are enabled. -Memory is implemented as 5 bit BCD characters, as follows: +Memory is implemented as 5 bit BCD digits, as follows: 4 3 2 1 0 @@ -177,8 +177,8 @@ interrupt system. IND[0:99] 1 indicator array IAE 1 indirect address enable (Model 2 only) IDXE 1 indexing enable (Model 2 only) - IDXB 1 indexinb band select (Model 2 only) - IR1Q 1 IR1 prior to last branch; + IDXB 1 indexing band select (Model 2 only) + IR1Q[0:63] 16 IR1 prior to last branch; most recent IR1 change first WRU 8 interrupt character @@ -198,12 +198,12 @@ key is pressed. The typewriter has no errors. 2.3 1621 Paper Tape Reader (PTR) -The paper tape reader (PTR) reads data from a disk file. The POS -register specifies the number of the next data item to be read. Thus, -by changing POS, the user can backspace or advance the reader. +The paper tape reader (PTR) reads data from a disk file. The POS register +specifies the number of the next data item to be read. Thus, by changing +POS, the user can backspace or advance the reader. The paper tape reader supports the BOOT command. BOOT PTR starts the -specified instruction sequence at location 0. +standard paper tape boot sequence at location 0. The paper tape reader implements these registers: @@ -227,7 +227,7 @@ Error handling is as follows: 2.4 1624 Paper Tape Punch (PTP) The paper tape punch (PTP) writes data to a disk file. The POS register -specifies the number of the next data item to bewritten. Thus, by +specifies the number of the next data item to be written. Thus, by changing POS, the user can backspace or advance the punch. The paper tape punch implements these registers: @@ -252,8 +252,8 @@ Error handling is as follows: The IBM 1402 card/reader punch is simulated as two independent devices: the card reader (CDR) and the card punch (CDP). -The card reader supports the BOOT command. BOOT CDR starts the -specified instruction sequence at location 0. +The card reader supports the BOOT command. BOOT CDR starts the standard +card boot sequence at location 0. The card reader reads data from a disk file, while the punch writes data to a disk file. Cards are simulated as ASCII text lines with terminating @@ -436,11 +436,11 @@ marks the end of the immediate Q operand; and the flags over digits The IBM 1620 uses single digits to represent numbers, and pairs of digits to represent characters (alphameric coding). Only a small number of the 256 possible alphameric codings have legitimate values. -Further, the translation between alphameric and devices varied -from device to device. The simulator implements a code called +Further, the translation between alphameric and devices varied from +device to device. The simulator implements a code called 1620 ASCII, which allows all 64 possible card codes to be represented by upper -case ASCII characters. In addition, lower case alphabetic -characters are accepted on input as equivalent to upper case. +case ASCII characters. In addition, lower case alphabetic characters +are accepted on input as equivalent to upper case. Card code PT code RA RN LPT WA ASCII representation diff --git a/I1620/i1620_dp.c b/I1620/i1620_dp.c index 8496189e..10f2a16c 100644 --- a/I1620/i1620_dp.c +++ b/I1620/i1620_dp.c @@ -1,6 +1,6 @@ /* i1620_dp.c: IBM 1311 disk simulator - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -83,7 +83,7 @@ extern uint8 ind[NUM_IND]; extern UNIT cpu_unit; int32 dp_stop = 1; /* disk err stop */ -t_addr dp_ba = 0; /* buffer addr */ +uint32 dp_ba = 0; /* buffer addr */ t_stat dp_reset (DEVICE *dptr); t_stat dp_rdadr (UNIT *uptr, int32 sec, int32 qnr, int32 qwc); diff --git a/I1620/i1620_fp.c b/I1620/i1620_fp.c index 02e93a62..0cb54a96 100644 --- a/I1620/i1620_fp.c +++ b/I1620/i1620_fp.c @@ -1,6 +1,6 @@ /* i1620_fp.c: IBM 1620 floating point simulator - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/I1620/i1620_lp.c b/I1620/i1620_lp.c index e2320204..28283f61 100644 --- a/I1620/i1620_lp.c +++ b/I1620/i1620_lp.c @@ -1,6 +1,6 @@ /* i1620_lp.c: IBM 1443 line printer simulator - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -24,6 +24,8 @@ in this Software without prior written authorization from Robert M Supnik. lpt 1443 line printer + + 25-Apr-03 RMS Revised for extended file support */ #include "i1620_defs.h" @@ -75,7 +77,7 @@ REG lpt_reg[] = { { FLDATA (PRCH9, ind[IN_PRCH9], 0) }, { FLDATA (PRCH12, ind[IN_PRCH12], 0) }, { FLDATA (PRBSY, ind[IN_PRBSY], 0) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { BRDATA (CCT, cct, 8, 32, CCT_LNT) }, { DRDATA (CCTP, cct_ptr, 8), PV_LEFT }, { DRDATA (CCTL, cct_lnt, 8), REG_RO + PV_LEFT }, diff --git a/I1620/i1620_pt.c b/I1620/i1620_pt.c index 251d2e9b..2f213077 100644 --- a/I1620/i1620_pt.c +++ b/I1620/i1620_pt.c @@ -1,6 +1,6 @@ /* i1620_pt.c: IBM 1621/1624 paper tape reader/punch simulator - Copyright (c) 2002, Robert M Supnik + Copyright (c) 2002-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ ptr 1621 paper tape reader ptp 1624 paper tape punch + + 25-Apr-03 RMS Revised for extended file support */ #include "i1620_defs.h" @@ -58,7 +60,7 @@ UNIT ptr_unit = { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0) }; REG ptr_reg[] = { - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { NULL } }; DEVICE ptr_dev = { @@ -78,7 +80,7 @@ UNIT ptp_unit = { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }; REG ptp_reg[] = { - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { NULL } }; DEVICE ptp_dev = { @@ -197,7 +199,7 @@ const int8 alp_to_ptp[256] = { t_stat ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1) { -t_addr i; +uint32 i; int8 mc; uint8 ptc; t_stat r, inv = SCPE_OK; @@ -243,7 +245,7 @@ return STOP_RWRAP; t_stat btr (uint32 op, uint32 pa, uint32 f0, uint32 f1) { -t_addr i; +uint32 i; uint8 ptc; t_stat r, inv = SCPE_OK; @@ -333,7 +335,7 @@ return SCPE_OK; t_stat ptp (uint32 op, uint32 pa, uint32 f0, uint32 f1) { -t_addr i; +uint32 i; int8 ptc; uint8 z, d; t_stat r; @@ -366,7 +368,7 @@ return STOP_RWRAP; t_stat btp (uint32 op, uint32 pa, uint32 f0, uint32 f1) { -t_addr i; +uint32 i; uint8 ptc, z, d; t_stat r; diff --git a/I1620/i1620_sys.c b/I1620/i1620_sys.c index 831d495a..43951d1d 100644 --- a/I1620/i1620_sys.c +++ b/I1620/i1620_sys.c @@ -1,6 +1,6 @@ /* i1620_sys.c: IBM 1620 simulator interface - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/I1620/i1620_tty.c b/I1620/i1620_tty.c index a268e1c0..47f20906 100644 --- a/I1620/i1620_tty.c +++ b/I1620/i1620_tty.c @@ -1,6 +1,6 @@ /* i1620_tty.c: IBM 1620 typewriter - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/Ibm1130/ibm1130_cpu.c b/Ibm1130/ibm1130_cpu.c index bf5b09e7..96f9767c 100644 --- a/Ibm1130/ibm1130_cpu.c +++ b/Ibm1130/ibm1130_cpu.c @@ -15,6 +15,7 @@ 10-May-02 BLK Fixed bug in MDX instruction 27-Mar-02 BLK Made BOSC work even in short form 16-Aug-02 BLK Fixed bug in multiply instruction; didn't work with negative values + 18-Mar-03 BLK Fixed bug in divide instruction; didn't work with negative values The register state for the IBM 1130 CPU is: @@ -883,7 +884,7 @@ t_stat sim_instr (void) break; case 0x11: /* --- AD - Add Double --- */ - src = ((ACC << 16) + (EXT & 0xFFFF)); + src = ((ACC << 16) | (EXT & 0xFFFF)); src2 = (ReadW(eaddr) << 16) + ReadW(eaddr|1); dst = src + src2; ACC = (dst >> 16) & 0xFFFF; @@ -905,7 +906,7 @@ t_stat sim_instr (void) break; case 0x13: /* --- SD - Subtract Double --- */ - src = ((ACC << 16) + (EXT & 0xFFFF)); + src = ((ACC << 16) | (EXT & 0xFFFF)); src2 = (ReadW(eaddr) << 16) + ReadW(eaddr|1); dst = src - src2; ACC = (dst >> 16) & 0xFFFF; @@ -918,9 +919,9 @@ t_stat sim_instr (void) case 0x14: /* --- M - Multiply --- */ if ((src = ACC & 0xFFFF) & 0x8000) /* sign extend the values */ - src |= 0xFFFF0000; + src |= ~0xFFFF; if ((src2 = ReadW(eaddr)) & 0x8000) - src2 |= 0xFFFF0000; + src2 |= ~0xFFFF; dst = src * src2; ACC = (dst >> 16) & 0xFFFF; /* split the results */ @@ -928,8 +929,10 @@ t_stat sim_instr (void) break; case 0x15: /* --- D - Divide --- */ - src = ((ACC << 16) + EXT); - src2 = ReadW(eaddr); + src = ((ACC << 16) | (EXT & 0xFFFF)); + if ((src2 = ReadW(eaddr)) & 0x8000) + src2 |= ~0xFFFF; /* oops: sign extend was missing, fixed 18Mar03 */ + if (src2 == 0) V = 1; /* divide by zero just sets overflow, ACC & EXT are undefined */ else { @@ -1251,7 +1254,7 @@ void xio_error (char *msg) * register_cmd - add a command to the extensible command table * ------------------------------------------------------------------------ */ -t_stat register_cmd (char *name, t_stat (*action)(), int arg, char *help) +t_stat register_cmd (char *name, t_stat (*action)(int32, char *), int arg, char *help) { int i; diff --git a/Ibm1130/ibm1130_cr.c b/Ibm1130/ibm1130_cr.c index 72167626..033f4982 100644 --- a/Ibm1130/ibm1130_cr.c +++ b/Ibm1130/ibm1130_cr.c @@ -16,7 +16,12 @@ NOTE - there is a problem with this code. The Device Status Word (DSW) is computed from current conditions when requested by an XIO load status command; the value of DSW available to the simulator's examine & save -commands may NOT be accurate. This should probably be fixed. +commands may NOT be accurate. This should probably be fixed. (I think there's +a way to have the expression evaluator call a routine? That would be one +way to solve the problem, the other is to keep DSW up-to-date all the time). + +* Update 2003-02-08: Fixed error in declaration of array list_save, pointed + out by Ray Comas. * Update 2002-02-29: Added deck-list option. If you issue an attach command and specify the filename as "@filename", the named file is interpreted @@ -436,8 +441,9 @@ static char tempfile[128]; static int cardnum; static int any_punched = 0; -#define MAXARG 80 /* saved arguments to attach command */ -static char list_save[MAXARG][10], *list_arg[MAXARG]; +#define MAXARGLEN 80 /* max length of a saved attach command argument */ +#define MAXARGS 10 /* max number of arguments to save */ +static char list_save[MAXARGS][MAXARGLEN], *list_arg[MAXARGLEN]; static int list_nargs = 0; static int16 punchstation[80]; @@ -497,12 +503,12 @@ t_stat set_active_cr_code (int match) return SCPE_OK; } -t_stat cr_set_code (UNIT *uptr, int32 match, char *cptr, void *desc) +static t_stat cr_set_code (UNIT *uptr, int32 match, char *cptr, void *desc) { return set_active_cr_code(match); } -t_stat cp_set_code (UNIT *uptr, int32 match, char *cptr, void *desc) +static t_stat cp_set_code (UNIT *uptr, int32 match, char *cptr, void *desc) { CPCODE *code; int ncode; @@ -964,7 +970,6 @@ static t_stat cr_attach (UNIT *uptr, char *cptr) // no - don't cancel pending read? // sim_cancel(uptr); /* cancel pending operations */ - CLRBIT(uptr->flags, UNIT_QUIET|UNIT_DEBUG); /* set debug/quiet flags */ if (sim_switches & SWMASK('D')) SETBIT(uptr->flags, UNIT_DEBUG); else if (sim_switches & SWMASK('Q')) SETBIT(uptr->flags, UNIT_QUIET); @@ -972,15 +977,15 @@ static t_stat cr_attach (UNIT *uptr, char *cptr) cr_detach(uptr); /* detach file and possibly deckfile */ CLRBIT(uptr->flags, UNIT_SCRATCH); - c = cptr; - for (list_nargs = 0; list_nargs < 10; ) { /* extract arguments */ + c = cptr; /* extract arguments */ + for (list_nargs = 0; list_nargs < MAXARGS; list_nargs++) { while (*c && (*c <= ' ')) /* skip blanks */ c++; + if (! *c) break; /* all done */ arg = c; /* save start */ - while (*c && (*c > ' ')) { if (*c == '\'' || *c == '"') { /* quoted string */ for (quote = *c++; *c;) @@ -989,11 +994,12 @@ static t_stat cr_attach (UNIT *uptr, char *cptr) } else c++; } + if (*c) *c++ = 0; /* term arg at space */ list_arg[list_nargs] = list_save[list_nargs]; /* set pointer to permanent storage location */ - strncpy(list_arg[list_nargs++], arg, MAXARG); /* store copy */ + strncpy(list_arg[list_nargs], arg, MAXARGLEN); /* store copy */ } if (list_nargs <= 0) /* need at least 1 */ diff --git a/Ibm1130/ibm1130_defs.h b/Ibm1130/ibm1130_defs.h index 513bddfe..76d81cfe 100644 --- a/Ibm1130/ibm1130_defs.h +++ b/Ibm1130/ibm1130_defs.h @@ -271,7 +271,7 @@ void remark_cmd (char *remark); void stuff_cmd (char *cmd); void update_gui (t_bool force); void sim_init (void); -t_stat register_cmd (char *name, t_stat (*action)(), int arg, char *help); +t_stat register_cmd (char *name, t_stat (*action)(int32, char *), int arg, char *help); /* GUI interface routines */ t_bool keyboard_is_locked (void); diff --git a/Ibm1130/ibm1130_stddev.c b/Ibm1130/ibm1130_stddev.c index 464bb958..8d811340 100644 --- a/Ibm1130/ibm1130_stddev.c +++ b/Ibm1130/ibm1130_stddev.c @@ -188,7 +188,7 @@ static void Beep (void) // notify user keyboard was locked or key was bad // tti_svc - keyboard polling (never stops) -t_stat tti_svc (UNIT *uptr) +static t_stat tti_svc (UNIT *uptr) { int32 temp; @@ -243,7 +243,7 @@ t_stat tti_svc (UNIT *uptr) return SCPE_OK; } -t_stat tti_reset (DEVICE *dptr) +static t_stat tti_reset (DEVICE *dptr) { tti_unit.buf = 0; tti_dsw = 0; @@ -262,7 +262,7 @@ t_bool keyboard_is_locked (void) /* return TRUE if keyboard is not expecting return (tti_dsw & TT_DSW_KEYBOARD_BUSY) == 0; } -t_stat tto_svc (UNIT *uptr) +static t_stat tto_svc (UNIT *uptr) { int32 temp; int ch; @@ -300,7 +300,7 @@ t_stat tto_svc (UNIT *uptr) return SCPE_OK; } -t_stat tto_reset (DEVICE *dptr) +static t_stat tto_reset (DEVICE *dptr) { tto_unit.buf = 0; tto_dsw = 0; diff --git a/Ibm1130/readme_update.txt b/Ibm1130/readme_update.txt index 53400d1d..6bb2682e 100644 --- a/Ibm1130/readme_update.txt +++ b/Ibm1130/readme_update.txt @@ -1,3 +1,12 @@ +Version: 18 March 2003 + +History (partial): + +2003-03-18 Fixed bug in asm1130 that produced an error message + with a (legal) offset of +127 in MDX instructions. + + Fixed sign bug in 1130 emulator divide instruction. + Interim 1130 distribution: -------------------------------------------- diff --git a/Interdata/id16_cpu.c b/Interdata/id16_cpu.c index d7c28260..7f0eae34 100644 --- a/Interdata/id16_cpu.c +++ b/Interdata/id16_cpu.c @@ -1,6 +1,6 @@ /* id16_cpu.c: Interdata 16b CPU simulator - Copyright (c) 2000-2002, Robert M. Supnik + Copyright (c) 2000-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -1683,7 +1683,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || ((val & 0xFFF) != 0) || (((uint32) val) > ((uptr->flags & UNIT_816E)? MAXMEMSIZE16E: MAXMEMSIZE16))) @@ -1700,7 +1700,7 @@ return SCPE_OK; t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc) { -t_addr i; +uint32 i; if (!(val & UNIT_816E) && (MEMSIZE > MAXMEMSIZE16)) { MEMSIZE = MAXMEMSIZE16; diff --git a/Interdata/id16_dboot.c b/Interdata/id16_dboot.c index cba6c382..edbc9c0a 100644 --- a/Interdata/id16_dboot.c +++ b/Interdata/id16_dboot.c @@ -1,6 +1,6 @@ /* id16_dboot.c: Interdata 16b simulator disk bootstrap - Copyright (c) 2000-2002, Robert M. Supnik + Copyright (c) 2000-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/Interdata/id32_cpu.c b/Interdata/id32_cpu.c index 130d0268..a0846485 100644 --- a/Interdata/id32_cpu.c +++ b/Interdata/id32_cpu.c @@ -1993,7 +1993,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { uint32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE32) || ((val & 0xFFFF) != 0)) return SCPE_ARG; diff --git a/Interdata/id_defs.h b/Interdata/id_defs.h index 15d49296..6fd75068 100644 --- a/Interdata/id_defs.h +++ b/Interdata/id_defs.h @@ -1,6 +1,6 @@ /* id_defs.h: Interdata 16b/32b simulator definitions - Copyright (c) 2000-2002, Robert M. Supnik + Copyright (c) 2000-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,8 @@ The author gratefully acknowledges the help of Carl Friend and Al Kossow, who provided key documents about the Interdata product line. + 21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict + 25-Apr-03 RMS Revised for extended file support 28-Feb-03 RMS Changed magtape device default to 0x85 */ @@ -52,7 +54,7 @@ #define PAMASK32 (MAXMEMSIZE32 - 1) #define MEMSIZE (cpu_unit.capac) /* act memory size */ -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) /* Single precision floating point registers */ @@ -171,8 +173,8 @@ typedef struct dpr dpr_t; struct BlockIO { uint32 dfl; /* devno, flags */ - t_addr cur; /* current addr */ - t_addr end; /* end addr */ + uint32 cur; /* current addr */ + uint32 end; /* end addr */ }; #define BL_RD 0x8000 /* block read */ @@ -466,7 +468,7 @@ typedef struct interdib DIB; /* Function prototypes */ -int32 int_chg (uint32 irq, int32 dat, int32 arm); +int32 int_chg (uint32 irq, int32 dat, int32 armdis); int32 io_2b (int32 val, int32 pos, int32 old); uint32 IOReadB (uint32 loc); void IOWriteB (uint32 loc, uint32 val); diff --git a/Interdata/id_doc.txt b/Interdata/id_doc.txt index 7bb2d0b1..5c9d677a 100644 --- a/Interdata/id_doc.txt +++ b/Interdata/id_doc.txt @@ -46,8 +46,8 @@ sim/ sim_defs.h sim_tmxr.c sim/interdata/ id_defs.h - id16_cpu.c [or id32_cpu.c] - id16_dboot.c [or id32_dboot.c] + id16_cpu.c [id32_cpu.c] + id16_dboot.c [id32_dboot.c] id_dp.c id_fd.c id_fp.c @@ -60,7 +60,7 @@ sim/interdata/ id_defs.h id_tt.c id_ttp.c id_uvc.c - id16_sys.c [or id32_sys.c] + id16_sys.c [id32_sys.c] 2. Interdata Features @@ -235,9 +235,6 @@ control registers for the interrupt system. R0..R15 32 active general register set GREG[32] 32 general register sets, 16 x 2 FR0..FR14 32 single precision floating point registers - if double precision floating point; for - microcoded floating point, floating point - registers are kept in memory locations 00 - 1F D0H..D14H 32 double precision floating point registers, high order D0L..D14L 32 double precision floating point registers, @@ -521,8 +518,8 @@ The programmable interval clock (PIC) implements these registers: IENB 1 clock interrupt enable IARM 1 clock interrupt armed -If the interval requested is longer than 1 msec, and a multiple of -1 msec, the programmable clock auto-calibrates; if not, it simply +If the interval requested is an exact multiple of 1 msec, the +programmable clock auto-calibrates; if not, it simply counts counts instructions. 2.4.7 Floppy Disk Controller (FD) @@ -587,7 +584,7 @@ or 8B. In UC mode, lower case input and output characters are converted automatically to upper case. In 7B mode, input and output characters are masked to 7 bits. In 8B mode, characters are not modified. The default mode is UC. Each line (each unit of PASL) can also be set for modem -control with the command SET PASLn DATASET. The defaults are UC mode +control with the command SET PASLn DATASET. The defaults are 7b mode and DATASET disabled. Once PAS is attached and the simulator is running, the terminals listen diff --git a/Interdata/id_dp.c b/Interdata/id_dp.c index f595620d..ea7ab2e3 100644 --- a/Interdata/id_dp.c +++ b/Interdata/id_dp.c @@ -25,6 +25,7 @@ dp M46-421 2.5MB/10MB cartridge disk + 25-Apr-03 RMS Revised for extended file support 16-Feb-03 RMS Fixed read to test transfer ok before selch operation */ @@ -151,7 +152,7 @@ uint32 dpd_arm[DP_NUMDR] = { 0 }; /* drives armed */ int32 dp_stime = 100; /* seek latency */ int32 dp_rtime = 100; /* rotate latency */ int32 dp_wtime = 1; /* word time */ -int32 dp_log = 0; /* debug log */ +uint32 dp_log = 0; /* debug log */ uint8 dp_tplte[(2 * DP_NUMDR) + 2]; /* fix/rmv + ctrl + end */ DEVICE dp_dev; @@ -210,7 +211,7 @@ REG dp_reg[] = { DP_NUMDR, REG_RO) }, { URDATA (UST, dp_unit[0].STD, 16, 8, 0, DP_NUMDR, REG_RO) }, - { URDATA (CAPAC, dp_unit[0].capac, 10, 31, 0, + { URDATA (CAPAC, dp_unit[0].capac, 10, T_ADDR_W, 0, DP_NUMDR, PV_LEFT | REG_HRO) }, { FLDATA (LOG, dp_log, 0), REG_HIDDEN }, { HRDATA (DEVNO, dp_dib.dno, 8), REG_HRO }, @@ -513,9 +514,10 @@ uint32 i, p; t_stat r; uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; -r = attach_unit (uptr, cptr); +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) return r; /* error? */ uptr->CYL = 0; -if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r; +if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */ if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK; for (i = 0; drv_tab[i].surf != 0; i++) { diff --git a/Interdata/id_fd.c b/Interdata/id_fd.c index 0cc0731d..a15b71e2 100644 --- a/Interdata/id_fd.c +++ b/Interdata/id_fd.c @@ -1,6 +1,6 @@ /* id_fd.c: Interdata floppy disk simulator - Copyright (c) 2001-2002, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -275,8 +275,7 @@ return 0; t_stat fd_svc (UNIT *uptr) { -uint32 i, u, tk, sc, crc, fnc; -t_addr da; +uint32 i, u, tk, sc, crc, fnc, da; u = uptr - fd_dev.units; /* get unit number */ fnc = GET_FNC (uptr->FNC); /* get function */ diff --git a/Interdata/id_fp.c b/Interdata/id_fp.c index fa44469d..24136f72 100644 --- a/Interdata/id_fp.c +++ b/Interdata/id_fp.c @@ -1,6 +1,6 @@ /* id_fp.c: Interdata floating point instructions - Copyright (c) 2000-2002, Robert M. Supnik + Copyright (c) 2000-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/Interdata/id_idc.c b/Interdata/id_idc.c index 198db9a8..97f40bb7 100644 --- a/Interdata/id_idc.c +++ b/Interdata/id_idc.c @@ -25,6 +25,7 @@ idc MSM/IDC disk controller + 25-Apr-03 RMS Revised for extended file support 16-Feb-03 RMS Fixed read to test transfer ok before selch operation Note: define flag ID_IDC to enable the extra functions of the intelligent @@ -273,7 +274,7 @@ REG idc_reg[] = { ID_NUMDR, REG_HRO) }, { URDATA (UST, idc_unit[0].STD, 16, 8, 0, ID_NUMDR, REG_RO) }, - { URDATA (CAPAC, idc_unit[0].capac, 10, 31, 0, + { URDATA (CAPAC, idc_unit[0].capac, 10, T_ADDR_W, 0, ID_NUMDR, PV_LEFT | REG_HRO) }, { HRDATA (DEVNO, idc_dib.dno, 8), REG_HRO }, { HRDATA (SELCH, idc_dib.sch, 2), REG_HRO }, @@ -668,9 +669,10 @@ uint32 i, p; t_stat r; uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; -r = attach_unit (uptr, cptr); +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) return r; /* error? */ uptr->CYL = 0; -if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r; +if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */ if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK; for (i = 0; drv_tab[i].surf != 0; i++) { diff --git a/Interdata/id_io.c b/Interdata/id_io.c index cfa38ae9..88c7d25f 100644 --- a/Interdata/id_io.c +++ b/Interdata/id_io.c @@ -1,6 +1,6 @@ /* id_io.c: Interdata CPU-independent I/O routines - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,8 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict + Interdata I/O devices are defined by a device information block: dno base device number @@ -391,7 +393,7 @@ return 0; /* Update device interrupt status */ -int32 int_chg (uint32 irq, int32 dat, int32 arm) +int32 int_chg (uint32 irq, int32 dat, int32 armdis) { int32 t = CMD_GETINT (dat); /* get int ctrl */ @@ -405,7 +407,7 @@ if (t == CMD_IDSA) { /* disarm? */ CLR_ENB (irq); CLR_INT (irq); return 0; } -return arm; +return armdis; } /* Process a 2b field and return unchanged, set, clear, complement */ diff --git a/Interdata/id_lp.c b/Interdata/id_lp.c index 6f1d97a3..da118ebf 100644 --- a/Interdata/id_lp.c +++ b/Interdata/id_lp.c @@ -1,6 +1,6 @@ /* id_lp.c: Interdata line printer - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -24,6 +24,8 @@ in this Software without prior written authorization from Robert M Supnik. lpt M46-206 line printer + + 25-Apr-03 RMS Revised for extended file support */ #include "id_defs.h" @@ -94,7 +96,7 @@ REG lpt_reg[] = { { FLDATA (IREQ, int_req[l_LPT], i_LPT) }, { FLDATA (IENB, int_enb[l_LPT], i_LPT) }, { FLDATA (IARM, lpt_arm, 0) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (CTIME, lpt_ctime, 24), PV_LEFT }, { DRDATA (STIME, lpt_stime, 24), PV_LEFT }, { FLDATA (STOP_IOE, lpt_stopioe, 0) }, diff --git a/Interdata/id_mt.c b/Interdata/id_mt.c index eb98c6f4..61d671f7 100644 --- a/Interdata/id_mt.c +++ b/Interdata/id_mt.c @@ -25,6 +25,8 @@ mt M46-494 dual density 9-track magtape controller + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support 28-Feb-03 RMS Revised for magtape library 20-Feb-03 RMS Fixed read to stop selch on error @@ -135,7 +137,7 @@ REG mt_reg[] = { { DRDATA (RTIME, mt_rtime, 24), PV_LEFT + REG_NZ }, { URDATA (UST, mt_unit[0].UST, 16, 8, 0, MT_NUMDR, 0) }, { URDATA (CMD, mt_unit[0].UCMD, 16, 8, 0, MT_NUMDR, 0) }, - { URDATA (POS, mt_unit[0].pos, 10, 32, 0, + { URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0, MT_NUMDR, PV_LEFT | REG_RO) }, { HRDATA (DEVNO, mt_dib.dno, 8), REG_HRO }, { HRDATA (SELCH, mt_dib.sch, 1), REG_HRO }, @@ -144,6 +146,8 @@ REG mt_reg[] = { MTAB mt_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_dev, &show_dev, NULL }, { MTAB_XTD|MTAB_VDV, 0, "SELCH", "SELCH", diff --git a/Interdata/id_pas.c b/Interdata/id_pas.c index b89ff6ef..03591711 100644 --- a/Interdata/id_pas.c +++ b/Interdata/id_pas.c @@ -25,6 +25,8 @@ pas Programmable asynchronous line adapter(s) + 09-May-03 RMS Added network device flag + This module implements up to 32 individual serial interfaces, representing either individual PASLA modules or combinations of the 2-line and 8-line multiplexors, which are functionally very similar. These interfaces are mapped @@ -160,7 +162,7 @@ DEVICE pas_dev = { 1, 10, 31, 1, 16, 8, &tmxr_ex, &tmxr_dep, &pas_reset, NULL, &pas_attach, &pas_detach, - &pas_dib, DEV_DISABLE }; + &pas_dib, DEV_NET | DEV_DISABLE }; /* PASL data structures diff --git a/Interdata/id_pt.c b/Interdata/id_pt.c index cd8969f5..8a499e6a 100644 --- a/Interdata/id_pt.c +++ b/Interdata/id_pt.c @@ -1,6 +1,6 @@ /* id_pt.c: Interdata paper tape reader - Copyright (c) 2000-2001, Robert M. Supnik + Copyright (c) 2000-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -24,6 +24,9 @@ in this Software without prior written authorization from Robert M Supnik. pt paper tape reader and punch + + 25-Apr-03 RMS Revised for extended file support + 10-Apr-03 RMS Fixed type problem in ptr service (from Mark Pizzolato) */ #include "id_defs.h" @@ -76,11 +79,11 @@ UNIT pt_unit[] = { REG pt_reg[] = { { HRDATA (STA, pt_sta, 8) }, { HRDATA (RBUF, pt_unit[PTR].buf, 8) }, - { DRDATA (RPOS, pt_unit[PTR].pos, 32), PV_LEFT }, + { DRDATA (RPOS, pt_unit[PTR].pos, T_ADDR_W), PV_LEFT }, { DRDATA (RTIME, pt_unit[PTR].wait, 24), PV_LEFT }, { FLDATA (RSTOP_IOE, ptr_stopioe, 0) }, { HRDATA (PBUF, pt_unit[PTP].buf, 8) }, - { DRDATA (PPOS, pt_unit[PTP].pos, 32), PV_LEFT }, + { DRDATA (PPOS, pt_unit[PTP].pos, T_ADDR_W), PV_LEFT }, { DRDATA (PTIME, pt_unit[PTP].wait, 24), PV_LEFT }, { FLDATA (PSTOP_IOE, ptp_stopioe, 0) }, { FLDATA (IREQ, int_req[l_PT], i_PT) }, @@ -164,7 +167,7 @@ return 0; t_stat ptr_svc (UNIT *uptr) { -uint32 temp; +int32 temp; if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ return IORETURN (ptr_stopioe, SCPE_UNATT); @@ -324,8 +327,7 @@ static uint8 load_rom[] = { t_stat pt_dump (FILE *of, char *cptr, char *fnam) { -t_addr i, lo, hi; -uint32 cs; +uint32 i, lo, hi, cs; char *tptr; extern DEVICE cpu_dev; diff --git a/Interdata/id_tt.c b/Interdata/id_tt.c index 2a4c0ba6..9c72778f 100644 --- a/Interdata/id_tt.c +++ b/Interdata/id_tt.c @@ -25,6 +25,7 @@ tt console + 25-Apr-03 RMS Revised for extended file support 11-Jan-03 RMS Added TTP support 22-Dec-02 RMS Added break support */ @@ -83,10 +84,10 @@ UNIT tt_unit[] = { REG tt_reg[] = { { HRDATA (STA, tt_sta, 8) }, { HRDATA (KBUF, tt_unit[TTI].buf, 8) }, - { DRDATA (KPOS, tt_unit[TTI].pos, 32), PV_LEFT }, + { DRDATA (KPOS, tt_unit[TTI].pos, T_ADDR_W), PV_LEFT }, { DRDATA (KTIME, tt_unit[TTI].wait, 24), REG_NZ + PV_LEFT }, { HRDATA (TBUF, tt_unit[TTO].buf, 8) }, - { DRDATA (TPOS, tt_unit[TTO].pos, 32), PV_LEFT }, + { DRDATA (TPOS, tt_unit[TTO].pos, T_ADDR_W), PV_LEFT }, { DRDATA (TTIME, tt_unit[TTO].wait, 24), REG_NZ + PV_LEFT }, { FLDATA (IREQ, int_req[l_TT], i_TT) }, { FLDATA (IENB, int_enb[l_TT], i_TT) }, diff --git a/Interdata/id_ttp.c b/Interdata/id_ttp.c index 9add8b27..b2f2e857 100644 --- a/Interdata/id_ttp.c +++ b/Interdata/id_ttp.c @@ -24,6 +24,8 @@ in this Software without prior written authorization from Robert M Supnik. ttp console (on PAS) + + 25-Apr-03 RMS Revised for extended file support */ #include "id_defs.h" @@ -83,14 +85,14 @@ UNIT ttp_unit[] = { REG ttp_reg[] = { { HRDATA (CMD, ttp_cmd, 16) }, { HRDATA (KBUF, ttp_unit[TTI].buf, 8) }, - { DRDATA (KPOS, ttp_unit[TTI].pos, 32), PV_LEFT }, + { DRDATA (KPOS, ttp_unit[TTI].pos, T_ADDR_W), PV_LEFT }, { DRDATA (KTIME, ttp_unit[TTI].wait, 24), REG_NZ + PV_LEFT }, { FLDATA (KIREQ, int_req[l_TTP], i_TTP) }, { FLDATA (KIENB, int_enb[l_TTP], i_TTP) }, { FLDATA (KARM, ttp_karm, 0) }, { FLDATA (CHP, ttp_kchp, 0) }, { HRDATA (TBUF, ttp_unit[TTO].buf, 8) }, - { DRDATA (TPOS, ttp_unit[TTO].pos, 32), PV_LEFT }, + { DRDATA (TPOS, ttp_unit[TTO].pos, T_ADDR_W), PV_LEFT }, { DRDATA (TTIME, ttp_unit[TTO].wait, 24), REG_NZ + PV_LEFT }, { FLDATA (TIREQ, int_req[l_TTP], i_TTP + 1) }, { FLDATA (TIENB, int_enb[l_TTP], i_TTP + 1) }, diff --git a/Interdata/id_uvc.c b/Interdata/id_uvc.c index ffc6bf2b..24dcd7cf 100644 --- a/Interdata/id_uvc.c +++ b/Interdata/id_uvc.c @@ -1,6 +1,6 @@ /* id_uvc.c: Interdata universal clock - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/NOVA/eclipse_cpu.c b/NOVA/eclipse_cpu.c index 8972e9bd..76ab2ead 100644 --- a/NOVA/eclipse_cpu.c +++ b/NOVA/eclipse_cpu.c @@ -2,7 +2,7 @@ Modified from the original NOVA simulator by Robert Supnik. - Copyright (c) 1998-2002, Charles E Owen + Copyright (c) 1998-2003, Charles E Owen Portions Copyright (c) 1993-2002, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a @@ -2953,7 +2953,7 @@ int32 pushrtn(int32 pc) int32 GetMap(int32 addr) { int32 page; - t_addr paddr; + uint32 paddr; switch (Usermap) { case 0: @@ -3015,7 +3015,7 @@ int32 GetMap(int32 addr) int32 PutMap(int32 addr, int32 data) { int32 page; - t_addr paddr; + uint32 paddr; switch (Usermap) { case 0: @@ -3060,7 +3060,7 @@ int32 PutMap(int32 addr, int32 data) #if 0 int16 GetDCHMap(int32 map, int32 addr) { - t_addr paddr; + uint32 paddr; if (!(MapStat & 02)) return M[addr]; paddr = ((Map[map][(addr >> 10) & 037] & PAGEMASK) << 10) | (addr & 001777); if (paddr < MEMSIZE) @@ -3070,7 +3070,7 @@ int16 GetDCHMap(int32 map, int32 addr) int16 PutDCHMap(int32 map, int32 addr, int16 data) { - t_addr paddr; + uint32 paddr; if (!(MapStat & 02)) { M[addr] = data; return (data); @@ -3192,7 +3192,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) return SCPE_ARG; diff --git a/NOVA/eclipse_tt.c b/NOVA/eclipse_tt.c index 58ddccf6..972d80f7 100644 --- a/NOVA/eclipse_tt.c +++ b/NOVA/eclipse_tt.c @@ -1,6 +1,6 @@ /* eclipse_tt.c: Eclipse console terminal simulator - Copyright (c) 1998-2002, Charles E Owen + Copyright (c) 1998-2003, Charles E Owen Portions copyright (c) 1993-2002, Robert M Supnik Written by Charles Owen, used by gracious permission Commercial use prohibited @@ -8,6 +8,7 @@ tti terminal input tto terminal output + 25-Apr-03 RMS Revised for extended file support 03-Oct-02 RMS Added DIBs 30-May-02 RMS Widened POS to 32b 28-Jan-02 RMS Cleaned up compiler warnings @@ -49,7 +50,7 @@ REG tti_reg[] = { { FLDATA (DONE, dev_done, INT_V_TTI) }, { FLDATA (DISABLE, dev_disable, INT_V_TTI) }, { FLDATA (INT, int_req, INT_V_TTI) }, - { DRDATA (POS, tti_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; @@ -82,7 +83,7 @@ REG tto_reg[] = { { FLDATA (DONE, dev_done, INT_V_TTO) }, { FLDATA (DISABLE, dev_disable, INT_V_TTO) }, { FLDATA (INT, int_req, INT_V_TTO) }, - { DRDATA (POS, tto_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT }, { NULL } }; diff --git a/NOVA/nova_cpu.c b/NOVA/nova_cpu.c index b61d9216..864786d7 100644 --- a/NOVA/nova_cpu.c +++ b/NOVA/nova_cpu.c @@ -674,9 +674,9 @@ else { /* IOT */ case ioDOC: if ((dstAC == 2) && (cpu_unit.flags & UNIT_MDV)) { uint32 mddata, uAC0, uAC1, uAC2; - uAC0 = (unsigned int32) AC[0]; - uAC1 = (unsigned int32) AC[1]; - uAC2 = (unsigned int32) AC[2]; + uAC0 = (uint32) AC[0]; + uAC1 = (uint32) AC[1]; + uAC2 = (uint32) AC[2]; if (pulse == iopP) { /* mul */ mddata = (uAC1 * uAC2) + uAC0; AC[0] = (mddata >> 16) & DMASK; @@ -704,8 +704,8 @@ else { /* IOT */ C = CBIT; else C = 0; AC[0] = AC[0] & DMASK; } } } - break; } /* end case code */ - } /* end if mul/div */ + break; } /* end case code */ + } /* end if mul/div */ /* IOT, continued */ diff --git a/NOVA/nova_defs.h b/NOVA/nova_defs.h index abbc40a7..fdad7f22 100644 --- a/NOVA/nova_defs.h +++ b/NOVA/nova_defs.h @@ -61,7 +61,7 @@ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ #define A_V_IND 15 /* ind: indirect */ #define A_IND (1 << A_V_IND) -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) /* Architectural constants */ diff --git a/NOVA/nova_dkp.c b/NOVA/nova_dkp.c index 5e2aec00..9dd91026 100644 --- a/NOVA/nova_dkp.c +++ b/NOVA/nova_dkp.c @@ -1,6 +1,6 @@ /* nova_dkp.c: NOVA moving head disk simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ dkp moving head disk + 25-Apr-03 RMS Revised autosizing 08-Oct-02 RMS Added DIB 06-Jan-02 RMS Revised enable/disable support 30-Nov-01 RMS Added read only unit, extended SET/SHOW support @@ -76,10 +77,10 @@ #define USSC_M_UNIT 03 #define USSC_UNIT (USSC_M_UNIT << USSC_V_UNIT) #define GET_COUNT(x) (((x) >> USSC_V_COUNT) & USSC_M_COUNT) -#define GET_SECT(x,dt) ((drv_tab[dt].new)? \ +#define GET_SECT(x,dt) ((drv_tab[dt].newf)? \ (((x) >> USSC_V_NSECTOR) & USSC_M_NSECTOR): \ (((x) >> USSC_V_OSECTOR) & USSC_M_OSECTOR) ) -#define GET_SURF(x,dt) ((drv_tab[dt].new)? \ +#define GET_SURF(x,dt) ((drv_tab[dt].newf)? \ (((x) >> USSC_V_NSURFACE) & USSC_M_NSURFACE): \ (((x) >> USSC_V_OSURFACE) & USSC_M_OSURFACE) ) #define GET_UNIT(x) (((x) >> USSC_V_UNIT) & USSC_M_UNIT) @@ -105,10 +106,10 @@ #define FCCY_SEEK 2 #define FCCY_RECAL 3 #define FCCY_FLAGS 0174000 /* flags */ -#define GET_CMD(x,dt) ((drv_tab[dt].new)? \ +#define GET_CMD(x,dt) ((drv_tab[dt].newf)? \ (((x) >> FCCY_V_NCMD) & FCCY_M_NCMD): \ (((x) >> FCCY_V_OCMD) & FCCY_M_OCMD) ) -#define GET_CYL(x,dt) ((drv_tab[dt].new)? \ +#define GET_CYL(x,dt) ((drv_tab[dt].newf)? \ (((x) >> FCCY_V_NCYL) & FCCY_M_NCYL): \ ((((x) >> FCCY_V_OCYL) & FCCY_M_OCYL) | \ ((dt != TYPE_D44)? 0: \ @@ -254,7 +255,7 @@ struct drvtyp { int32 surf; /* surfaces */ int32 cyl; /* cylinders */ int32 size; /* #blocks */ - int32 new; /* new format flag */ + int32 newf; /* new format flag */ }; struct drvtyp drv_tab[] = { @@ -323,7 +324,7 @@ REG dkp_reg[] = { { FLDATA (DISABLE, dev_disable, INT_V_DKP) }, { DRDATA (STIME, dkp_swait, 24), PV_LEFT }, { DRDATA (RTIME, dkp_rwait, 24), PV_LEFT }, - { URDATA (CAPAC, dkp_unit[0].capac, 10, 31, 0, + { URDATA (CAPAC, dkp_unit[0].capac, 10, T_ADDR_W, 0, DKP_NUMDR, PV_LEFT | REG_HRO) }, { NULL } }; @@ -460,7 +461,7 @@ case ioDIB: /* DIB */ break; case ioDOB: /* DOB */ if ((dev_busy & INT_DKP) == 0) dkp_ma = - AC & (drv_tab[dtype].new? DMASK: AMASK); + AC & (drv_tab[dtype].newf? DMASK: AMASK); break; case ioDIC: /* DIC */ rval = dkp_ussc; /* return unit, sect */ @@ -576,7 +577,7 @@ else if ((uptr->CYL >= drv_tab[dtype].cyl) || /* bad cylinder */ (GET_SECT (dkp_ussc, dtype) >= drv_tab[dtype].sect)) /* or bad sector? */ dkp_sta = dkp_sta | STA_DONE | STA_ERR | STA_UNS; -else if (GET_CYL (dkp_fccy, dtype) != uptr->CYL) /* address error? */ +else if (GET_CYL (dkp_fccy, dtype) != uptr->CYL) /* address error? */ dkp_sta = dkp_sta | STA_DONE | STA_ERR | STA_UNS; else { sc = 16 - GET_COUNT (dkp_ussc); /* get sector count */ @@ -618,7 +619,7 @@ else { sc = 16 - GET_COUNT (dkp_ussc); /* get sector count */ newsect = sa % drv_tab[dtype].sect; newsurf = (sa / drv_tab[dtype].sect) % drv_tab[dtype].surf; dkp_ussc = (dkp_ussc & USSC_UNIT) | ((dkp_ussc + sc) & USSC_M_COUNT) | - ((drv_tab[dtype].new)? + ((drv_tab[dtype].newf)? ((newsurf << USSC_V_NSURFACE) | (newsect << USSC_V_NSECTOR)): ((newsurf << USSC_V_OSURFACE) | (newsect << USSC_V_OSECTOR)) ); dkp_sta = dkp_sta | STA_DONE; } /* set status */ @@ -716,7 +717,7 @@ for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i]; unitno = unitno & USSC_M_UNIT; dtype = GET_DTYPE (dkp_unit[unitno].flags); M[BOOT_UNIT] = M[BOOT_UNIT] | (unitno << USSC_V_UNIT); -if (drv_tab[dtype].new) M[BOOT_SEEK] = 0176000; +if (drv_tab[dtype].newf) M[BOOT_SEEK] = 0176000; saved_PC = BOOT_START; return SCPE_OK; } diff --git a/NOVA/nova_dsk.c b/NOVA/nova_dsk.c index c7998fab..c8832e7d 100644 --- a/NOVA/nova_dsk.c +++ b/NOVA/nova_dsk.c @@ -25,6 +25,7 @@ dsk fixed head disk + 14-Mar-03 RMS Fixed variable capacity interaction with save/restore 03-Mar-03 RMS Fixed variable capacity and autosizing 03-Oct-02 RMS Added DIB 06-Jan-02 RMS Revised enable/disable support @@ -44,6 +45,7 @@ #define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */ #define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */ #define UNIT_M_PLAT 07 +#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT) #define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1) #define UNIT_AUTO (1 << UNIT_V_AUTO) #define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT) @@ -184,7 +186,7 @@ if ((pulse == iopP) && ((dsk_wlk >> GET_DISK (dsk_da)) & 1)) { /* wrt lock? */ return rval; } if (pulse & 1) { /* read or write? */ - if (((t_addr) (dsk_da * DSK_NUMWD)) >= dsk_unit.capac) { /* inv sev? */ + if (((uint32) (dsk_da * DSK_NUMWD)) >= dsk_unit.capac) { /* inv sev? */ dev_done = dev_done | INT_DSK; /* set done */ int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable); dsk_stat = DSKS_ERR + DSKS_NSD; /* set status */ @@ -222,7 +224,7 @@ if (uptr->FUNC == iopP) { /* write? */ for (i = 0; i < DSK_NUMWD; i++) { /* copy sector */ pa = MapAddr (0, (dsk_ma + i) & AMASK); /* map address */ *(((int16 *) uptr->filebuf) + da + i) = M[pa]; } - if (((t_addr) (da + i)) >= uptr->hwmark) /* past end? */ + if (((uint32) (da + i)) >= uptr->hwmark) /* past end? */ uptr->hwmark = da + i + 1; /* upd hwmark */ dsk_ma = (dsk_ma + DSK_NUMWD + 3) & AMASK; } @@ -271,15 +273,15 @@ return SCPE_OK; t_stat dsk_attach (UNIT *uptr, char *cptr) { -t_addr sz, p; -t_addr ds_bytes = DSK_DKSIZE * sizeof (int16); +uint32 sz, p; +uint32 ds_bytes = DSK_DKSIZE * sizeof (int16); if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) { p = (sz + ds_bytes - 1) / ds_bytes; - if (p == 0) p = 1; - if (p > DSK_NUMDK) p = DSK_NUMDK; } -else p = UNIT_GETP (uptr->flags); /* get # plat */ -uptr->capac = p * DSK_DKSIZE; /* set capacity */ + if (p >= DSK_NUMDK) p = DSK_NUMDK - 1; + uptr->flags = (uptr->flags & ~UNIT_PLAT) | + (p << UNIT_V_PLAT); } +uptr->capac = UNIT_GETP (uptr->flags) * DSK_DKSIZE; /* set capacity */ return attach_unit (uptr, cptr); } diff --git a/NOVA/nova_lp.c b/NOVA/nova_lp.c index d3c1fcad..36817c27 100644 --- a/NOVA/nova_lp.c +++ b/NOVA/nova_lp.c @@ -1,6 +1,6 @@ /* nova_lp.c: NOVA line printer simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ lpt line printer + 25-Apr-03 RMS Revised for extended file support 30-May-02 RMS Widened POS to 32b */ @@ -56,7 +57,7 @@ REG lpt_reg[] = { { FLDATA (DONE, dev_done, INT_V_LPT) }, { FLDATA (DISABLE, dev_disable, INT_V_LPT) }, { FLDATA (INT, int_req, INT_V_LPT) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lpt_stopioe, 0) }, { NULL } }; @@ -106,7 +107,7 @@ if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) { perror ("LPT I/O error"); clearerr (lpt_unit.fileref); return SCPE_IOERR; } -lpt_unit.pos = ftell (lpt_unit.fileref); +lpt_unit.pos = lpt_unit.pos + 1; return SCPE_OK; } diff --git a/NOVA/nova_mta.c b/NOVA/nova_mta.c index 2c46b92c..e965da73 100644 --- a/NOVA/nova_mta.c +++ b/NOVA/nova_mta.c @@ -25,6 +25,8 @@ mta magnetic tape + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support 28-Feb-03 RMS Revised for magtape library 30-Oct-02 RMS Fixed BOT handling, added error record handling 08-Oct-02 RMS Added DIB @@ -203,13 +205,15 @@ REG mta_reg[] = { { DRDATA (CTIME, mta_cwait, 24), PV_LEFT }, { DRDATA (RTIME, mta_rwait, 24), PV_LEFT }, { URDATA (UST, mta_unit[0].USTAT, 8, 32, 0, MTA_NUMDR, 0) }, - { URDATA (POS, mta_unit[0].pos, 8, 32, 0, + { URDATA (POS, mta_unit[0].pos, 8, T_ADDR_W, 0, MTA_NUMDR, REG_RO | PV_LEFT) }, { NULL } }; MTAB mta_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", &mta_vlock }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &mta_vlock }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { 0 } }; DEVICE mta_dev = { diff --git a/NOVA/nova_plt.c b/NOVA/nova_plt.c index 3b9e5bb9..f954733e 100644 --- a/NOVA/nova_plt.c +++ b/NOVA/nova_plt.c @@ -1,6 +1,6 @@ /* nova_plt.c: NOVA plotter simulator - Copyright (c) 2000-2002, Robert M. Supnik + Copyright (c) 2000-2003, Robert M. Supnik Written by Bruce Ray and used with his gracious permission. Permission is hereby granted, free of charge, to any person obtaining a @@ -26,6 +26,7 @@ plt plotter + 25-Apr-03 RMS Revised for extended file support 03-Oct-02 RMS Added DIB 30-May-02 RMS Widened POS to 32b 06-Jan-02 RMS Revised enable/disable support @@ -61,7 +62,7 @@ REG plt_reg[] = { { FLDATA (DONE, dev_done, INT_V_PLT) }, { FLDATA (DISABLE, dev_disable, INT_V_PLT) }, { FLDATA (INT, int_req, INT_V_PLT) }, - { DRDATA (POS, plt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, plt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, plt_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, plt_stopioe, 0) }, { NULL } }; diff --git a/NOVA/nova_pt.c b/NOVA/nova_pt.c index 7085bbc8..33333d91 100644 --- a/NOVA/nova_pt.c +++ b/NOVA/nova_pt.c @@ -1,6 +1,6 @@ /* nova_pt.c: NOVA paper tape read/punch simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,7 @@ ptr paper tape reader ptp paper tape punch + 25-Apr-03 RMS Revised for extended file support 03-Oct-02 RMS Added DIBs 30-May-02 RMS Widened POS to 32b 29-Nov-01 RMS Added read only unit support @@ -63,7 +64,7 @@ REG ptr_reg[] = { { FLDATA (DONE, dev_done, INT_V_PTR) }, { FLDATA (DISABLE, dev_disable, INT_V_PTR) }, { FLDATA (INT, int_req, INT_V_PTR) }, - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptr_stopioe, 0) }, { NULL } }; @@ -93,7 +94,7 @@ REG ptp_reg[] = { { FLDATA (DONE, dev_done, INT_V_PTP) }, { FLDATA (DISABLE, dev_disable, INT_V_PTP) }, { FLDATA (INT, int_req, INT_V_PTP) }, - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptp_stopioe, 0) }, { NULL } }; diff --git a/NOVA/nova_sys.c b/NOVA/nova_sys.c index c874acea..6198ad65 100644 --- a/NOVA/nova_sys.c +++ b/NOVA/nova_sys.c @@ -1,6 +1,6 @@ /* nova_sys.c: NOVA simulator interface - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -127,7 +127,7 @@ const char *sim_stop_messages[] = { t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) { int32 data, csum, count, state, i; -t_addr origin; +uint32 origin; if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; state = 0; diff --git a/NOVA/nova_tt.c b/NOVA/nova_tt.c index 22a2925b..f745b08e 100644 --- a/NOVA/nova_tt.c +++ b/NOVA/nova_tt.c @@ -26,6 +26,7 @@ tti terminal input tto terminal output + 25-Apr-03 RMS Revised for extended file support 05-Jan-02 RMS Fixed calling sequence for setmod 03-Oct-02 RMS Added DIBs 30-May-02 RMS Widened POS to 32b @@ -67,7 +68,7 @@ REG tti_reg[] = { { FLDATA (DONE, dev_done, INT_V_TTI) }, { FLDATA (DISABLE, dev_disable, INT_V_TTI) }, { FLDATA (INT, int_req, INT_V_TTI) }, - { DRDATA (POS, tti_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; @@ -100,7 +101,7 @@ REG tto_reg[] = { { FLDATA (DONE, dev_done, INT_V_TTO) }, { FLDATA (DISABLE, dev_disable, INT_V_TTO) }, { FLDATA (INT, int_req, INT_V_TTO) }, - { DRDATA (POS, tto_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT }, { NULL } }; diff --git a/NOVA/nova_tt1.c b/NOVA/nova_tt1.c index e98c0e54..ea3f1bd3 100644 --- a/NOVA/nova_tt1.c +++ b/NOVA/nova_tt1.c @@ -27,6 +27,7 @@ tti1 second terminal input tto1 second terminal output + 09-May-03 RMS Added network device flag 05-Jan-03 RMS Fixed calling sequence for setmod 03-Oct-02 RMS Added DIBs 22-Aug-02 RMS Updated for changes in sim_tmxr @@ -105,7 +106,7 @@ DEVICE tti1_dev = { 1, 10, 31, 1, 8, 8, &tmxr_ex, &tmxr_dep, &tti1_reset, NULL, &tti1_attach, &tti1_detach, - &tti1_dib, DEV_DISABLE }; + &tti1_dib, DEV_NET | DEV_DISABLE }; /* TTO1 data structures diff --git a/PDP1/pdp1_cpu.c b/PDP1/pdp1_cpu.c index 85fa6c88..21b4988e 100644 --- a/PDP1/pdp1_cpu.c +++ b/PDP1/pdp1_cpu.c @@ -1,6 +1,6 @@ /* pdp1_cpu.c: PDP-1 CPU simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -792,7 +792,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) return SCPE_ARG; diff --git a/PDP1/pdp1_defs.h b/PDP1/pdp1_defs.h index 6fde640d..3a623e9b 100644 --- a/PDP1/pdp1_defs.h +++ b/PDP1/pdp1_defs.h @@ -1,6 +1,6 @@ /* pdp1_defs.h: 18b PDP simulator definitions - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -54,7 +54,7 @@ #define MAXMEMSIZE (1u << ASIZE) /* max mem size */ #define AMASK (MAXMEMSIZE - 1) /* address mask */ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) /* Architectural constants */ diff --git a/PDP1/pdp1_drm.c b/PDP1/pdp1_drm.c index 3346e1e8..9587067f 100644 --- a/PDP1/pdp1_drm.c +++ b/PDP1/pdp1_drm.c @@ -133,7 +133,7 @@ return IO; t_stat drm_svc (UNIT *uptr) { int32 i; -t_addr da; +uint32 da; if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ drm_err = 1; /* set error */ diff --git a/PDP1/pdp1_dt.c b/PDP1/pdp1_dt.c index fd72b409..2e17f824 100644 --- a/PDP1/pdp1_dt.c +++ b/PDP1/pdp1_dt.c @@ -1,6 +1,6 @@ /* pdp1_dt.c: 18b DECtape simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ dt Type 550/555 DECtape + 25-Apr-03 RMS Revised for extended file support + 14-Mar-03 RMS Fixed variable size interaction with save/restore 17-Oct-02 RMS Fixed bug in end of reel logic 06-Oct-02 RMS Added device disable support 13-Aug-02 RMS Cloned from pdp18b_dt.c @@ -309,7 +311,7 @@ REG dt_reg[] = { { ORDATA (SUBSTATE, dt_substate, 2) }, { ORDATA (LOG, dt_log, 4), REG_HIDDEN }, { DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN }, - { URDATA (POS, dt_unit[0].pos, 10, 32, 0, + { URDATA (POS, dt_unit[0].pos, 10, T_ADDR_W, 0, DT_NUMDR, PV_LEFT | REG_RO) }, { URDATA (STATT, dt_unit[0].STATE, 8, 18, 0, DT_NUMDR, REG_RO) }, @@ -622,7 +624,7 @@ int32 fnc = DTS_GETFNC (uptr->STATE); int32 *bptr = uptr->filebuf; int32 unum = uptr - dt_dev.units; int32 blk, wrd, ma, relpos; -t_addr ba; +uint32 ba; /* Motion cases @@ -866,33 +868,35 @@ t_stat dt_attach (UNIT *uptr, char *cptr) { uint16 pdp8b[D8_NBSIZE]; uint16 pdp11b[D18_BSIZE]; -uint32 k, p, *bptr; +uint32 ba, sz, k, *bptr; +int32 u = uptr - dt_dev.units; t_stat r; -t_addr ba; r = attach_unit (uptr, cptr); /* attach */ if (r != SCPE_OK) return r; /* error? */ -uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */ -if (sim_switches & SWMASK ('R')) /* att 12b? */ - uptr->flags = uptr->flags | UNIT_8FMT; -else if (sim_switches & SWMASK ('S')) /* att 16b? */ - uptr->flags = uptr->flags | UNIT_11FMT; -else if (!(sim_switches & SWMASK ('T')) && /* autosize? */ - (fseek (uptr->fileref, 0, SEEK_END) == 0) && - ((p = ftell (uptr->fileref)) != 0)) { - if (p == D8_FILSIZ) uptr->flags = uptr->flags | UNIT_8FMT; - if (p == D11_FILSIZ) uptr->flags = uptr->flags | UNIT_11FMT; } +if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */ + uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */ + if (sim_switches & SWMASK ('R')) /* att 12b? */ + uptr->flags = uptr->flags | UNIT_8FMT; + else if (sim_switches & SWMASK ('S')) /* att 16b? */ + uptr->flags = uptr->flags | UNIT_11FMT; + else if (!(sim_switches & SWMASK ('T')) && /* autosize? */ + (sz = sim_fsize (cptr))) { + if (sz == D8_FILSIZ) + uptr->flags = uptr->flags | UNIT_8FMT; + else if (sz == D11_FILSIZ) + uptr->flags = uptr->flags | UNIT_11FMT; } } uptr->capac = DTU_CAPAC (uptr); /* set capacity */ uptr->filebuf = calloc (uptr->capac, sizeof (int32)); if (uptr->filebuf == NULL) { /* can't alloc? */ detach_unit (uptr); return SCPE_MEM; } bptr = uptr->filebuf; /* file buffer */ -if (uptr->flags & UNIT_8FMT) printf ("DT: 12b format"); -else if (uptr->flags & UNIT_11FMT) printf ("DT: 16b format"); -else printf ("DT: 18b/36b format"); +printf ("%s%d: ", sim_dname (&dt_dev), u); +if (uptr->flags & UNIT_8FMT) printf ("12b format"); +else if (uptr->flags & UNIT_11FMT) printf ("16b format"); +else printf ("18b/36b format"); printf (", buffering file in memory\n"); -rewind (uptr->fileref); /* start of file */ if (uptr->flags & UNIT_8FMT) { /* 12b? */ for (ba = 0; ba < uptr->capac; ) { /* loop thru file */ k = fxread (pdp8b, sizeof (int16), D8_NBSIZE, uptr->fileref); @@ -935,20 +939,19 @@ t_stat dt_detach (UNIT* uptr) { uint16 pdp8b[D8_NBSIZE]; uint16 pdp11b[D18_BSIZE]; -uint32 k, *bptr; -int32 unum = uptr - dt_dev.units; -t_addr ba; +uint32 ba, k, *bptr; +int32 u = uptr - dt_dev.units; if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; if (sim_is_active (uptr)) { sim_cancel (uptr); - if ((unum == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) { + if ((u == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) { dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF; DT_UPDINT; } uptr->STATE = uptr->pos = 0; } bptr = uptr->filebuf; /* file buffer */ if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */ - printf ("DT: writing buffer to file\n"); + printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u); rewind (uptr->fileref); /* start of file */ if (uptr->flags & UNIT_8FMT) { /* 12b? */ for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */ diff --git a/PDP1/pdp1_lp.c b/PDP1/pdp1_lp.c index d5386cdb..4b0b8cda 100644 --- a/PDP1/pdp1_lp.c +++ b/PDP1/pdp1_lp.c @@ -1,6 +1,6 @@ /* pdp1_lp.c: PDP-1 line printer simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ lpt Type 62 line printer for the PDP-1 + 25-Apr-03 RMS Revised for extended file support 30-May-02 RMS Widened POS to 32b 13-Apr-01 RMS Revised for register arrays */ @@ -66,7 +67,7 @@ REG lpt_reg[] = { { FLDATA (RPLS, lpt_rpls, 0) }, { DRDATA (BPTR, bptr, 6) }, { ORDATA (LPT_STATE, lpt_iot, 6), REG_HRO }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lpt_stopioe, 0) }, { BRDATA (LBUF, lpt_buf, 8, 8, LPT_BSIZE) }, diff --git a/PDP1/pdp1_stddev.c b/PDP1/pdp1_stddev.c index 7b2efc0b..7a73abd5 100644 --- a/PDP1/pdp1_stddev.c +++ b/PDP1/pdp1_stddev.c @@ -1,6 +1,6 @@ /* pdp1_stddev.c: PDP-1 standard devices - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,6 +28,7 @@ tti keyboard tto teleprinter + 25-Apr-03 RMS Revised for extended file support 22-Dec-02 RMS Added break support 29-Nov-02 RMS Fixed output flag initialization (found by Derek Peschel) 21-Nov-02 RMS Changed typewriter to half duplex (found by Derek Peschel) @@ -124,7 +125,7 @@ REG ptr_reg[] = { { FLDATA (DONE, iosta, IOS_V_PTR) }, { FLDATA (RPLS, ptr_rpls, 0) }, { ORDATA (STATE, ptr_state, 5), REG_HRO }, - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptr_stopioe, 0) }, { NULL } }; @@ -150,7 +151,7 @@ REG ptp_reg[] = { { ORDATA (BUF, ptp_unit.buf, 8) }, { FLDATA (DONE, iosta, IOS_V_PTP) }, { FLDATA (RPLS, ptp_rpls, 0) }, - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptp_stopioe, 0) }, { NULL } }; @@ -179,11 +180,11 @@ REG tty_reg[] = { { FLDATA (RPLS, tto_rpls, 0) }, { ORDATA (HOLD, tti_hold, 9), REG_HRO }, { FLDATA (KDONE, iosta, IOS_V_TTI) }, + { DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT }, { DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT }, - { DRDATA (KPOS, tty_unit[TTI].pos, 32), PV_LEFT }, { FLDATA (TDONE, iosta, IOS_V_TTO) }, + { DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT }, { DRDATA (TTIME, tty_unit[TTO].wait, 24), PV_LEFT }, - { DRDATA (TPOS, tty_unit[TTO].pos, 32), PV_LEFT }, { NULL } }; DEVICE tty_dev = { diff --git a/PDP1/pdp1_sys.c b/PDP1/pdp1_sys.c index 5a3204ce..5f14d6e7 100644 --- a/PDP1/pdp1_sys.c +++ b/PDP1/pdp1_sys.c @@ -1,6 +1,6 @@ /* pdp1_sys.c: PDP-1 simulator interface - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/PDP10/pdp10_cpu.c b/PDP10/pdp10_cpu.c index 48d37c8c..7ee895d8 100644 --- a/PDP10/pdp10_cpu.c +++ b/PDP10/pdp10_cpu.c @@ -1,6 +1,6 @@ /* pdp10_cpu.c: PDP-10 CPU simulator - Copyright (c) 1993-2002, Robert M. Supnik + Copyright (c) 1993-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/PDP10/pdp10_defs.h b/PDP10/pdp10_defs.h index f27b6d94..a92ef0d0 100644 --- a/PDP10/pdp10_defs.h +++ b/PDP10/pdp10_defs.h @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 19-May-03 RMS Revised for new conditional compilation scheme 09-Jan-03 RMS Added DEUNA/DELUA support 29-Sep-02 RMS Added variable vector, RX211 support 22-Apr-02 RMS Removed magtape record length error @@ -39,6 +40,10 @@ #ifndef _PDP10_DEFS_H_ #define _PDP10_DEFS_H_ 0 +#ifndef VM_PDP10 +#define VM_PDP10 0 +#endif + #include "sim_defs.h" /* simulator defns */ /* Digital Equipment Corporation's 36b family had six implementations: @@ -614,6 +619,8 @@ typedef struct pdp_dib DIB; #define FST 0 /* Unibus 1 */ #define MAP 1 /* Unibus 3 */ +#define DEV_RDX 8 /* default device radix */ + /* I/O page layout */ #define IOPAGEBASE 0760000 /* I/O page base */ @@ -729,10 +736,10 @@ typedef struct pdp_dib DIB; /* Function prototypes */ -int32 Map_ReadB (t_addr ba, int32 bc, uint8 *buf, t_bool ub); -int32 Map_ReadW (t_addr ba, int32 bc, uint16 *buf, t_bool ub); -int32 Map_WriteB (t_addr ba, int32 bc, uint8 *buf, t_bool ub); -int32 Map_WriteW (t_addr ba, int32 bc, uint16 *buf, t_bool ub); +int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf, t_bool ub); +int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf, t_bool ub); +int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf, t_bool ub); +int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf, t_bool ub); t_stat set_addr (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat show_addr (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat set_vec (UNIT *uptr, int32 val, char *cptr, void *desc); diff --git a/PDP10/pdp10_doc.txt b/PDP10/pdp10_doc.txt index cfcceac0..7a70d0ef 100644 --- a/PDP10/pdp10_doc.txt +++ b/PDP10/pdp10_doc.txt @@ -1,7 +1,7 @@ To: Users From: Bob Supnik Subj: PDP-10 Simulator Usage -Date: 15-Jan-2003 +Date: 15-May-2003 COPYRIGHT NOTICE @@ -36,12 +36,10 @@ This memorandum documents the PDP-10 simulator. 1. Simulator Files -To compile the PDP-10, you must define USE_INT64 as part of the compilation -command line. +To compile the PDP-10, you must define VM_PDP10 and USE_INT64 as part of the +compilation command line. -sim/ dec_dz.h - dec_pt.h - sim_defs.h +sim/ sim_defs.h sim_rev.h sim_sock.h sim_tmxr.h @@ -54,19 +52,19 @@ sim/ dec_dz.h sim/pdp10/ pdp10_defs.h pdp10_cpu.c - pdp10_dz.c pdp10_fe.c pdp10_ksio.c pdp10_lp20.c pdp10_mdfp.c pdp10_pag.c - pdp10_pt.c pdp10_rp.c pdp10_sys.c pdp10_tu.c pdp10_xtnd.c -sim/pdp11/ pdp11_ry.c +sim/pdp11/ pdp11_dz.c + pdp11_pt.c + pdp11_ry.c pdp11_xu.c 2. PDP-10 Features diff --git a/PDP10/pdp10_dz.c b/PDP10/pdp10_dz.c deleted file mode 100644 index 12e14d87..00000000 --- a/PDP10/pdp10_dz.c +++ /dev/null @@ -1,33 +0,0 @@ -/* pdp10_dz.c: DZ11 terminal multiplexor simulator - - Copyright (c) 1993-2002, Robert M Supnik - - 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 - ROBERT M SUPNIK 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. - - Except as contained in this notice, the name of Robert M Supnik shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - dz DZ11 terminal multiplexor -*/ - -#define VM_PDP10 0 /* no flt addr */ -#define RANK_DZ 0 /* no autoconfig */ - -#include "pdp10_defs.h" -#include "dec_dz.h" diff --git a/PDP10/pdp10_fe.c b/PDP10/pdp10_fe.c index cadb6b20..e0f9d1cf 100644 --- a/PDP10/pdp10_fe.c +++ b/PDP10/pdp10_fe.c @@ -1,6 +1,6 @@ /* pdp10_fe.c: PDP-10 front end (console terminal) simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ fe KS10 console front end + 25-Apr-03 RMS Revised for extended file support 22-Dec-02 RMS Added break support 30-May-02 RMS Widened COUNT to 32b 30-Nov-01 RMS Added extended SET/SHOW support @@ -59,10 +60,10 @@ UNIT fe_unit[] = { REG fe_reg[] = { { ORDATA (IBUF, fei_unit.buf, 8) }, - { DRDATA (ICOUNT, fei_unit.pos, 32), REG_RO + PV_LEFT }, + { DRDATA (ICOUNT, fei_unit.pos, T_ADDR_W), REG_RO + PV_LEFT }, { DRDATA (ITIME, fei_unit.wait, 24), REG_NZ + PV_LEFT }, { ORDATA (OBUF, feo_unit.buf, 8) }, - { DRDATA (OCOUNT, feo_unit.pos, 32), REG_RO + PV_LEFT }, + { DRDATA (OCOUNT, feo_unit.pos, T_ADDR_W), REG_RO + PV_LEFT }, { DRDATA (OTIME, feo_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; diff --git a/PDP10/pdp10_ksio.c b/PDP10/pdp10_ksio.c index 9eb4b034..ec54d729 100644 --- a/PDP10/pdp10_ksio.c +++ b/PDP10/pdp10_ksio.c @@ -1,6 +1,6 @@ /* pdp10_ksio.c: PDP-10 KS10 I/O subsystem simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ uba Unibus adapters + 12-Mar-03 RMS Added logical name support 10-Oct-02 RMS Revised for dynamic table generation Added SHOW IOSPACE routine 29-Sep-02 RMS Added variable vector, central map support @@ -405,9 +406,9 @@ pa10 = (ubmap[ub][vpn] + PAG_GETOFF (ba >> 2)) & PAMASK; return pa10; } -int32 Map_ReadB (t_addr ba, int32 bc, uint8 *buf, t_bool ub) +int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf, t_bool ub) { -t_addr lim; +uint32 lim; a10 pa10; lim = ba + bc; @@ -421,9 +422,9 @@ for ( ; ba < lim; ba++) { /* by bytes */ return 0; } -int32 Map_ReadW (t_addr ba, int32 bc, uint16 *buf, t_bool ub) +int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf, t_bool ub) { -t_addr lim; +uint32 lim; a10 pa10; ba = ba & ~01; /* align start */ @@ -438,9 +439,9 @@ for ( ; ba < lim; ba = ba + 2) { /* by words */ return 0; } -int32 Map_WriteB (t_addr ba, int32 bc, uint8 *buf, t_bool ub) +int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf, t_bool ub) { -t_addr lim; +uint32 lim; a10 pa10; static d10 mask = 0377; @@ -455,9 +456,9 @@ for ( ; ba < lim; ba++) { /* by bytes */ return 0; } -int32 Map_WriteW (t_addr ba, int32 bc, uint16 *buf, t_bool ub) +int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf, t_bool ub) { -t_addr lim; +uint32 lim; a10 pa10; d10 val; @@ -708,9 +709,11 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */ (curr->ba < (dibp->ba + dibp->lnt))) || ((end >= dibp->ba) && /* overlap end? */ (end < (dibp->ba + dibp->lnt)))) { - printf ("Device %s address conflict at %08o\n", dptr->name, dibp->ba); + printf ("Device %s address conflict at %08o\n", + sim_dname (dptr), dibp->ba); if (sim_log) fprintf (sim_log, - "Device %s address conflict at %08o\n", dptr->name, dibp->ba); + "Device %s address conflict at %08o\n", + sim_dname (dptr), dibp->ba); return TRUE; } } return FALSE; } @@ -781,7 +784,7 @@ for (i = 0; dib_tab[i] != NULL; i++) { /* print table */ break; } } fprintf (st, "%07o - %07o\t%s\n", dib_tab[i]->ba, dib_tab[i]->ba + dib_tab[i]->lnt - 1, - dptr? dptr->name: "CPU"); + dptr? sim_dname (dptr): "CPU"); } return SCPE_OK; } diff --git a/PDP10/pdp10_lp20.c b/PDP10/pdp10_lp20.c index a3b7b6eb..343994ae 100644 --- a/PDP10/pdp10_lp20.c +++ b/PDP10/pdp10_lp20.c @@ -1,6 +1,6 @@ /* pdp10_lp20.c: PDP-10 LP20 line printer simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ lp20 line printer + 25-Apr-03 RMS Revised for extended file support 29-Sep-02 RMS Added variable vector support Modified to use common Unibus routines New data structures @@ -201,7 +202,7 @@ REG lp20_reg[] = { { FLDATA (ERR, lpcsa, CSR_V_ERR) }, { FLDATA (DONE, lpcsa, CSR_V_DONE) }, { FLDATA (IE, lpcsa, CSR_V_IE) }, - { DRDATA (POS, lp20_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lp20_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lp20_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lp20_stopioe, 0) }, { BRDATA (TXRAM, txram, 8, 12, TX_SIZE) }, diff --git a/PDP10/pdp10_mdfp.c b/PDP10/pdp10_mdfp.c index f5e4a830..5c3e1ad9 100644 --- a/PDP10/pdp10_mdfp.c +++ b/PDP10/pdp10_mdfp.c @@ -1,6 +1,6 @@ /* pdp10_mdfp.c: PDP-10 multiply/divide and floating point simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/PDP10/pdp10_pag.c b/PDP10/pdp10_pag.c index f008ba63..bcb6d9c8 100644 --- a/PDP10/pdp10_pag.c +++ b/PDP10/pdp10_pag.c @@ -1,6 +1,6 @@ /* pdp10_pag.c: PDP-10 paging subsystem simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/PDP10/pdp10_pt.c b/PDP10/pdp10_pt.c deleted file mode 100644 index eeb2db22..00000000 --- a/PDP10/pdp10_pt.c +++ /dev/null @@ -1,38 +0,0 @@ -/* pdp10_pt.c: PDP-10 paper tape reader/punch simulator - - Copyright (c) 1993-2002, Robert M Supnik - - 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 - ROBERT M SUPNIK 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. - - Except as contained in this notice, the name of Robert M Supnik shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - ptr paper tape reader - ptp paper tape punch - - 12-Sep-02 RMS Consolidated source -*/ - -#define VM_PDP10 1 -#define PT_RDX 8 -#define PT_DIS DEV_DIS -#include "pdp10_defs.h" -extern int32 int_req; -extern int32 int_vec[32]; -#include "dec_pt.h" diff --git a/PDP10/pdp10_rp.c b/PDP10/pdp10_rp.c index 9b786c01..4e0b2d49 100644 --- a/PDP10/pdp10_rp.c +++ b/PDP10/pdp10_rp.c @@ -1,6 +1,6 @@ /* pdp10_rp.c - RH11/RP04/05/06/07 RM02/03/05/80 "Massbus" disk controller - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ rp RH/RP/RM moving head disks + 25-Apr-03 RMS Revised for extended file support 21-Nov-02 RMS Fixed bug in bootstrap (reported by Michael Thompson) 29-Sep-02 RMS Added variable vector support New data structures @@ -408,7 +409,7 @@ REG rp_reg[] = { { DRDATA (STIME, rp_swait, 24), REG_NZ + PV_LEFT }, { DRDATA (RTIME, rp_rwait, 24), REG_NZ + PV_LEFT }, { URDATA (FNC, rp_unit[0].FUNC, 8, 5, 0, RP_NUMDR, REG_HRO) }, - { URDATA (CAPAC, rp_unit[0].capac, 10, 31, 0, + { URDATA (CAPAC, rp_unit[0].capac, 10, T_ADDR_W, 0, RP_NUMDR, PV_LEFT | REG_HRO) }, { FLDATA (STOP_IOE, rp_stopioe, 0) }, { NULL } }; diff --git a/PDP10/pdp10_tim.c b/PDP10/pdp10_tim.c index 99592d52..e2a0036b 100644 --- a/PDP10/pdp10_tim.c +++ b/PDP10/pdp10_tim.c @@ -1,6 +1,6 @@ /* pdp10_tim.c: PDP-10 tim subsystem simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/PDP10/pdp10_tu.c b/PDP10/pdp10_tu.c index b312309f..f457131a 100644 --- a/PDP10/pdp10_tu.c +++ b/PDP10/pdp10_tu.c @@ -25,6 +25,8 @@ tu RH11/TM03/TU45 magtape + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support 28-Feb-03 RMS Revised for magtape library 27-Jan-03 RMS Changed to dynamically allocate buffer 21-Nov-02 RMS Fixed bug in bootstrap (reported by Michael Thompson) @@ -358,7 +360,7 @@ REG tu_reg[] = { { FLDATA (STOP_IOE, tu_stopioe, 0) }, { DRDATA (TIME, tu_time, 24), PV_LEFT }, { URDATA (UST, tu_unit[0].USTAT, 8, 17, 0, TU_NUMDR, 0) }, - { URDATA (POS, tu_unit[0].pos, 10, 32, 0, + { URDATA (POS, tu_unit[0].pos, 10, T_ADDR_W, 0, TU_NUMDR, PV_LEFT | REG_RO) }, { ORDATA (LOG, tu_log, 8), REG_HIDDEN }, { NULL } }; @@ -366,6 +368,8 @@ REG tu_reg[] = { MTAB tu_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL, NULL, &show_addr, NULL }, { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, diff --git a/PDP10/pdp10_xtnd.c b/PDP10/pdp10_xtnd.c index da5e76a9..3c17e676 100644 --- a/PDP10/pdp10_xtnd.c +++ b/PDP10/pdp10_xtnd.c @@ -1,6 +1,6 @@ /* pdp10_xtnd.c: PDP-10 extended instruction simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/PDP11/pdp11_cis.c b/PDP11/pdp11_cis.c index c567dfb6..4190b7be 100644 --- a/PDP11/pdp11_cis.c +++ b/PDP11/pdp11_cis.c @@ -1,6 +1,6 @@ /* pdp11_cis.c: PDP-11 CIS optional instruction set simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/PDP11/pdp11_cpu.c b/PDP11/pdp11_cpu.c index 4b704180..f08eae0a 100644 --- a/PDP11/pdp11_cpu.c +++ b/PDP11/pdp11_cpu.c @@ -25,6 +25,8 @@ cpu PDP-11 CPU (J-11 microprocessor) + 05-Jun-03 RMS Fixed bugs in memory size table + 12-Mar-03 RMS Added logical name support 01-Feb-03 RMS Changed R display to follow PSW, added SP display 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict 05-Jan-03 RMS Added memory size restore support @@ -549,7 +551,7 @@ MTAB cpu_mod[] = { { UNIT_MSIZE, 65536, NULL, "64K", &cpu_set_size}, { UNIT_MSIZE, 98304, NULL, "96K", &cpu_set_size}, { UNIT_MSIZE, 131072, NULL, "128K", &cpu_set_size}, - { UNIT_MSIZE, 229376, NULL, "192K", &cpu_set_size}, + { UNIT_MSIZE, 196608, NULL, "192K", &cpu_set_size}, { UNIT_MSIZE, 262144, NULL, "256K", &cpu_set_size}, { UNIT_MSIZE, 393216, NULL, "384K", &cpu_set_size}, { UNIT_MSIZE, 524288, NULL, "512K", &cpu_set_size}, @@ -557,7 +559,7 @@ MTAB cpu_mod[] = { { UNIT_MSIZE, 1048576, NULL, "1024K", &cpu_set_size}, { UNIT_MSIZE, 2097152, NULL, "2048K", &cpu_set_size}, { UNIT_MSIZE, 3145728, NULL, "3072K", &cpu_set_size}, - { UNIT_MSIZE, 4194304, NULL, "4096K", &cpu_set_size}, + { UNIT_MSIZE, 4186112, NULL, "4096K", &cpu_set_size}, { UNIT_MSIZE, 1048576, NULL, "1M", &cpu_set_size}, { UNIT_MSIZE, 2097152, NULL, "2M", &cpu_set_size}, { UNIT_MSIZE, 3145728, NULL, "3M", &cpu_set_size}, @@ -2450,7 +2452,7 @@ return iopageW ((int32) val, addr, WRITEC); t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i, clim; +uint32 i, clim; unsigned int16 *nM; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) @@ -2482,8 +2484,8 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { if ((dptr->flags & DEV_DISABLE) && /* disable-able? */ !(dptr->flags & DEV_DIS) && /* enabled? */ ((dptr->flags & (DEV_QBUS|DEV_UBUS)) == target)) { - printf ("Disabling %s\n", dptr->name); - if (sim_log) fprintf (sim_log, "Disabling %s\n", dptr->name); + printf ("Disabling %s\n", sim_dname (dptr)); + if (sim_log) fprintf (sim_log, "Disabling %s\n", sim_dname (dptr)); dptr->flags = dptr->flags | DEV_DIS; } } return SCPE_OK; } diff --git a/PDP11/pdp11_defs.h b/PDP11/pdp11_defs.h index 05df8f72..2c460e80 100644 --- a/PDP11/pdp11_defs.h +++ b/PDP11/pdp11_defs.h @@ -26,6 +26,8 @@ The author gratefully acknowledges the help of Max Burnet, Megan Gentry, and John Wilson in resolving questions about the PDP-11 + 19-May-03 RMS Revised for new conditional compilation + 05-Apr-03 RMS Fixed bug in MMR1 update (found by Tim Stark) 28-Feb-03 RMS Added TM logging support 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict 11-Nov-02 RMS Changed log definitions to be VAX compatible @@ -53,6 +55,10 @@ #ifndef _PDP11_DEFS_H #define _PDP11_DEFS_H 0 +#ifndef VM_PDP11 +#define VM_PDP11 0 +#endif + #include "sim_defs.h" /* simulator defns */ #include @@ -316,6 +322,8 @@ typedef struct fpac fpac_t; #define MAP 1 /* mapped */ #define NOMAP 0 /* not mapped */ +#define DEV_RDX 8 /* default device radix */ + /* Device information block */ #define VEC_DEVMAX 4 /* max device vec */ @@ -542,7 +550,7 @@ typedef struct pdp_dib DIB; /* CPU and FPU macros */ -#define update_MM ((MMR0 & (MMR0_FREEZE + MMR0_MME)) == MMR0_MME) +#define update_MM ((MMR0 & MMR0_FREEZE) == 0) #define setTRAP(name) trap_req = trap_req | (name) #define setCPUERR(name) CPUERR = CPUERR | (name) #define ABORT(val) longjmp (save_env, (val)) @@ -570,11 +578,11 @@ typedef struct pdp_dib DIB; /* Function prototypes */ -t_bool Map_Addr (t_addr qa, t_addr *ma); -int32 Map_ReadB (t_addr ba, int32 bc, uint8 *buf, t_bool map); -int32 Map_ReadW (t_addr ba, int32 bc, uint16 *buf, t_bool map); -int32 Map_WriteB (t_addr ba, int32 bc, uint8 *buf, t_bool map); -int32 Map_WriteW (t_addr ba, int32 bc, uint16 *buf, t_bool map); +t_bool Map_Addr (uint32 qa, uint32 *ma); +int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf, t_bool map); +int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf, t_bool map); +int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf, t_bool map); +int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf, t_bool map); t_stat set_addr (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat show_addr (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat set_addr_flt (UNIT *uptr, int32 val, char *cptr, void *desc); diff --git a/PDP11/pdp11_doc.txt b/PDP11/pdp11_doc.txt index 316632a4..7c8a5276 100644 --- a/PDP11/pdp11_doc.txt +++ b/PDP11/pdp11_doc.txt @@ -36,9 +36,7 @@ This memorandum documents the PDP-11 simulator. 1. Simulator Files -sim/ dec_dz.h - dec_pt.h - sim_defs.h +sim/ sim_defs.h sim_ether.h sim_rev.h sim_sock.h @@ -53,6 +51,7 @@ sim/pdp11/ pdp11_defs.h pdp11_mscp.h pdp11_uqssp.h pdp11_xq.h + pdp11_xq_bootrom.h pdp11_cpu.c pdp11_dz.c pdp11_fp.c @@ -108,11 +107,12 @@ TM TM11/TU10 magnetic tape controller with eight drives TS TS11/TSV05 magnetic tape controller with one drive TQ TQK50 TMSCP magnetic tape controller with four drives XQ DELQA/DEQNA Qbus Ethernet controller +XQB second DELQA/DEQNA Qbus Ethernet controller XU DEUNA/DELUA Unibus Ethernet controller -The DZ, RK, HK, RL, RP, RQ, RQB, RQC, RQD, RX, RY, TC, TM, TS, TQ, XQ, and XU -devices can be set DISABLED. RQB, RQC, RQD, RY, TS, and XU are disabled by -default. +The DZ, RK, HK, RL, RP, RQ, RQB, RQC, RQD, RX, RY, TC, TM, TS, TQ, XQ, XQB, +and XU devices can be set DISABLED. RQB, RQC, RQD, RY, TS, XQB, and XU are +disabled by default. The PDP-11 simulator implements several unique stop conditions: @@ -287,7 +287,7 @@ longer recognizes the explicitly configured device. A device can be reset to autoconfigure with the SET AUTOCONFIGURE command. The current I/O map can be displayed with the SHOW CPU IOSPACE command. -Address that have set by autoconfiguration are marked with an asterisk (*). +Addresses that have set by autoconfiguration are marked with an asterisk (*). All devices support the SHOW ADDRESS and SHOW VECTOR commands, which display the device address and vector, respectively. @@ -1175,9 +1175,10 @@ Error handling is as follows: OS I/O error fatal tape error -2.10 DELQA/DEQNA Qbus Ethernet Controller (XQ) +2.10 DELQA/DEQNA Qbus Ethernet Controllers (XQ, XQB) -XQ simulates the DELQA/DEQNA Qbus Ethernet controller. Options allow +The simulator implements two DELQA/DEQNA Qbus Ethernet controllers (XQ, +XQB). Initially, XQ is enabled, and XQB is disabled. Options allow control of the MAC address, the controller mode, and the sanity timer. SET XQ MAC= ex. 08-00-2B-AA-BB-CC diff --git a/PDP11/pdp11_dz.c b/PDP11/pdp11_dz.c index 1b62f163..6b6c33bb 100644 --- a/PDP11/pdp11_dz.c +++ b/PDP11/pdp11_dz.c @@ -1,6 +1,6 @@ /* pdp11_dz.c: DZ11 terminal multiplexor simulator - Copyright (c) 2001-2002, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,21 +25,609 @@ dz DZ11 terminal multiplexor - 01-Nov-02 RMS Added 8B support + 19-May-03 RMS Revised for new conditional compilation scheme + 09-May-03 RMS Added network device flag + 22-Dec-02 RMS Added break (framing error) support + 31-Oct-02 RMS Added 8b support + 12-Oct-02 RMS Added autoconfigure support + 29-Sep-02 RMS Fixed bug in set number of lines routine + Added variable vector support + New data structures + 22-Apr-02 RMS Updated for changes in sim_tmxr + 28-Apr-02 RMS Fixed interrupt acknowledge, fixed SHOW DZ ADDRESS + 14-Jan-02 RMS Added multiboard support + 30-Dec-01 RMS Added show statistics, set disconnect + Removed statistics registers + 03-Dec-01 RMS Modified for extended SET/SHOW 09-Nov-01 RMS Added VAX support + 20-Oct-01 RMS Moved getchar from sim_tmxr, changed interrupt + logic to use tmxr_rqln + 06-Oct-01 RMS Fixed bug in carrier detect logic + 03-Oct-01 RMS Added support for BSD-style "ringless" modems + 27-Sep-01 RMS Fixed bug in xmte initialization + 17-Sep-01 RMS Added separate autodisconnect switch + 16-Sep-01 RMS Fixed modem control bit offsets */ -#if defined (USE_INT64) -#define VM_VAX 1 -#include "vax_defs.h" -#define DZ_RDX 16 -#define DZ_8B_DFLT UNIT_8B +#if defined (VM_PDP10) /* PDP10 version */ +#include "pdp10_defs.h" +#define RANK_DZ 0 /* no autoconfig */ +#define DZ_8B_DFLT 0 +extern int32 int_req; +extern int32 int_vec[32]; -#else -#define VM_PDP11 1 -#include "pdp11_defs.h" -#define DZ_RDX 8 +#elif defined (VM_VAX) /* VAX version */ +#include "vax_defs.h" #define DZ_8B_DFLT UNIT_8B +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; + +#else /* PDP-11 version */ +#include "pdp11_defs.h" +#define DZ_8B_DFLT UNIT_8B +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; #endif -#include "dec_dz.h" +#include "sim_sock.h" +#include "sim_tmxr.h" + +#if !defined (DZ_MUXES) +#define DZ_MUXES 1 +#endif +#if !defined (DZ_LINES) +#define DZ_LINES 8 +#endif + +#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */ +#define UNIT_8B (1 << UNIT_V_8B) + +#define DZ_MNOMASK (DZ_MUXES - 1) /* mask for mux no */ +#define DZ_LNOMASK (DZ_LINES - 1) /* mask for lineno */ +#define DZ_LMASK ((1 << DZ_LINES) - 1) /* mask of lines */ +#define DZ_SILO_ALM 16 /* silo alarm level */ + +/* DZCSR - 160100 - control/status register */ + +#define CSR_MAINT 0000010 /* maint - NI */ +#define CSR_CLR 0000020 /* clear */ +#define CSR_MSE 0000040 /* master scan enb */ +#define CSR_RIE 0000100 /* rcv int enb */ +#define CSR_RDONE 0000200 /* rcv done - RO */ +#define CSR_V_TLINE 8 /* xmit line - RO */ +#define CSR_TLINE (DZ_LNOMASK << CSR_V_TLINE) +#define CSR_SAE 0010000 /* silo alm enb */ +#define CSR_SA 0020000 /* silo alm - RO */ +#define CSR_TIE 0040000 /* xmit int enb */ +#define CSR_TRDY 0100000 /* xmit rdy - RO */ +#define CSR_RW (CSR_MSE | CSR_RIE | CSR_SAE | CSR_TIE) +#define CSR_MBZ (0004003 | CSR_CLR | CSR_MAINT) + +#define CSR_GETTL(x) (((x) >> CSR_V_TLINE) & DZ_LNOMASK) +#define CSR_PUTTL(x,y) x = ((x) & ~CSR_TLINE) | (((y) & DZ_LNOMASK) << CSR_V_TLINE) + +/* DZRBUF - 160102 - receive buffer, read only */ + +#define RBUF_CHAR 0000377 /* rcv char */ +#define RBUF_V_RLINE 8 /* rcv line */ +#define RBUF_PARE 0010000 /* parity err - NI */ +#define RBUF_FRME 0020000 /* frame err */ +#define RBUF_OVRE 0040000 /* overrun err - NI */ +#define RBUF_VALID 0100000 /* rcv valid */ +#define RBUF_MBZ 0004000 + +/* DZLPR - 160102 - line parameter register, write only, word access only */ + +#define LPR_V_LINE 0 /* line */ +#define LPR_LPAR 0007770 /* line pars - NI */ +#define LPR_RCVE 0010000 /* receive enb */ +#define LPR_GETLN(x) (((x) >> LPR_V_LINE) & DZ_LNOMASK) + +/* DZTCR - 160104 - transmission control register */ + +#define TCR_V_XMTE 0 /* xmit enables */ +#define TCR_V_DTR 8 /* DTRs */ + +/* DZMSR - 160106 - modem status register, read only */ + +#define MSR_V_RI 0 /* ring indicators */ +#define MSR_V_CD 8 /* carrier detect */ + +/* DZTDR - 160106 - transmit data, write only */ + +#define TDR_CHAR 0000377 /* xmit char */ +#define TDR_V_TBR 8 /* xmit break - NI */ + +extern int32 IREQ (HLVL); +extern int32 sim_switches; +extern FILE *sim_log; +extern int32 tmxr_poll; /* calibrated delay */ + +uint16 dz_csr[DZ_MUXES] = { 0 }; /* csr */ +uint16 dz_rbuf[DZ_MUXES] = { 0 }; /* rcv buffer */ +uint16 dz_lpr[DZ_MUXES] = { 0 }; /* line param */ +uint16 dz_tcr[DZ_MUXES] = { 0 }; /* xmit control */ +uint16 dz_msr[DZ_MUXES] = { 0 }; /* modem status */ +uint16 dz_tdr[DZ_MUXES] = { 0 }; /* xmit data */ +uint8 dz_sae[DZ_MUXES] = { 0 }; /* silo alarm enabled */ +uint32 dz_rxi = 0; /* rcv interrupts */ +uint32 dz_txi = 0; /* xmt interrupts */ +int32 dz_mctl = 0; /* modem ctrl enabled */ +int32 dz_auto = 0; /* autodiscon enabled */ +TMLN dz_ldsc[DZ_MUXES * DZ_LINES] = { 0 }; /* line descriptors */ +TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, NULL }; /* mux descriptor */ + +DEVICE dz_dev; +t_stat dz_rd (int32 *data, int32 PA, int32 access); +t_stat dz_wr (int32 data, int32 PA, int32 access); +int32 dz_rxinta (void); +int32 dz_txinta (void); +t_stat dz_svc (UNIT *uptr); +t_stat dz_reset (DEVICE *dptr); +t_stat dz_attach (UNIT *uptr, char *cptr); +t_stat dz_detach (UNIT *uptr); +t_stat dz_clear (int32 dz, t_bool flag); +int32 dz_getc (int32 dz); +void dz_update_rcvi (void); +void dz_update_xmti (void); +void dz_clr_rxint (int32 dz); +void dz_set_rxint (int32 dz); +void dz_clr_txint (int32 dz); +void dz_set_txint (int32 dz); +t_stat dz_summ (FILE *st, UNIT *uptr, int32 val, void *desc); +t_stat dz_show (FILE *st, UNIT *uptr, int32 val, void *desc); +t_stat dz_show_vec (FILE *st, UNIT *uptr, int32 val, void *desc); +t_stat dz_setnl (UNIT *uptr, int32 val, char *cptr, void *desc); + +/* DZ data structures + + dz_dev DZ device descriptor + dz_unit DZ unit list + dz_reg DZ register list +*/ + +DIB dz_dib = { IOBA_DZ, IOLN_DZ * DZ_MUXES, &dz_rd, &dz_wr, + 2, IVCL (DZRX), VEC_DZRX, { &dz_rxinta, &dz_txinta } }; + +UNIT dz_unit = { UDATA (&dz_svc, UNIT_ATTABLE + DZ_8B_DFLT, 0) }; + +REG dz_nlreg = { DRDATA (NLINES, dz_desc.lines, 6), PV_LEFT }; + +REG dz_reg[] = { + { BRDATA (CSR, dz_csr, DEV_RDX, 16, DZ_MUXES) }, + { BRDATA (RBUF, dz_rbuf, DEV_RDX, 16, DZ_MUXES) }, + { BRDATA (LPR, dz_lpr, DEV_RDX, 16, DZ_MUXES) }, + { BRDATA (TCR, dz_tcr, DEV_RDX, 16, DZ_MUXES) }, + { BRDATA (MSR, dz_msr, DEV_RDX, 16, DZ_MUXES) }, + { BRDATA (TDR, dz_tdr, DEV_RDX, 16, DZ_MUXES) }, + { BRDATA (SAENB, dz_sae, DEV_RDX, 1, DZ_MUXES) }, + { GRDATA (RXINT, dz_rxi, DEV_RDX, DZ_MUXES, 0) }, + { GRDATA (TXINT, dz_txi, DEV_RDX, DZ_MUXES, 0) }, + { FLDATA (MDMCTL, dz_mctl, 0) }, + { FLDATA (AUTODS, dz_auto, 0) }, + { GRDATA (DEVADDR, dz_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, dz_dib.vec, DEV_RDX, 16, 0), REG_HRO }, + { NULL } }; + +MTAB dz_mod[] = { + { UNIT_8B, 0, "7b", "7B", NULL }, + { UNIT_8B, UNIT_8B, "8b", "8B", NULL }, + { MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT", + &tmxr_dscln, NULL, &dz_desc }, + { UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &dz_summ }, + { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL, + NULL, &dz_show, NULL }, + { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL, + NULL, &dz_show, NULL }, + { MTAB_XTD|MTAB_VDV, 010, "ADDRESS", "ADDRESS", + &set_addr, &show_addr, NULL }, + { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", + &set_vec, &dz_show_vec, NULL }, +#if !defined (VM_PDP10) + { MTAB_XTD | MTAB_VDV, 0, NULL, "AUTOCONFIGURE", + &set_addr_flt, NULL, NULL }, +#endif + { MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES", + &dz_setnl, NULL, &dz_nlreg }, + { 0 } }; + +DEVICE dz_dev = { + "DZ", &dz_unit, dz_reg, dz_mod, + 1, DEV_RDX, 8, 1, DEV_RDX, 8, + &tmxr_ex, &tmxr_dep, &dz_reset, + NULL, &dz_attach, &dz_detach, + &dz_dib, DEV_FLTA | DEV_DISABLE | DEV_NET | DEV_UBUS | DEV_QBUS }; + +/* IO dispatch routines, I/O addresses 177601x0 - 177601x7 */ + +t_stat dz_rd (int32 *data, int32 PA, int32 access) +{ +int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */ + +switch ((PA >> 1) & 03) { /* case on PA<2:1> */ +case 00: /* CSR */ + *data = dz_csr[dz] = dz_csr[dz] & ~CSR_MBZ; + break; +case 01: /* RBUF */ + dz_csr[dz] = dz_csr[dz] & ~CSR_SA; /* clr silo alarm */ + if (dz_csr[dz] & CSR_MSE) { /* scanner on? */ + dz_rbuf[dz] = dz_getc (dz); /* get top of silo */ + if (!dz_rbuf[dz]) dz_sae[dz] = 1; /* empty? re-enable */ + tmxr_poll_rx (&dz_desc); /* poll input */ + dz_update_rcvi (); } /* update rx intr */ + else { + dz_rbuf[dz] = 0; /* no data */ + dz_update_rcvi (); } /* no rx intr */ + *data = dz_rbuf[dz]; + break; +case 02: /* TCR */ + *data = dz_tcr[dz]; + break; +case 03: /* MSR */ + *data = dz_msr[dz]; + break; } +return SCPE_OK; +} + +t_stat dz_wr (int32 data, int32 PA, int32 access) +{ +int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */ +int32 i, line; +TMLN *lp; + +switch ((PA >> 1) & 03) { /* case on PA<2:1> */ +case 00: /* CSR */ + if (access == WRITEB) data = (PA & 1)? /* byte? merge */ + (dz_csr[dz] & 0377) | (data << 8): + (dz_csr[dz] & ~0377) | data; + if (data & CSR_CLR) dz_clear (dz, FALSE); /* clr? reset */ + if (data & CSR_MSE) sim_activate (&dz_unit, tmxr_poll); + else dz_csr[dz] &= ~(CSR_SA | CSR_RDONE | CSR_TRDY); + if ((data & CSR_RIE) == 0) dz_clr_rxint (dz); /* RIE = 0? */ + else if (((dz_csr[dz] & CSR_IE) == 0) && /* RIE 0->1? */ + ((dz_csr[dz] & CSR_SAE)? + (dz_csr[dz] & CSR_SA): (dz_csr[dz] & CSR_RDONE))) + dz_set_rxint (dz); + if ((data & CSR_TIE) == 0) dz_clr_txint (dz); /* TIE = 0? */ + else if (((dz_csr[dz] & CSR_TIE) == 0) && (dz_csr[dz] & CSR_TRDY)) + dz_set_txint (dz); + dz_csr[dz] = (dz_csr[dz] & ~CSR_RW) | (data & CSR_RW); + break; +case 01: /* LPR */ + dz_lpr[dz] = data; + line = (dz * DZ_LINES) + LPR_GETLN (data); /* get line num */ + lp = &dz_ldsc[line]; /* get line desc */ + if (dz_lpr[dz] & LPR_RCVE) lp->rcve = 1; /* rcv enb? on */ + else lp->rcve = 0; /* else line off */ + tmxr_poll_rx (&dz_desc); /* poll input */ + dz_update_rcvi (); /* update rx intr */ + break; +case 02: /* TCR */ + if (access == WRITEB) data = (PA & 1)? /* byte? merge */ + (dz_tcr[dz] & 0377) | (data << 8): + (dz_tcr[dz] & ~0377) | data; + if (dz_mctl) { /* modem ctl? */ + dz_msr[dz] |= ((data & 0177400) & /* dcd |= dtr & ring */ + ((dz_msr[dz] & DZ_LMASK) << MSR_V_CD)); + dz_msr[dz] &= ~(data >> TCR_V_DTR); /* ring &= ~dtr */ + if (dz_auto) { /* auto disconnect? */ + int32 drop; + drop = (dz_tcr[dz] & ~data) >> TCR_V_DTR; /* drop = dtr & ~data */ + for (i = 0; i < DZ_LINES; i++) { /* drop hangups */ + line = (dz * DZ_LINES) + i; /* get line num */ + lp = &dz_ldsc[line]; /* get line desc */ + if (lp->conn && (drop & (1 << i))) { + tmxr_msg (lp->conn, "\r\nLine hangup\r\n"); + tmxr_reset_ln (lp); /* reset line, cdet */ + dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); + } /* end if drop */ + } /* end for */ + } /* end if auto */ + } /* end if modem */ + dz_tcr[dz] = data; + tmxr_poll_tx (&dz_desc); /* poll output */ + dz_update_xmti (); /* update int */ + break; +case 03: /* TDR */ + if (PA & 1) { /* odd byte? */ + dz_tdr[dz] = (dz_tdr[dz] & 0377) | (data << 8); /* just save */ + break; } + dz_tdr[dz] = data; + if (dz_csr[dz] & CSR_MSE) { /* enabled? */ + line = (dz * DZ_LINES) + CSR_GETTL (dz_csr[dz]); + lp = &dz_ldsc[line]; /* get line desc */ + tmxr_putc_ln (lp, dz_tdr[dz] & /* store char */ + ((dz_unit.flags & UNIT_8B)? 0377: 0177)); + tmxr_poll_tx (&dz_desc); /* poll output */ + dz_update_xmti (); } /* update int */ + break; } +return SCPE_OK; +} + +/* Unit service routine + + The DZ11 polls to see if asynchronous activity has occurred and now + needs to be processed. The polling interval is controlled by the clock + simulator, so for most environments, it is calibrated to real time. + Typical polling intervals are 50-60 times per second. + + The simulator assumes that software enables all of the multiplexors, + or none of them. +*/ + +t_stat dz_svc (UNIT *uptr) +{ +int32 dz, t, newln; + +for (dz = t = 0; dz < DZ_MUXES; dz++) /* check enabled */ + t = t | (dz_csr[dz] & CSR_MSE); +if (t) { /* any enabled? */ + newln = tmxr_poll_conn (&dz_desc); /* poll connect */ + if ((newln >= 0) && dz_mctl) { /* got a live one? */ + dz = newln / DZ_LINES; /* get mux num */ + if (dz_tcr[dz] & (1 << (newln + TCR_V_DTR))) /* DTR set? */ + dz_msr[dz] |= (1 << (newln + MSR_V_CD)); /* set cdet */ + else dz_msr[dz] |= (1 << newln); } /* set ring */ + tmxr_poll_rx (&dz_desc); /* poll input */ + dz_update_rcvi (); /* upd rcv intr */ + tmxr_poll_tx (&dz_desc); /* poll output */ + dz_update_xmti (); /* upd xmt intr */ + sim_activate (uptr, tmxr_poll); } /* reactivate */ +return SCPE_OK; +} + +/* Get first available character for mux, if any */ + +int32 dz_getc (int32 dz) +{ +uint32 i, line, c; + +for (i = c = 0; (i < DZ_LINES) && (c == 0); i++) { /* loop thru lines */ + line = (dz * DZ_LINES) + i; /* get line num */ + c = tmxr_getc_ln (&dz_ldsc[line]); /* test for input */ + if (c & SCPE_BREAK) c = RBUF_VALID | RBUF_FRME; /* break? frame err */ + if (c) c = c | (i << RBUF_V_RLINE); /* or in line # */ + } /* end for */ +return c; +} + +/* Update receive interrupts */ + +void dz_update_rcvi (void) +{ +int32 i, dz, line, scnt[DZ_MUXES]; +TMLN *lp; + +for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */ + scnt[dz] = 0; /* clr input count */ + for (i = 0; i < DZ_LINES; i++) { /* poll lines */ + line = (dz * DZ_LINES) + i; /* get line num */ + lp = &dz_ldsc[line]; /* get line desc */ + scnt[dz] = scnt[dz] + tmxr_rqln (lp); /* sum buffers */ + if (dz_mctl && !lp->conn) /* if disconn */ + dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); /* reset car det */ + } + } +for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */ + if (scnt[dz] && (dz_csr[dz] & CSR_MSE)) { /* input & enabled? */ + dz_csr[dz] |= CSR_RDONE; /* set done */ + if (dz_sae[dz] && (scnt[dz] >= DZ_SILO_ALM)) { /* alm enb & cnt hi? */ + dz_csr[dz] |= CSR_SA; /* set status */ + dz_sae[dz] = 0; } } /* disable alarm */ + else dz_csr[dz] &= ~CSR_RDONE; /* no, clear done */ + if ((dz_csr[dz] & CSR_RIE) && /* int enable */ + ((dz_csr[dz] & CSR_SAE)? + (dz_csr[dz] & CSR_SA): (dz_csr[dz] & CSR_RDONE))) + dz_set_rxint (dz); /* and alm/done? */ + else dz_clr_rxint (dz); /* no, clear int */ + } +return; +} + +/* Update transmit interrupts */ + +void dz_update_xmti (void) +{ +int32 dz, linemask, i, j, line; + +for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */ + linemask = dz_tcr[dz] & DZ_LMASK; /* enabled lines */ + dz_csr[dz] &= ~CSR_TRDY; /* assume not rdy */ + j = CSR_GETTL (dz_csr[dz]); /* start at current */ + for (i = 0; i < DZ_LINES; i++) { /* loop thru lines */ + j = (j + 1) & DZ_LNOMASK; /* next line */ + line = (dz * DZ_LINES) + j; /* get line num */ + if ((linemask & (1 << j)) && dz_ldsc[line].xmte) { + CSR_PUTTL (dz_csr[dz], j); /* put ln in csr */ + dz_csr[dz] |= CSR_TRDY; /* set xmt rdy */ + break; } } + if ((dz_csr[dz] & CSR_TIE) && (dz_csr[dz] & CSR_TRDY)) /* ready plus int? */ + dz_set_txint (dz); + else dz_clr_txint (dz); /* no int req */ + } +return; +} + +/* Interrupt routines */ + +void dz_clr_rxint (int32 dz) +{ +dz_rxi = dz_rxi & ~(1 << dz); /* clr mux rcv int */ +if (dz_rxi == 0) CLR_INT (DZRX); /* all clr? */ +else SET_INT (DZRX); /* no, set intr */ +return; +} + +void dz_set_rxint (int32 dz) +{ +dz_rxi = dz_rxi | (1 << dz); /* set mux rcv int */ +SET_INT (DZRX); /* set master intr */ +return; +} + +int32 dz_rxinta (void) +{ +int32 dz; + +for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */ + if (dz_rxi & (1 << dz)) { + dz_clr_rxint (dz); /* clear intr */ + return (dz_dib.vec + (dz * 010)); } } /* return vector */ +return 0; +} + +void dz_clr_txint (int32 dz) +{ +dz_txi = dz_txi & ~(1 << dz); /* clr mux xmt int */ +if (dz_txi == 0) CLR_INT (DZTX); /* all clr? */ +else SET_INT (DZTX); /* no, set intr */ +return; +} + +void dz_set_txint (int32 dz) +{ +dz_txi = dz_txi | (1 << dz); /* set mux xmt int */ +SET_INT (DZTX); /* set master intr */ +return; +} + +int32 dz_txinta (void) +{ +int32 dz; + +for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */ + if (dz_txi & (1 << dz)) { + dz_clr_txint (dz); /* clear intr */ + return (dz_dib.vec + 4 + (dz * 010)); } } /* return vector */ +return 0; +} + +/* Device reset */ + +t_stat dz_clear (int32 dz, t_bool flag) +{ +int32 i, line; + +dz_csr[dz] = 0; /* clear CSR */ +dz_rbuf[dz] = 0; /* silo empty */ +dz_lpr[dz] = 0; /* no params */ +if (flag) dz_tcr[dz] = 0; /* INIT? clr all */ +else dz_tcr[dz] &= ~0377; /* else save dtr */ +dz_tdr[dz] = 0; +dz_sae[dz] = 1; /* alarm on */ +dz_clr_rxint (dz); /* clear int */ +dz_clr_txint (dz); +for (i = 0; i < DZ_LINES; i++) { /* loop thru lines */ + line = (dz * DZ_LINES) + i; + if (!dz_ldsc[line].conn) dz_ldsc[line].xmte = 1;/* set xmt enb */ + dz_ldsc[line].rcve = 0; } /* clr rcv enb */ +return SCPE_OK; +} + +t_stat dz_reset (DEVICE *dptr) +{ +int32 i, ndev; + +for (i = 0; i < (DZ_MUXES * DZ_LINES); i++) /* init mux desc */ + dz_desc.ldsc[i] = &dz_ldsc[i]; +for (i = 0; i < DZ_MUXES; i++) dz_clear (i, TRUE); /* init muxes */ +dz_rxi = dz_txi = 0; /* clr master int */ +CLR_INT (DZRX); +CLR_INT (DZTX); +sim_cancel (&dz_unit); /* stop poll */ +ndev = ((dptr->flags & DEV_DIS)? 0: (dz_desc.lines / DZ_LINES)); +return auto_config (RANK_DZ, ndev); /* auto config */ +} + +/* Attach */ + +t_stat dz_attach (UNIT *uptr, char *cptr) +{ +t_stat r; +extern int32 sim_switches; + +dz_mctl = dz_auto = 0; /* modem ctl off */ +r = tmxr_attach (&dz_desc, uptr, cptr); /* attach mux */ +if (r != SCPE_OK) return r; /* error? */ +if (sim_switches & SWMASK ('M')) { /* modem control? */ + dz_mctl = 1; + printf ("Modem control activated\n"); + if (sim_log) fprintf (sim_log, "Modem control activated\n"); + if (sim_switches & SWMASK ('A')) { /* autodisconnect? */ + dz_auto = 1; + printf ("Auto disconnect activated\n"); + if (sim_log) fprintf (sim_log, "Auto disconnect activated\n"); + } + } +return SCPE_OK; +} + +/* Detach */ + +t_stat dz_detach (UNIT *uptr) +{ +return tmxr_detach (&dz_desc, uptr); +} + +/* Show summary processor */ + +t_stat dz_summ (FILE *st, UNIT *uptr, int32 val, void *desc) +{ +int32 i, t; + +for (i = t = 0; i < dz_desc.lines; i++) { /* get num conn */ + if (dz_ldsc[i].conn) t = t + 1; } +if (t == 1) fprintf (st, "1 connection"); +else fprintf (st, "%d connections", t); +return SCPE_OK; +} + +/* SHOW CONN/STAT processor */ + +t_stat dz_show (FILE *st, UNIT *uptr, int32 val, void *desc) +{ +int32 i, t; + +for (i = t = 0; i < dz_desc.lines; i++) { /* loop thru conn */ + if (dz_ldsc[i].conn) { + t = 1; + if (val) tmxr_fconns (st, &dz_ldsc[i], i); + else tmxr_fstats (st, &dz_ldsc[i], i); } } +if (t == 0) fprintf (st, "all disconnected\n"); +return SCPE_OK; +} + +/* SET LINES processor */ + +t_stat dz_setnl (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +int32 newln, i, t, ndev; +t_stat r; + +if (cptr == NULL) return SCPE_ARG; +newln = (int32) get_uint (cptr, 10, (DZ_MUXES * DZ_LINES), &r); +if ((r != SCPE_OK) || (newln == dz_desc.lines)) return r; +if ((newln == 0) || (newln % DZ_LINES)) return SCPE_ARG; +if (newln < dz_desc.lines) { + for (i = newln, t = 0; i < dz_desc.lines; i++) t = t | dz_ldsc[i].conn; + if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE)) + return SCPE_OK; + for (i = newln; i < dz_desc.lines; i++) { + if (dz_ldsc[i].conn) { + tmxr_msg (dz_ldsc[i].conn, "\r\nOperator disconnected line\r\n"); + tmxr_reset_ln (&dz_ldsc[i]); } /* reset line */ + if ((i % DZ_LINES) == (DZ_LINES - 1)) + dz_clear (i / DZ_LINES, TRUE); } /* reset mux */ + } +dz_dib.lnt = (newln / DZ_LINES) * IOLN_DZ; /* set length */ +dz_desc.lines = newln; +ndev = ((dz_dev.flags & DEV_DIS)? 0: (dz_desc.lines / DZ_LINES)); +return auto_config (RANK_DZ, ndev); /* auto config */ +} + +/* SHOW VECTOR processor */ + +t_stat dz_show_vec (FILE *st, UNIT *uptr, int32 val, void *desc) +{ +return show_vec (st, uptr, ((dz_desc.lines * 2) / DZ_LINES), desc); +} diff --git a/PDP11/pdp11_hk.c b/PDP11/pdp11_hk.c index 552025fc..31f35e52 100644 --- a/PDP11/pdp11_hk.c +++ b/PDP11/pdp11_hk.c @@ -1,6 +1,6 @@ /* pdp11_hk.c - RK611/RK06/RK07 disk controller - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ hk RK611/RK06/RK07 disk + 25-Apr-03 RMS Revised for extended file support + This is a somewhat abstracted implementation of the RK611, more closely modelled on third party clones than DEC's own implementation. In particular, the drive-to-controller serial communications system is simulated only at @@ -38,7 +40,7 @@ */ #include "pdp11_defs.h" -#define VM_PDP11 1 + #define HK_RDX 8 #define HK_WID 16 extern int32 cpu_18b, cpu_ubm; @@ -322,7 +324,7 @@ int32 hk_rwait = 10; /* rotate time */ int16 hkdb[3] = { 0 }; /* data buffer silo */ int16 hk_off[HK_NUMDR] = { 0 }; /* saved offset */ int16 hk_dif[HK_NUMDR] = { 0 }; /* cylinder diff */ -static int reg_in_drive[16] = { +static int32 reg_in_drive[16] = { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; DEVICE hk_dev; @@ -400,7 +402,7 @@ REG hk_reg[] = { HK_NUMDR, REG_HRO) }, { BRDATA (OFFSET, hk_off, HK_RDX, 16, HK_NUMDR), REG_HRO }, { BRDATA (CYLDIF, hk_dif, HK_RDX, 16, HK_NUMDR), REG_HRO }, - { URDATA (CAPAC, hk_unit[0].capac, 10, 32, 0, + { URDATA (CAPAC, hk_unit[0].capac, 10, T_ADDR_W, 0, HK_NUMDR, PV_LEFT | REG_HRO) }, { FLDATA (STOP_IOE, hk_stopioe, 0) }, { GRDATA (DEVADDR, hk_dib.ba, HK_RDX, 32, 0), REG_HRO }, @@ -591,13 +593,13 @@ void hk_go (int32 drv) int32 fnc, t; UNIT *uptr; -static int fnc_nxf[16] = { +static int32 fnc_nxf[16] = { 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0 }; -static int fnc_att[16] = { +static int32 fnc_att[16] = { 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }; -static int fnc_rdy[16] = { +static int32 fnc_rdy[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }; -static int fnc_cyl[16] = { +static int32 fnc_cyl[16] = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }; fnc = GET_FNC (hkcs1); @@ -686,7 +688,7 @@ t_stat hk_svc (UNIT *uptr) { int32 i, t, dc, drv, fnc, err; int32 wc, awc, da; -t_addr ba; +uint32 ba; uint16 comp; drv = uptr - hk_dev.units; /* get drv number */ @@ -1018,25 +1020,25 @@ return SCPE_OK; t_stat hk_attach (UNIT *uptr, char *cptr) { -int drv, p; +uint32 drv, p; t_stat r; uptr->capac = HK_SIZE (uptr); -r = attach_unit (uptr, cptr); -if (r != SCPE_OK) return r; +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) return r; /* error? */ drv = uptr - hk_dev.units; /* get drv number */ hkds[drv] = DS_ATA | DS_RDY | ((uptr->flags & UNIT_WPRT)? DS_WRL: 0); -hker[drv] = 0; +hker[drv] = 0; /* upd drv status */ hk_off[drv] = 0; hk_dif[drv] = 0; uptr->CYL = 0; -update_hkcs (CS1_DI, drv); +update_hkcs (CS1_DI, drv); /* upd ctlr status */ -if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */ -if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; -if ((p = ftell (uptr->fileref)) == 0) { +if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; /* seek to end */ +if ((p = ftell (uptr->fileref)) == 0) { /* new disk image? */ if (uptr->flags & UNIT_RO) return SCPE_OK; return pdp11_bad_block (uptr, HK_NUMSC, HK_NUMWD); } +if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */ if (p > (RK06_SIZE * sizeof (int16))) { uptr->flags = uptr->flags | UNIT_RK07; uptr->capac = RK07_SIZE; } @@ -1080,8 +1082,6 @@ return pdp11_bad_block (uptr, HK_NUMSC, HK_NUMWD); /* Device bootstrap - does not clear CSR when done */ -#if defined (VM_PDP11) - #define BOOT_START 02000 /* start */ #define BOOT_ENTRY (BOOT_START + 002) /* entry */ #define BOOT_UNIT (BOOT_START + 010) /* unit number */ @@ -1132,12 +1132,3 @@ M[BOOT_CSR >> 1] = hk_dib.ba & DMASK; saved_PC = BOOT_ENTRY; return SCPE_OK; } - -#else - -t_stat hk_boot (int32 unitno, DEVICE *dptr) -{ -return SCPE_NOFNC; -} - -#endif diff --git a/PDP11/pdp11_io.c b/PDP11/pdp11_io.c index 8703d515..bae93443 100644 --- a/PDP11/pdp11_io.c +++ b/PDP11/pdp11_io.c @@ -1,6 +1,6 @@ /* pdp11_io.c: PDP-11 I/O simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 12-Mar-03 RMS Added logical name support 08-Oct-02 RMS Trimmed I/O bus addresses Added support for dynamic tables Added show I/O space, autoconfigure routines @@ -186,7 +187,7 @@ return SCPE_NXM; /* Map I/O address to memory address */ -t_bool Map_Addr (t_addr ba, t_addr *ma) +t_bool Map_Addr (uint32 ba, uint32 *ma) { if (cpu_bme) { /* bus map on? */ int32 pg = UBM_GETPN (ba); /* map entry */ @@ -206,9 +207,9 @@ return TRUE; Map_WriteW - store word buffer into memory */ -int32 Map_ReadB (t_addr ba, int32 bc, uint8 *buf, t_bool map) +int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf, t_bool map) { -t_addr alim, lim, ma; +uint32 alim, lim, ma; ba = ba & BUSMASK (map); /* trim address */ lim = ba + bc; @@ -229,9 +230,9 @@ else { /* physical */ return (lim - alim); } } -int32 Map_ReadW (t_addr ba, int32 bc, uint16 *buf, t_bool map) +int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf, t_bool map) { -t_addr alim, lim, ma; +uint32 alim, lim, ma; ba = (ba & BUSMASK (map)) & ~01; /* trim, align addr */ lim = ba + (bc & ~01); @@ -250,9 +251,9 @@ else { /* physical */ return (lim - alim); } } -int32 Map_WriteB (t_addr ba, int32 bc, uint8 *buf, t_bool map) +int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf, t_bool map) { -t_addr alim, lim, ma; +uint32 alim, lim, ma; ba = ba & BUSMASK (map); /* trim address */ lim = ba + bc; @@ -275,9 +276,9 @@ else { /* physical */ return (lim - alim); } } -int32 Map_WriteW (t_addr ba, int32 bc, uint16 *buf, t_bool map) +int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf, t_bool map) { -t_addr alim, lim, ma; +uint32 alim, lim, ma; ba = (ba & BUSMASK (map)) & ~01; /* trim, align addr */ lim = ba + (bc & ~01); @@ -415,9 +416,11 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */ (curr->ba < (dibp->ba + dibp->lnt))) || ((end >= dibp->ba) && /* overlap end? */ (end < (dibp->ba + dibp->lnt)))) { - printf ("Device %s address conflict at %08o\n", dptr->name, dibp->ba); + printf ("Device %s address conflict at %08o\n", + sim_dname (dptr), dibp->ba); if (sim_log) fprintf (sim_log, - "Device %s address conflict at %08o\n", dptr->name, dibp->ba); + "Device %s address conflict at %08o\n", + sim_dname (dptr), dibp->ba); return TRUE; } } return FALSE; } @@ -499,7 +502,7 @@ for (i = 0; dib_tab[i] != NULL; i++) { /* print table */ fprintf (st, "%08o - %08o%c\t%s\n", dib_tab[i]->ba, dib_tab[i]->ba + dib_tab[i]->lnt - 1, (dptr && (dptr->flags & DEV_FLTA))? '*': ' ', - dptr? dptr->name: "CPU"); + dptr? sim_dname (dptr): "CPU"); } return SCPE_OK; } diff --git a/PDP11/pdp11_lp.c b/PDP11/pdp11_lp.c index 78b16b14..022497a9 100644 --- a/PDP11/pdp11_lp.c +++ b/PDP11/pdp11_lp.c @@ -1,6 +1,6 @@ /* pdp11_lp.c: PDP-11 line printer simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ lpt LP11 line printer + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support 29-Sep-02 RMS Added vector change/display support New data structures 30-May-02 RMS Widened POS to 32b @@ -34,15 +36,18 @@ 30-Oct-00 RMS Standardized register naming */ -#if defined (USE_INT64) -#define VM_VAX 1 -#include "vax_defs.h" -#define LPT_DRDX 16 +#if defined (VM_PDP10) /* PDP10 version */ +#error "LP11 is not supported on the PDP-10!" -#else -#define VM_PDP11 1 +#elif defined (VM_VAX) /* VAX version */ +#include "vax_defs.h" +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; + +#else /* PDP-11 version */ #include "pdp11_defs.h" -#define LPT_DRDX 8 +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; #endif #define LPTCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* implemented */ @@ -76,17 +81,17 @@ UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; REG lpt_reg[] = { - { GRDATA (BUF, lpt_unit.buf, LPT_DRDX, 8, 0) }, - { GRDATA (CSR, lpt_csr, LPT_DRDX, 16, 0) }, + { GRDATA (BUF, lpt_unit.buf, DEV_RDX, 8, 0) }, + { GRDATA (CSR, lpt_csr, DEV_RDX, 16, 0) }, { FLDATA (INT, IREQ (LPT), INT_V_LPT) }, { FLDATA (ERR, lpt_csr, CSR_V_ERR) }, { FLDATA (DONE, lpt_csr, CSR_V_DONE) }, { FLDATA (IE, lpt_csr, CSR_V_IE) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lpt_stopioe, 0) }, - { GRDATA (DEVADDR, lpt_dib.ba, LPT_DRDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, lpt_dib.vec, LPT_DRDX, 16, 0), REG_HRO }, + { GRDATA (DEVADDR, lpt_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, lpt_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { NULL } }; MTAB lpt_mod[] = { @@ -98,7 +103,7 @@ MTAB lpt_mod[] = { DEVICE lpt_dev = { "LPT", &lpt_unit, lpt_reg, lpt_mod, - 1, 10, 31, 1, LPT_DRDX, 8, + 1, 10, 31, 1, DEV_RDX, 8, NULL, NULL, &lpt_reset, NULL, &lpt_attach, &lpt_detach, &lpt_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS }; @@ -148,7 +153,7 @@ if (putc (lpt_unit.buf & 0177, lpt_unit.fileref) == EOF) { clearerr (lpt_unit.fileref); return SCPE_IOERR; } lpt_csr = lpt_csr & ~CSR_ERR; -lpt_unit.pos = ftell (lpt_unit.fileref); +lpt_unit.pos = lpt_unit.pos + 1; return SCPE_OK; } diff --git a/PDP11/pdp11_pclk.c b/PDP11/pdp11_pclk.c index 30e134c0..af088679 100644 --- a/PDP11/pdp11_pclk.c +++ b/PDP11/pdp11_pclk.c @@ -1,6 +1,6 @@ /* pdp11_pclk.c: KW11P programmable clock simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Written by John Dundas, used with his gracious permission Permission is hereby granted, free of charge, to any person obtaining a diff --git a/PDP11/pdp11_pt.c b/PDP11/pdp11_pt.c index eb590216..169c4d4c 100644 --- a/PDP11/pdp11_pt.c +++ b/PDP11/pdp11_pt.c @@ -1,6 +1,6 @@ -/* pdp11_pt.c: PDP-11 paper tape reader/punch simulator +/* pdp11_pt.c: PC11 paper tape reader/punch simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,21 +26,299 @@ ptr paper tape reader ptp paper tape punch + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support 12-Sep-02 RMS Split off from pdp11_stddev.c */ -#if defined (USE_INT64) /* VAX version */ -#include "vax_defs.h" -#define VM_VAX 1 -#define PT_RDX 16 +#if defined (VM_PDP10) /* PDP10 version */ +#include "pdp10_defs.h" #define PT_DIS DEV_DIS -#else -#include "pdp11_defs.h" /* PDP-11 version */ -#define VM_PDP11 1 -#define PT_RDX 8 -#define PT_DIS 0 -#endif +extern int32 int_req; +extern int32 int_vec[32]; +#elif defined (VM_VAX) /* VAX version */ +#include "vax_defs.h" +#define PT_DIS DEV_DIS extern int32 int_req[IPL_HLVL]; extern int32 int_vec[IPL_HLVL][32]; -#include "dec_pt.h" + +#else /* PDP-11 version */ +#include "pdp11_defs.h" +#define PT_DIS 0 +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; +#endif + +#define PTRCSR_IMP (CSR_ERR+CSR_BUSY+CSR_DONE+CSR_IE) /* paper tape reader */ +#define PTRCSR_RW (CSR_IE) +#define PTPCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* paper tape punch */ +#define PTPCSR_RW (CSR_IE) + +int32 ptr_csr = 0; /* control/status */ +int32 ptr_stopioe = 0; /* stop on error */ +int32 ptp_csr = 0; /* control/status */ +int32 ptp_stopioe = 0; /* stop on error */ + +DEVICE ptr_dev, ptp_dev; +t_stat ptr_rd (int32 *data, int32 PA, int32 access); +t_stat ptr_wr (int32 data, int32 PA, int32 access); +t_stat ptr_svc (UNIT *uptr); +t_stat ptr_reset (DEVICE *dptr); +t_stat ptr_attach (UNIT *uptr, char *ptr); +t_stat ptr_detach (UNIT *uptr); +t_stat ptp_rd (int32 *data, int32 PA, int32 access); +t_stat ptp_wr (int32 data, int32 PA, int32 access); +t_stat ptp_svc (UNIT *uptr); +t_stat ptp_reset (DEVICE *dptr); +t_stat ptp_attach (UNIT *uptr, char *ptr); +t_stat ptp_detach (UNIT *uptr); + +/* PTR data structures + + ptr_dev PTR device descriptor + ptr_unit PTR unit descriptor + ptr_reg PTR register list +*/ + +DIB ptr_dib = { IOBA_PTR, IOLN_PTR, &ptr_rd, &ptr_wr, + 1, IVCL (PTR), VEC_PTR, { NULL } }; + +UNIT ptr_unit = { + UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), + SERIAL_IN_WAIT }; + +REG ptr_reg[] = { + { GRDATA (BUF, ptr_unit.buf, DEV_RDX, 8, 0) }, + { GRDATA (CSR, ptr_csr, DEV_RDX, 16, 0) }, + { FLDATA (INT, int_req, INT_V_PTR) }, + { FLDATA (ERR, ptr_csr, CSR_V_ERR) }, + { FLDATA (BUSY, ptr_csr, CSR_V_BUSY) }, + { FLDATA (DONE, ptr_csr, CSR_V_DONE) }, + { FLDATA (IE, ptr_csr, CSR_V_IE) }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, + { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, + { FLDATA (STOP_IOE, ptr_stopioe, 0) }, + { FLDATA (DEVDIS, ptr_dev.flags, DEV_V_DIS), REG_HRO }, + { NULL } }; + +MTAB ptr_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL, + NULL, &show_addr, NULL }, + { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, + NULL, &show_vec, NULL }, + { 0 } }; + +DEVICE ptr_dev = { + "PTR", &ptr_unit, ptr_reg, ptr_mod, + 1, 10, 31, 1, DEV_RDX, 8, + NULL, NULL, &ptr_reset, + NULL, &ptr_attach, &ptr_detach, + &ptr_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS }; + +/* PTP data structures + + ptp_dev PTP device descriptor + ptp_unit PTP unit descriptor + ptp_reg PTP register list +*/ + +DIB ptp_dib = { IOBA_PTP, IOLN_PTP, &ptp_rd, &ptp_wr, + 1, IVCL (PTP), VEC_PTP, { NULL } }; + +UNIT ptp_unit = { + UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; + +REG ptp_reg[] = { + { GRDATA (BUF, ptp_unit.buf, DEV_RDX, 8, 0) }, + { GRDATA (CSR, ptp_csr, DEV_RDX, 16, 0) }, + { FLDATA (INT, int_req, INT_V_PTP) }, + { FLDATA (ERR, ptp_csr, CSR_V_ERR) }, + { FLDATA (DONE, ptp_csr, CSR_V_DONE) }, + { FLDATA (IE, ptp_csr, CSR_V_IE) }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, + { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, + { FLDATA (STOP_IOE, ptp_stopioe, 0) }, + { NULL } }; + +MTAB ptp_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL, + NULL, &show_addr, NULL }, + { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, + NULL, &show_vec, NULL }, + { 0 } }; + +DEVICE ptp_dev = { + "PTP", &ptp_unit, ptp_reg, ptp_mod, + 1, 10, 31, 1, DEV_RDX, 8, + NULL, NULL, &ptp_reset, + NULL, &ptp_attach, &ptp_detach, + &ptp_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS }; + +/* Paper tape reader I/O address routines */ + +t_stat ptr_rd (int32 *data, int32 PA, int32 access) +{ +switch ((PA >> 1) & 01) { /* decode PA<1> */ +case 0: /* ptr csr */ + *data = ptr_csr & PTRCSR_IMP; + return SCPE_OK; +case 1: /* ptr buf */ + ptr_csr = ptr_csr & ~CSR_DONE; + CLR_INT (PTR); + *data = ptr_unit.buf & 0377; + return SCPE_OK; } +return SCPE_NXM; /* can't get here */ +} + +t_stat ptr_wr (int32 data, int32 PA, int32 access) +{ +switch ((PA >> 1) & 01) { /* decode PA<1> */ +case 0: /* ptr csr */ + if (PA & 1) return SCPE_OK; + if ((data & CSR_IE) == 0) CLR_INT (PTR); + else if (((ptr_csr & CSR_IE) == 0) && (ptr_csr & (CSR_ERR | CSR_DONE))) + SET_INT (PTR); + if (data & CSR_GO) { + ptr_csr = (ptr_csr & ~CSR_DONE) | CSR_BUSY; + CLR_INT (PTR); + if (ptr_unit.flags & UNIT_ATT) /* data to read? */ + sim_activate (&ptr_unit, ptr_unit.wait); + else sim_activate (&ptr_unit, 0); } /* error if not */ + ptr_csr = (ptr_csr & ~PTRCSR_RW) | (data & PTRCSR_RW); + return SCPE_OK; +case 1: /* ptr buf */ + return SCPE_OK; } /* end switch PA */ +return SCPE_NXM; /* can't get here */ +} + +/* Paper tape reader service */ + +t_stat ptr_svc (UNIT *uptr) +{ +int32 temp; + +ptr_csr = (ptr_csr | CSR_ERR) & ~CSR_BUSY; +if (ptr_csr & CSR_IE) SET_INT (PTR); +if ((ptr_unit.flags & UNIT_ATT) == 0) + return IORETURN (ptr_stopioe, SCPE_UNATT); +if ((temp = getc (ptr_unit.fileref)) == EOF) { + if (feof (ptr_unit.fileref)) { + if (ptr_stopioe) printf ("PTR end of file\n"); + else return SCPE_OK; } + else perror ("PTR I/O error"); + clearerr (ptr_unit.fileref); + return SCPE_IOERR; } +ptr_csr = (ptr_csr | CSR_DONE) & ~CSR_ERR; +ptr_unit.buf = temp & 0377; +ptr_unit.pos = ptr_unit.pos + 1; +return SCPE_OK; +} + +/* Paper tape reader support routines */ + +t_stat ptr_reset (DEVICE *dptr) +{ +ptr_unit.buf = 0; +ptr_csr = 0; +if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR; +CLR_INT (PTR); +sim_cancel (&ptr_unit); +return SCPE_OK; +} + +t_stat ptr_attach (UNIT *uptr, char *cptr) +{ +t_stat reason; + +reason = attach_unit (uptr, cptr); +if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR; +else ptr_csr = ptr_csr & ~CSR_ERR; +return reason; +} + +t_stat ptr_detach (UNIT *uptr) +{ +ptr_csr = ptr_csr | CSR_ERR; +return detach_unit (uptr); +} + +/* Paper tape punch I/O address routines */ + +t_stat ptp_rd (int32 *data, int32 PA, int32 access) +{ +switch ((PA >> 1) & 01) { /* decode PA<1> */ +case 0: /* ptp csr */ + *data = ptp_csr & PTPCSR_IMP; + return SCPE_OK; +case 1: /* ptp buf */ + *data = ptp_unit.buf; + return SCPE_OK; } +return SCPE_NXM; /* can't get here */ +} + +t_stat ptp_wr (int32 data, int32 PA, int32 access) +{ +switch ((PA >> 1) & 01) { /* decode PA<1> */ +case 0: /* ptp csr */ + if (PA & 1) return SCPE_OK; + if ((data & CSR_IE) == 0) CLR_INT (PTP); + else if (((ptp_csr & CSR_IE) == 0) && (ptp_csr & (CSR_ERR | CSR_DONE))) + SET_INT (PTP); + ptp_csr = (ptp_csr & ~PTPCSR_RW) | (data & PTPCSR_RW); + return SCPE_OK; +case 1: /* ptp buf */ + if ((PA & 1) == 0) ptp_unit.buf = data & 0377; + ptp_csr = ptp_csr & ~CSR_DONE; + CLR_INT (PTP); + if (ptp_unit.flags & UNIT_ATT) /* file to write? */ + sim_activate (&ptp_unit, ptp_unit.wait); + else sim_activate (&ptp_unit, 0); /* error if not */ + return SCPE_OK; } /* end switch PA */ +return SCPE_NXM; /* can't get here */ +} + +/* Paper tape punch service */ + +t_stat ptp_svc (UNIT *uptr) +{ +ptp_csr = ptp_csr | CSR_ERR | CSR_DONE; +if (ptp_csr & CSR_IE) SET_INT (PTP); +if ((ptp_unit.flags & UNIT_ATT) == 0) + return IORETURN (ptp_stopioe, SCPE_UNATT); +if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) { + perror ("PTP I/O error"); + clearerr (ptp_unit.fileref); + return SCPE_IOERR; } +ptp_csr = ptp_csr & ~CSR_ERR; +ptp_unit.pos = ptp_unit.pos + 1; +return SCPE_OK; +} + +/* Paper tape punch support routines */ + +t_stat ptp_reset (DEVICE *dptr) +{ +ptp_unit.buf = 0; +ptp_csr = CSR_DONE; +if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR; +CLR_INT (PTP); +sim_cancel (&ptp_unit); /* deactivate unit */ +return SCPE_OK; +} + +t_stat ptp_attach (UNIT *uptr, char *cptr) +{ +t_stat reason; + +reason = attach_unit (uptr, cptr); +if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR; +else ptp_csr = ptp_csr & ~CSR_ERR; +return reason; +} + +t_stat ptp_detach (UNIT *uptr) +{ +ptp_csr = ptp_csr | CSR_ERR; +return detach_unit (uptr); +} diff --git a/PDP11/pdp11_rk.c b/PDP11/pdp11_rk.c index 55f5528c..5dc8b1e2 100644 --- a/PDP11/pdp11_rk.c +++ b/PDP11/pdp11_rk.c @@ -1,6 +1,6 @@ /* pdp11_rk.c: RK11 cartridge disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -428,7 +428,7 @@ t_stat rk_svc (UNIT *uptr) { int32 i, drv, err, awc, wc, t; int32 da, track, sect; -t_addr ma; +uint32 ma; uint16 comp; drv = uptr - rk_dev.units; /* get drv number */ diff --git a/PDP11/pdp11_rl.c b/PDP11/pdp11_rl.c index 1c623837..67932ae4 100644 --- a/PDP11/pdp11_rl.c +++ b/PDP11/pdp11_rl.c @@ -1,6 +1,6 @@ /* pdp11_rl.c: RL11 (RLV12) cartridge disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ rl RL11(RLV12)/RL01/RL02 cartridge disk + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support 29-Sep-02 RMS Added variable address support to bootstrap Added vector change/display support Revised mapping nomenclature @@ -65,15 +67,18 @@ - VAX Q22 systems - the RL11 must go through the I/O map */ -#if defined (USE_INT64) /* VAX version */ -#include "vax_defs.h" -#define VM_VAX 1 -#define RL_RDX 16 +#if defined (VM_PDP10) /* PDP10 version */ +#error "RL11 is not supported on the PDP-10!" -#else /* PDP11 version */ +#elif defined (VM_VAX) /* VAX version */ +#include "vax_defs.h" +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; + +#else /* PDP-11 version */ #include "pdp11_defs.h" -#define VM_PDP11 1 -#define RL_RDX 8 +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; extern int32 cpu_18b, cpu_ubm; #endif @@ -233,24 +238,24 @@ UNIT rl_unit[] = { UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) } }; REG rl_reg[] = { - { GRDATA (RLCS, rlcs, RL_RDX, 16, 0) }, - { GRDATA (RLDA, rlda, RL_RDX, 16, 0) }, - { GRDATA (RLBA, rlba, RL_RDX, 16, 0) }, - { GRDATA (RLBAE, rlbae, RL_RDX, 6, 0) }, - { GRDATA (RLMP, rlmp, RL_RDX, 16, 0) }, - { GRDATA (RLMP1, rlmp1, RL_RDX, 16, 0) }, - { GRDATA (RLMP2, rlmp2, RL_RDX, 16, 0) }, + { GRDATA (RLCS, rlcs, DEV_RDX, 16, 0) }, + { GRDATA (RLDA, rlda, DEV_RDX, 16, 0) }, + { GRDATA (RLBA, rlba, DEV_RDX, 16, 0) }, + { GRDATA (RLBAE, rlbae, DEV_RDX, 6, 0) }, + { GRDATA (RLMP, rlmp, DEV_RDX, 16, 0) }, + { GRDATA (RLMP1, rlmp1, DEV_RDX, 16, 0) }, + { GRDATA (RLMP2, rlmp2, DEV_RDX, 16, 0) }, { FLDATA (INT, IREQ (RL), INT_V_RL) }, { FLDATA (ERR, rlcs, CSR_V_ERR) }, { FLDATA (DONE, rlcs, CSR_V_DONE) }, { FLDATA (IE, rlcs, CSR_V_IE) }, { DRDATA (STIME, rl_swait, 24), PV_LEFT }, { DRDATA (RTIME, rl_rwait, 24), PV_LEFT }, - { URDATA (CAPAC, rl_unit[0].capac, 10, 31, 0, + { URDATA (CAPAC, rl_unit[0].capac, 10, T_ADDR_W, 0, RL_NUMDR, PV_LEFT + REG_HRO) }, { FLDATA (STOP_IOE, rl_stopioe, 0) }, - { GRDATA (DEVADDR, rl_dib.ba, RL_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, rl_dib.vec, RL_RDX, 16, 0), REG_HRO }, + { GRDATA (DEVADDR, rl_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, rl_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { NULL } }; MTAB rl_mod[] = { @@ -273,7 +278,7 @@ MTAB rl_mod[] = { DEVICE rl_dev = { "RL", rl_unit, rl_reg, rl_mod, - RL_NUMDR, RL_RDX, 24, 1, RL_RDX, 16, + RL_NUMDR, DEV_RDX, 24, 1, DEV_RDX, 16, NULL, NULL, &rl_reset, &rl_boot, &rl_attach, NULL, &rl_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS }; @@ -404,7 +409,7 @@ t_stat rl_svc (UNIT *uptr) { int32 err, wc, maxwc, t; int32 i, func, da, awc; -t_addr ma; +uint32 ma; uint16 comp; func = GET_FUNC (rlcs); /* get function */ @@ -538,18 +543,19 @@ return SCPE_OK; t_stat rl_attach (UNIT *uptr, char *cptr) { -int32 p; +uint32 p; t_stat r; uptr->capac = (uptr->flags & UNIT_RL02)? RL02_SIZE: RL01_SIZE; -r = attach_unit (uptr, cptr); -if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r; +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) return r; /* error? */ uptr->TRK = 0; /* cylinder 0 */ uptr->STAT = RLDS_VCK; /* new volume */ -if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; -if ((p = ftell (uptr->fileref)) == 0) { - if (uptr->flags & UNIT_RO) return SCPE_OK; +if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; /* seek to end */ +if ((p = ftell (uptr->fileref)) == 0) { /* new disk image? */ + if (uptr->flags & UNIT_RO) return SCPE_OK; /* if ro, done */ return pdp11_bad_block (uptr, RL_NUMSC, RL_NUMWD); } +if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */ if (p > (RL01_SIZE * sizeof (int16))) { uptr->flags = uptr->flags | UNIT_RL02; uptr->capac = RL02_SIZE; } diff --git a/PDP11/pdp11_rp.c b/PDP11/pdp11_rp.c index cdd36a79..d8246211 100644 --- a/PDP11/pdp11_rp.c +++ b/PDP11/pdp11_rp.c @@ -1,6 +1,6 @@ /* pdp11_rp.c - RP04/05/06/07 RM02/03/05/80 "Massbus style" disk controller - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ rp RH/RP/RM moving head disks + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support 29-Sep-02 RMS Added variable address support to bootstrap Added vector change/display support Revised mapping mnemonics @@ -89,23 +91,27 @@ provides an internal mode flag for RH11 vs RH70 */ -#if defined (USE_INT64) /* VAX version */ +#if defined (VM_PDP10) /* PDP10 version */ +#error "PDP-10 uses pdp10_rp.c!" + +#elif defined (VM_VAX) /* VAX version */ #include "vax_defs.h" -#define VM_VAX 1 -#define RP_RDX 16 #define RP_WID 32 #define DMASK 0xFFFF #define RH11 0 /* always 22b */ +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; -#else /* PDP11 version */ +#else /* PDP-11 version */ #include "pdp11_defs.h" -#define VM_PDP11 1 -#define RP_RDX 8 +#define PT_DIS 0 #define RP_WID 16 #define RH (cpu_18b || (cpu_ubm && cpu_rh11)) #define RH11 (RH) extern uint16 *M; extern int32 cpu_18b, cpu_ubm, cpu_rh11; +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; #endif #include @@ -350,11 +356,11 @@ extern int32 cpu_18b, cpu_ubm, cpu_rh11; #define RP07_SIZE (RP07_SECT * RP07_SURF * RP07_CYL * RP_NUMWD) struct drvtyp { - int sect; /* sectors */ - int surf; /* surfaces */ - int cyl; /* cylinders */ - int size; /* #blocks */ - int devtype; /* device type */ + int32 sect; /* sectors */ + int32 surf; /* surfaces */ + int32 cyl; /* cylinders */ + int32 size; /* #blocks */ + int32 devtype; /* device type */ }; static struct drvtyp drv_tab[] = { @@ -442,23 +448,23 @@ UNIT rp_unit[] = { UNIT_ROABLE+(RM03_DTYPE << UNIT_V_DTYPE), RM03_SIZE) } }; REG rp_reg[] = { - { GRDATA (RPCS1, rpcs1, RP_RDX, 16, 0) }, - { GRDATA (RPWC, rpwc, RP_RDX, 16, 0) }, - { GRDATA (RPBA, rpba, RP_RDX, 16, 0) }, - { GRDATA (RPDA, rpda, RP_RDX, 16, 0) }, - { GRDATA (RPCS2, rpcs2, RP_RDX, 16, 0) }, - { BRDATA (RPDS, rpds, RP_RDX, 16, RP_NUMDR) }, - { BRDATA (RPER1, rper1, RP_RDX, 16, RP_NUMDR) }, - { GRDATA (RPOF, rpof, RP_RDX, 16, 0) }, - { GRDATA (RPDC, rpdc, RP_RDX, 16, 0) }, - { GRDATA (RPER2, rper2, RP_RDX, 16, 0) }, - { GRDATA (RPER3, rper3, RP_RDX, 16, 0) }, - { GRDATA (RPEC1, rpec1, RP_RDX, 16, 0) }, - { GRDATA (RPEC2, rpec2, RP_RDX, 16, 0) }, - { GRDATA (RPMR, rpmr, RP_RDX, 16, 0) }, - { GRDATA (RPDB, rpdb, RP_RDX, 16, 0) }, - { GRDATA (RPBAE, rpbae, RP_RDX, 6, 0) }, - { GRDATA (RPCS3, rpcs3, RP_RDX, 16, 0) }, + { GRDATA (RPCS1, rpcs1, DEV_RDX, 16, 0) }, + { GRDATA (RPWC, rpwc, DEV_RDX, 16, 0) }, + { GRDATA (RPBA, rpba, DEV_RDX, 16, 0) }, + { GRDATA (RPDA, rpda, DEV_RDX, 16, 0) }, + { GRDATA (RPCS2, rpcs2, DEV_RDX, 16, 0) }, + { BRDATA (RPDS, rpds, DEV_RDX, 16, RP_NUMDR) }, + { BRDATA (RPER1, rper1, DEV_RDX, 16, RP_NUMDR) }, + { GRDATA (RPOF, rpof, DEV_RDX, 16, 0) }, + { GRDATA (RPDC, rpdc, DEV_RDX, 16, 0) }, + { GRDATA (RPER2, rper2, DEV_RDX, 16, 0) }, + { GRDATA (RPER3, rper3, DEV_RDX, 16, 0) }, + { GRDATA (RPEC1, rpec1, DEV_RDX, 16, 0) }, + { GRDATA (RPEC2, rpec2, DEV_RDX, 16, 0) }, + { GRDATA (RPMR, rpmr, DEV_RDX, 16, 0) }, + { GRDATA (RPDB, rpdb, DEV_RDX, 16, 0) }, + { GRDATA (RPBAE, rpbae, DEV_RDX, 6, 0) }, + { GRDATA (RPCS3, rpcs3, DEV_RDX, 16, 0) }, { FLDATA (IFF, rpiff, 0) }, { FLDATA (INT, IREQ (RP), INT_V_RP) }, { FLDATA (SC, rpcs1, CSR_V_ERR) }, @@ -466,13 +472,13 @@ REG rp_reg[] = { { FLDATA (IE, rpcs1, CSR_V_IE) }, { DRDATA (STIME, rp_swait, 24), REG_NZ + PV_LEFT }, { DRDATA (RTIME, rp_rwait, 24), REG_NZ + PV_LEFT }, - { URDATA (FNC, rp_unit[0].FUNC, RP_RDX, 5, 0, + { URDATA (FNC, rp_unit[0].FUNC, DEV_RDX, 5, 0, RP_NUMDR, REG_HRO) }, - { URDATA (CAPAC, rp_unit[0].capac, 10, 31, 0, + { URDATA (CAPAC, rp_unit[0].capac, 10, T_ADDR_W, 0, RP_NUMDR, PV_LEFT | REG_HRO) }, { FLDATA (STOP_IOE, rp_stopioe, 0) }, - { GRDATA (DEVADDR, rp_dib.ba, RP_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, rp_dib.vec, RP_RDX, 16, 0), REG_HRO }, + { GRDATA (DEVADDR, rp_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, rp_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { NULL } }; MTAB rp_mod[] = { @@ -525,7 +531,7 @@ MTAB rp_mod[] = { DEVICE rp_dev = { "RP", rp_unit, rp_reg, rp_mod, - RP_NUMDR, RP_RDX, 30, 1, RP_RDX, RP_WID, + RP_NUMDR, DEV_RDX, 30, 1, DEV_RDX, RP_WID, NULL, NULL, &rp_reset, &rp_boot, &rp_attach, &rp_detach, &rp_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS }; @@ -863,7 +869,7 @@ t_stat rp_svc (UNIT *uptr) { int32 i, t, dtype, drv, err; int32 wc, awc, da; -t_addr ba; +uint32 ba; uint16 comp; dtype = GET_DTYPE (uptr->flags); /* get drive type */ @@ -1064,20 +1070,20 @@ int32 drv, i, p; t_stat r; uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; -r = attach_unit (uptr, cptr); -if (r != SCPE_OK) return r; +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) return r; /* error? */ drv = uptr - rp_dev.units; /* get drv number */ -rpds[drv] = DS_ATA | DS_MOL | DS_RDY | DS_DPR | +rpds[drv] = DS_ATA | DS_MOL | DS_RDY | DS_DPR | /* upd drv status */ ((uptr->flags & UNIT_WPRT)? DS_WRL: 0); rper1[drv] = 0; -update_rpcs (CS1_SC, drv); +update_rpcs (CS1_SC, drv); /* upd ctlr status */ -if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */ -if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; -if ((p = ftell (uptr->fileref)) == 0) { +if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; /* seek to end */ +if ((p = ftell (uptr->fileref)) == 0) { /* new disk image? */ if (uptr->flags & UNIT_RO) return SCPE_OK; return pdp11_bad_block (uptr, drv_tab[GET_DTYPE (uptr->flags)].sect, RP_NUMWD); } +if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */ for (i = 0; drv_tab[i].sect != 0; i++) { if (p <= (drv_tab[i].size * (int) sizeof (int16))) { uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE); diff --git a/PDP11/pdp11_rq.c b/PDP11/pdp11_rq.c index 25d1743b..484b29f7 100644 --- a/PDP11/pdp11_rq.c +++ b/PDP11/pdp11_rq.c @@ -1,6 +1,6 @@ -/* pdp11_rq.c: RQDX3 disk controller simulator +/* pdp11_rq.c: MSCP disk controller simulator - Copyright (c) 2003, Robert M Supnik + Copyright (c) 2002-2003, Robert M Supnik Derived from work by Stephen F. Shirron Permission is hereby granted, free of charge, to any person obtaining a @@ -26,6 +26,9 @@ rq RQDX3 disk controller + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support + 14-Mar-03 RMS Fixed variable size interaction with save/restore 27-Feb-03 RMS Added user-defined drive support 26-Feb-03 RMS Fixed bug in vector calculation for VAXen 22-Feb-03 RMS Fixed ordering bug in queue process @@ -49,26 +52,29 @@ 17-Dec-01 RMS Added queue process */ -#if defined (USE_INT64) +#if defined (VM_PDP10) /* PDP10 version */ +#error "RQDX3 not supported on PDP-10!" + +#elif defined (VM_VAX) /* VAX version */ #include "vax_defs.h" -#define VM_VAX 1 -#define RQ_RDX 16 #define RQ_AINC 4 #define RQ_WID 32 +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; -#else +#else /* PDP-11 version */ #include "pdp11_defs.h" -#define VM_PDP11 1 -#define RQ_RDX 8 #define RQ_AINC 2 #define RQ_WID 16 extern int32 cpu_18b, cpu_ubm; +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; #endif #if !defined (RQ_NUMCT) #define RQ_NUMCT 4 #elif (RQ_NUMCT > 4) -Assertion failure: RQ_NUMCT exceeds 4 +#error "Assertion failure: RQ_NUMCT exceeds 4" #endif #include "pdp11_uqssp.h" @@ -418,8 +424,9 @@ struct rqpkt { #define RA8U_MOD 11 /* RA82 */ #define RA8U_MED 0x25641052 /* RA82 */ #define RA8U_FLGS RQDF_SDI -#define RA8U_MINC ((5 << 20) / RQ_NUMBY) -#define RA8U_MAXC ((2047 << 20) / RQ_NUMBY) +#define RA8U_MINC 5 /* min cap MB */ +#define RA8U_MAXC 2000 /* max cap MB */ +#define RA8U_EMAXC 1000000 /* ext max cap */ struct drvtyp { int32 sect; /* sectors */ @@ -429,7 +436,7 @@ struct drvtyp { int32 gpc; /* grp/cyl */ int32 xbn; /* XBN size */ int32 dbn; /* DBN size */ - int32 lbn; /* LBN size */ + uint32 lbn; /* LBN size */ int32 rcts; /* RCT size */ int32 rctc; /* RCT copies */ int32 rbn; /* RBNs */ @@ -460,6 +467,7 @@ extern int32 tmr_poll, clk_tps; extern int32 cpu_log; extern UNIT cpu_unit; extern FILE *sim_log; +extern uint32 sim_taddr_64; uint16 *rqxb = NULL; /* xfer buffer */ int32 rq_itime = 200; /* init time, except */ @@ -575,22 +583,22 @@ UNIT rq_unit[] = { { UDATA (&rq_quesvc, UNIT_DIS, 0) } }; REG rq_reg[] = { - { GRDATA (SA, rq_ctx.sa, RQ_RDX, 16, 0) }, - { GRDATA (SAW, rq_ctx.saw, RQ_RDX, 16, 0) }, - { GRDATA (S1DAT, rq_ctx.s1dat, RQ_RDX, 16, 0) }, - { GRDATA (COMM, rq_ctx.comm, RQ_RDX, 22, 0) }, - { GRDATA (CQBA, rq_ctx.cq.ba, RQ_RDX, 22, 0) }, - { GRDATA (CQLNT, rq_ctx.cq.lnt, RQ_RDX, 8, 2), REG_NZ }, - { GRDATA (CQIDX, rq_ctx.cq.idx, RQ_RDX, 8, 2) }, - { GRDATA (RQBA, rq_ctx.rq.ba, RQ_RDX, 22, 0) }, - { GRDATA (RQLNT, rq_ctx.rq.lnt, RQ_RDX, 8, 2), REG_NZ }, - { GRDATA (RQIDX, rq_ctx.rq.idx, RQ_RDX, 8, 2) }, + { GRDATA (SA, rq_ctx.sa, DEV_RDX, 16, 0) }, + { GRDATA (SAW, rq_ctx.saw, DEV_RDX, 16, 0) }, + { GRDATA (S1DAT, rq_ctx.s1dat, DEV_RDX, 16, 0) }, + { GRDATA (COMM, rq_ctx.comm, DEV_RDX, 22, 0) }, + { GRDATA (CQBA, rq_ctx.cq.ba, DEV_RDX, 22, 0) }, + { GRDATA (CQLNT, rq_ctx.cq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (CQIDX, rq_ctx.cq.idx, DEV_RDX, 8, 2) }, + { GRDATA (RQBA, rq_ctx.rq.ba, DEV_RDX, 22, 0) }, + { GRDATA (RQLNT, rq_ctx.rq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (RQIDX, rq_ctx.rq.idx, DEV_RDX, 8, 2) }, { DRDATA (FREE, rq_ctx.freq, 5) }, { DRDATA (RESP, rq_ctx.rspq, 5) }, { DRDATA (PBSY, rq_ctx.pbsy, 5) }, - { GRDATA (CFLGS, rq_ctx.cflgs, RQ_RDX, 16, 0) }, - { GRDATA (CSTA, rq_ctx.csta, RQ_RDX, 4, 0) }, - { GRDATA (PERR, rq_ctx.perr, RQ_RDX, 9, 0) }, + { GRDATA (CFLGS, rq_ctx.cflgs, DEV_RDX, 16, 0) }, + { GRDATA (CSTA, rq_ctx.csta, DEV_RDX, 4, 0) }, + { GRDATA (PERR, rq_ctx.perr, DEV_RDX, 9, 0) }, { DRDATA (CRED, rq_ctx.credits, 5) }, { DRDATA (HAT, rq_ctx.hat, 17) }, { DRDATA (HTMO, rq_ctx.htmo, 17) }, @@ -601,12 +609,13 @@ REG rq_reg[] = { { DRDATA (I4TIME, rq_itime4, 24), PV_LEFT + REG_NZ }, { DRDATA (QTIME, rq_qtime, 24), PV_LEFT + REG_NZ }, { DRDATA (XTIME, rq_xtime, 24), PV_LEFT + REG_NZ }, - { BRDATA (PKTS, rq_ctx.pak, RQ_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) }, + { BRDATA (PKTS, rq_ctx.pak, DEV_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) }, { URDATA (CPKT, rq_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) }, { URDATA (PKTQ, rq_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) }, - { URDATA (UFLG, rq_unit[0].uf, RQ_RDX, 16, 0, RQ_NUMDR, 0) }, - { GRDATA (DEVADDR, rq_dib.ba, RQ_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, rq_dib.vec, RQ_RDX, 16, 0), REG_HRO }, + { URDATA (UFLG, rq_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) }, + { URDATA (CAPAC, rq_unit[0].capac, 10, T_ADDR_W, 0, RQ_NUMDR, PV_LEFT | REG_HRO) }, + { GRDATA (DEVADDR, rq_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, rq_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { DRDATA (DEVLBN, drv_tab[RA8U_DTYPE].lbn, 22), REG_HRO }, { NULL } }; @@ -672,7 +681,7 @@ MTAB rq_mod[] = { DEVICE rq_dev = { "RQ", rq_unit, rq_reg, rq_mod, - RQ_NUMDR + 2, RQ_RDX, 31, RQ_AINC, RQ_RDX, RQ_WID, + RQ_NUMDR + 2, DEV_RDX, 31, RQ_AINC, DEV_RDX, RQ_WID, NULL, NULL, &rq_reset, &rq_boot, &rq_attach, &rq_detach, &rq_dib, DEV_FLTA | DEV_DISABLE | DEV_UBUS | DEV_QBUS }; @@ -703,39 +712,40 @@ UNIT rqb_unit[] = { { UDATA (&rq_quesvc, UNIT_DIS, 0) } }; REG rqb_reg[] = { - { GRDATA (SA, rqb_ctx.sa, RQ_RDX, 16, 0) }, - { GRDATA (SAW, rqb_ctx.saw, RQ_RDX, 16, 0) }, - { GRDATA (S1DAT, rqb_ctx.s1dat, RQ_RDX, 16, 0) }, - { GRDATA (COMM, rqb_ctx.comm, RQ_RDX, 22, 0) }, - { GRDATA (CQBA, rqb_ctx.cq.ba, RQ_RDX, 22, 0) }, - { GRDATA (CQLNT, rqb_ctx.cq.lnt, RQ_RDX, 8, 2), REG_NZ }, - { GRDATA (CQIDX, rqb_ctx.cq.idx, RQ_RDX, 8, 2) }, - { GRDATA (RQBA, rqb_ctx.rq.ba, RQ_RDX, 22, 0) }, - { GRDATA (RQLNT, rqb_ctx.rq.lnt, RQ_RDX, 8, 2), REG_NZ }, - { GRDATA (RQIDX, rqb_ctx.rq.idx, RQ_RDX, 8, 2) }, + { GRDATA (SA, rqb_ctx.sa, DEV_RDX, 16, 0) }, + { GRDATA (SAW, rqb_ctx.saw, DEV_RDX, 16, 0) }, + { GRDATA (S1DAT, rqb_ctx.s1dat, DEV_RDX, 16, 0) }, + { GRDATA (COMM, rqb_ctx.comm, DEV_RDX, 22, 0) }, + { GRDATA (CQBA, rqb_ctx.cq.ba, DEV_RDX, 22, 0) }, + { GRDATA (CQLNT, rqb_ctx.cq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (CQIDX, rqb_ctx.cq.idx, DEV_RDX, 8, 2) }, + { GRDATA (RQBA, rqb_ctx.rq.ba, DEV_RDX, 22, 0) }, + { GRDATA (RQLNT, rqb_ctx.rq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (RQIDX, rqb_ctx.rq.idx, DEV_RDX, 8, 2) }, { DRDATA (FREE, rqb_ctx.freq, 5) }, { DRDATA (RESP, rqb_ctx.rspq, 5) }, { DRDATA (PBSY, rqb_ctx.pbsy, 5) }, - { GRDATA (CFLGS, rqb_ctx.cflgs, RQ_RDX, 16, 0) }, - { GRDATA (CSTA, rqb_ctx.csta, RQ_RDX, 4, 0) }, - { GRDATA (PERR, rqb_ctx.perr, RQ_RDX, 9, 0) }, + { GRDATA (CFLGS, rqb_ctx.cflgs, DEV_RDX, 16, 0) }, + { GRDATA (CSTA, rqb_ctx.csta, DEV_RDX, 4, 0) }, + { GRDATA (PERR, rqb_ctx.perr, DEV_RDX, 9, 0) }, { DRDATA (CRED, rqb_ctx.credits, 5) }, { DRDATA (HAT, rqb_ctx.hat, 17) }, { DRDATA (HTMO, rqb_ctx.htmo, 17) }, { FLDATA (PRGI, rqb_ctx.prgi, 0), REG_HIDDEN }, { FLDATA (PIP, rqb_ctx.pip, 0), REG_HIDDEN }, { FLDATA (INT, rqb_ctx.irq, 0) }, - { BRDATA (PKTS, rqb_ctx.pak, RQ_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) }, + { BRDATA (PKTS, rqb_ctx.pak, DEV_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) }, { URDATA (CPKT, rqb_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) }, { URDATA (PKTQ, rqb_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) }, - { URDATA (UFLG, rqb_unit[0].uf, RQ_RDX, 16, 0, RQ_NUMDR, 0) }, - { GRDATA (DEVADDR, rqb_dib.ba, RQ_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, rqb_dib.vec, RQ_RDX, 16, 0), REG_HRO }, + { URDATA (UFLG, rqb_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) }, + { URDATA (CAPAC, rqb_unit[0].capac, 10, 31, 0, RQ_NUMDR, PV_LEFT | REG_HRO) }, + { GRDATA (DEVADDR, rqb_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, rqb_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { NULL } }; DEVICE rqb_dev = { "RQB", rqb_unit, rqb_reg, rq_mod, - RQ_NUMDR + 2, RQ_RDX, 31, RQ_AINC, RQ_RDX, RQ_WID, + RQ_NUMDR + 2, DEV_RDX, 31, RQ_AINC, DEV_RDX, RQ_WID, NULL, NULL, &rq_reset, &rq_boot, &rq_attach, &rq_detach, &rqb_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS }; @@ -766,39 +776,40 @@ UNIT rqc_unit[] = { { UDATA (&rq_quesvc, UNIT_DIS, 0) } }; REG rqc_reg[] = { - { GRDATA (SA, rqc_ctx.sa, RQ_RDX, 16, 0) }, - { GRDATA (SAW, rqc_ctx.saw, RQ_RDX, 16, 0) }, - { GRDATA (S1DAT, rqc_ctx.s1dat, RQ_RDX, 16, 0) }, - { GRDATA (COMM, rqc_ctx.comm, RQ_RDX, 22, 0) }, - { GRDATA (CQBA, rqc_ctx.cq.ba, RQ_RDX, 22, 0) }, - { GRDATA (CQLNT, rqc_ctx.cq.lnt, RQ_RDX, 8, 2), REG_NZ }, - { GRDATA (CQIDX, rqc_ctx.cq.idx, RQ_RDX, 8, 2) }, - { GRDATA (RQBA, rqc_ctx.rq.ba, RQ_RDX, 22, 0) }, - { GRDATA (RQLNT, rqc_ctx.rq.lnt, RQ_RDX, 8, 2), REG_NZ }, - { GRDATA (RQIDX, rqc_ctx.rq.idx, RQ_RDX, 8, 2) }, + { GRDATA (SA, rqc_ctx.sa, DEV_RDX, 16, 0) }, + { GRDATA (SAW, rqc_ctx.saw, DEV_RDX, 16, 0) }, + { GRDATA (S1DAT, rqc_ctx.s1dat, DEV_RDX, 16, 0) }, + { GRDATA (COMM, rqc_ctx.comm, DEV_RDX, 22, 0) }, + { GRDATA (CQBA, rqc_ctx.cq.ba, DEV_RDX, 22, 0) }, + { GRDATA (CQLNT, rqc_ctx.cq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (CQIDX, rqc_ctx.cq.idx, DEV_RDX, 8, 2) }, + { GRDATA (RQBA, rqc_ctx.rq.ba, DEV_RDX, 22, 0) }, + { GRDATA (RQLNT, rqc_ctx.rq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (RQIDX, rqc_ctx.rq.idx, DEV_RDX, 8, 2) }, { DRDATA (FREE, rqc_ctx.freq, 5) }, { DRDATA (RESP, rqc_ctx.rspq, 5) }, { DRDATA (PBSY, rqc_ctx.pbsy, 5) }, - { GRDATA (CFLGS, rqc_ctx.cflgs, RQ_RDX, 16, 0) }, - { GRDATA (CSTA, rqc_ctx.csta, RQ_RDX, 4, 0) }, - { GRDATA (PERR, rqc_ctx.perr, RQ_RDX, 9, 0) }, + { GRDATA (CFLGS, rqc_ctx.cflgs, DEV_RDX, 16, 0) }, + { GRDATA (CSTA, rqc_ctx.csta, DEV_RDX, 4, 0) }, + { GRDATA (PERR, rqc_ctx.perr, DEV_RDX, 9, 0) }, { DRDATA (CRED, rqc_ctx.credits, 5) }, { DRDATA (HAT, rqc_ctx.hat, 17) }, { DRDATA (HTMO, rqc_ctx.htmo, 17) }, { FLDATA (PRGI, rqc_ctx.prgi, 0), REG_HIDDEN }, { FLDATA (PIP, rqc_ctx.pip, 0), REG_HIDDEN }, { FLDATA (INT, rqc_ctx.irq, 0) }, - { BRDATA (PKTS, rqc_ctx.pak, RQ_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) }, + { BRDATA (PKTS, rqc_ctx.pak, DEV_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) }, { URDATA (CPKT, rqc_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) }, { URDATA (PKTQ, rqc_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) }, - { URDATA (UFLG, rqc_unit[0].uf, RQ_RDX, 16, 0, RQ_NUMDR, 0) }, - { GRDATA (DEVADDR, rqc_dib.ba, RQ_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, rqc_dib.vec, RQ_RDX, 16, 0), REG_HRO }, + { URDATA (UFLG, rqc_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) }, + { URDATA (CAPAC, rqc_unit[0].capac, 10, 31, 0, RQ_NUMDR, PV_LEFT | REG_HRO) }, + { GRDATA (DEVADDR, rqc_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, rqc_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { NULL } }; DEVICE rqc_dev = { "RQC", rqc_unit, rqc_reg, rq_mod, - RQ_NUMDR + 2, RQ_RDX, 31, RQ_AINC, RQ_RDX, RQ_WID, + RQ_NUMDR + 2, DEV_RDX, 31, RQ_AINC, DEV_RDX, RQ_WID, NULL, NULL, &rq_reset, &rq_boot, &rq_attach, &rq_detach, &rqc_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS }; @@ -829,39 +840,40 @@ UNIT rqd_unit[] = { { UDATA (&rq_quesvc, UNIT_DIS, 0) } }; REG rqd_reg[] = { - { GRDATA (SA, rqd_ctx.sa, RQ_RDX, 16, 0) }, - { GRDATA (SAW, rqd_ctx.saw, RQ_RDX, 16, 0) }, - { GRDATA (S1DAT, rqd_ctx.s1dat, RQ_RDX, 16, 0) }, - { GRDATA (COMM, rqd_ctx.comm, RQ_RDX, 22, 0) }, - { GRDATA (CQBA, rqd_ctx.cq.ba, RQ_RDX, 22, 0) }, - { GRDATA (CQLNT, rqd_ctx.cq.lnt, RQ_RDX, 8, 2), REG_NZ }, - { GRDATA (CQIDX, rqd_ctx.cq.idx, RQ_RDX, 8, 2) }, - { GRDATA (RQBA, rqd_ctx.rq.ba, RQ_RDX, 22, 0) }, - { GRDATA (RQLNT, rqd_ctx.rq.lnt, RQ_RDX, 8, 2), REG_NZ }, - { GRDATA (RQIDX, rqd_ctx.rq.idx, RQ_RDX, 8, 2) }, + { GRDATA (SA, rqd_ctx.sa, DEV_RDX, 16, 0) }, + { GRDATA (SAW, rqd_ctx.saw, DEV_RDX, 16, 0) }, + { GRDATA (S1DAT, rqd_ctx.s1dat, DEV_RDX, 16, 0) }, + { GRDATA (COMM, rqd_ctx.comm, DEV_RDX, 22, 0) }, + { GRDATA (CQBA, rqd_ctx.cq.ba, DEV_RDX, 22, 0) }, + { GRDATA (CQLNT, rqd_ctx.cq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (CQIDX, rqd_ctx.cq.idx, DEV_RDX, 8, 2) }, + { GRDATA (RQBA, rqd_ctx.rq.ba, DEV_RDX, 22, 0) }, + { GRDATA (RQLNT, rqd_ctx.rq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (RQIDX, rqd_ctx.rq.idx, DEV_RDX, 8, 2) }, { DRDATA (FREE, rqd_ctx.freq, 5) }, { DRDATA (RESP, rqd_ctx.rspq, 5) }, { DRDATA (PBSY, rqd_ctx.pbsy, 5) }, - { GRDATA (CFLGS, rqd_ctx.cflgs, RQ_RDX, 16, 0) }, - { GRDATA (CSTA, rqd_ctx.csta, RQ_RDX, 4, 0) }, - { GRDATA (PERR, rqd_ctx.perr, RQ_RDX, 9, 0) }, + { GRDATA (CFLGS, rqd_ctx.cflgs, DEV_RDX, 16, 0) }, + { GRDATA (CSTA, rqd_ctx.csta, DEV_RDX, 4, 0) }, + { GRDATA (PERR, rqd_ctx.perr, DEV_RDX, 9, 0) }, { DRDATA (CRED, rqd_ctx.credits, 5) }, { DRDATA (HAT, rqd_ctx.hat, 17) }, { DRDATA (HTMO, rqd_ctx.htmo, 17) }, { FLDATA (PRGI, rqd_ctx.prgi, 0), REG_HIDDEN }, { FLDATA (PIP, rqd_ctx.pip, 0), REG_HIDDEN }, { FLDATA (INT, rqd_ctx.irq, 0) }, - { BRDATA (PKTS, rqd_ctx.pak, RQ_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) }, + { BRDATA (PKTS, rqd_ctx.pak, DEV_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) }, { URDATA (CPKT, rqd_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) }, { URDATA (PKTQ, rqd_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) }, - { URDATA (UFLG, rqd_unit[0].uf, RQ_RDX, 16, 0, RQ_NUMDR, 0) }, - { GRDATA (DEVADDR, rqd_dib.ba, RQ_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, rqd_dib.vec, RQ_RDX, 16, 0), REG_HRO }, + { URDATA (UFLG, rqd_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) }, + { URDATA (CAPAC, rqd_unit[0].capac, 10, 31, 0, RQ_NUMDR, PV_LEFT | REG_HRO) }, + { GRDATA (DEVADDR, rqd_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, rqd_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { NULL } }; DEVICE rqd_dev = { "RQD", rqd_unit, rqd_reg, rq_mod, - RQ_NUMDR + 2, RQ_RDX, 31, RQ_AINC, RQ_RDX, RQ_WID, + RQ_NUMDR + 2, DEV_RDX, 31, RQ_AINC, DEV_RDX, RQ_WID, NULL, NULL, &rq_reset, &rq_boot, &rq_attach, &rq_detach, &rqd_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS }; @@ -944,7 +956,7 @@ return -1; t_bool rq_step4 (MSC *cp) { int32 i, lnt; -t_addr base; +uint32 base; uint16 zero[SA_COMM_MAX >> 1]; cp->rq.ioff = SA_COMM_RI; /* set intr offset */ @@ -1420,7 +1432,7 @@ if ((cmd != OP_ACC) && (cmd != OP_ERS) && /* 'real' xfer */ return (ST_HST | SB_HST_OA); /* host buf odd */ if (bc & 1) return (ST_HST | SB_HST_OC); /* odd byte cnt? */ if (bc & 0xF0000000) return (ST_CMD | I_BCNT); /* 'reasonable' bc? */ -if (lbn & 0xF0000000) return (ST_CMD | I_LBN); /* 'reasonable' lbn? */ +/* if (lbn & 0xF0000000) return (ST_CMD | I_LBN); /* 'reasonable' lbn? */ if (lbn >= maxlbn) { /* accessing RCT? */ if (lbn >= (maxlbn + drv_tab[dtyp].rcts)) /* beyond copy 1? */ return (ST_CMD | I_LBN); /* lbn err */ @@ -1449,7 +1461,7 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* get cmd */ uint32 ba = GETP32 (pkt, RW_WBAL); /* buf addr */ uint32 bc = GETP32 (pkt, RW_WBCL); /* byte count */ uint32 bl = GETP32 (pkt, RW_WBLL); /* block addr */ -uint32 da = bl * RQ_NUMBY; /* disk addr */ +t_addr da = ((t_addr) bl) * RQ_NUMBY; /* disk addr */ if ((cp == NULL) || (pkt == 0)) return STOP_RQ; /* what??? */ tbc = (bc > RQ_MAXFR)? RQ_MAXFR: bc; /* trim cnt to max */ @@ -1472,7 +1484,7 @@ if ((cmd == OP_ERS) || (cmd == OP_WR)) { /* write op? */ if (cmd == OP_ERS) { /* erase? */ wwc = ((tbc + (RQ_NUMBY - 1)) & ~(RQ_NUMBY - 1)) >> 1; for (i = 0; i < wwc; i++) rqxb[i] = 0; /* clr buf */ - err = fseek (uptr->fileref, da, SEEK_SET); /* set pos */ + err = fseek_ext (uptr->fileref, da, SEEK_SET); /* set pos */ if (!err) fxwrite (rqxb, sizeof (int16), wwc, uptr->fileref); err = ferror (uptr->fileref); } /* end if erase */ @@ -1481,7 +1493,7 @@ else if (cmd == OP_WR) { /* write? */ if (abc = tbc - t) { /* any xfer? */ wwc = ((abc + (RQ_NUMBY - 1)) & ~(RQ_NUMBY - 1)) >> 1; for (i = (abc >> 1); i < wwc; i++) rqxb[i] = 0; - err = fseek (uptr->fileref, da, SEEK_SET); + err = fseek_ext (uptr->fileref, da, SEEK_SET); if (!err) fxwrite (rqxb, sizeof (int16), wwc, uptr->fileref); err = ferror (uptr->fileref); } if (t) { /* nxm? */ @@ -1491,7 +1503,7 @@ else if (cmd == OP_WR) { /* write? */ rq_rw_end (cp, uptr, EF_LOG, ST_HST | SB_HST_NXM); return SCPE_OK; } } /* end else wr */ -else { err = fseek (uptr->fileref, da, SEEK_SET); /* set pos */ +else { err = fseek_ext (uptr->fileref, da, SEEK_SET); /* set pos */ if (!err) { i = fxread (rqxb, sizeof (int16), tbc >> 1, uptr->fileref); for ( ; i < (tbc >> 1); i++) rqxb[i] = 0; /* fill */ @@ -1733,8 +1745,7 @@ return; t_bool rq_getpkt (MSC *cp, int32 *pkt) { -uint32 desc; -t_addr addr; +uint32 addr, desc; if (!rq_getdesc (cp, &cp->cq, &desc)) return ERR; /* get cmd desc */ if ((desc & UQ_DESC_OWN) == 0) { /* none */ @@ -1755,8 +1766,7 @@ return rq_putdesc (cp, &cp->cq, desc); /* release desc */ t_bool rq_putpkt (MSC *cp, int32 pkt, t_bool qt) { -uint32 desc, lnt, cr; -t_addr addr; +uint32 addr, desc, lnt, cr; DEVICE *dptr = rq_devmap[cp->cnum]; if (pkt == 0) return OK; /* any packet? */ @@ -1788,7 +1798,7 @@ return rq_putdesc (cp, &cp->rq, desc); /* release desc */ t_bool rq_getdesc (MSC *cp, struct uq_ring *ring, uint32 *desc) { -t_addr addr = ring->ba + ring->idx; +uint32 addr = ring->ba + ring->idx; uint16 d[2]; if (Map_ReadW (addr, 4, d, MAP)) /* fetch desc */ @@ -1806,7 +1816,7 @@ return OK; t_bool rq_putdesc (MSC *cp, struct uq_ring *ring, uint32 desc) { uint32 prvd, newd = (desc & ~UQ_DESC_OWN) | UQ_DESC_F; -t_addr prva, addr = ring->ba + ring->idx; +uint32 prva, addr = ring->ba + ring->idx; uint16 d[2]; d[0] = newd & 0xFFFF; /* 32b to 16b */ @@ -1899,7 +1909,7 @@ return; void rq_ring_int (MSC *cp, struct uq_ring *ring) { -t_addr iadr = cp->comm + ring->ioff; /* addr intr wd */ +uint32 iadr = cp->comm + ring->ioff; /* addr intr wd */ uint16 flag = 1; Map_WriteW (iadr, 2, &flag, MAP); /* write flag */ @@ -1991,7 +2001,8 @@ return SCPE_OK; t_stat rq_set_type (UNIT *uptr, int32 val, char *cptr, void *desc) { -int32 cap; +uint32 cap; +uint32 max = sim_taddr_64? RA8U_EMAXC: RA8U_MAXC; t_stat r; if ((val < 0) || (val > RA8U_DTYPE) || ((val != RA8U_DTYPE) && cptr)) @@ -2000,9 +2011,9 @@ if (uptr->flags & UNIT_ATT) return SCPE_ALATT; if (cptr) { cap = (int32) get_uint (cptr, 10, RA8U_MAXC, &r); if ((r != SCPE_OK) || (cap < RA8U_MINC)) return SCPE_ARG; - drv_tab[val].lbn = cap; } + drv_tab[val].lbn = cap << (20 - 9); } uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (val << UNIT_V_DTYPE); -uptr->capac = drv_tab[val].lbn * RQ_NUMBY; +uptr->capac = ((t_addr) drv_tab[val].lbn) * RQ_NUMBY; return SCPE_OK; } diff --git a/PDP11/pdp11_rx.c b/PDP11/pdp11_rx.c index 8f56f7bf..ea10d132 100644 --- a/PDP11/pdp11_rx.c +++ b/PDP11/pdp11_rx.c @@ -1,6 +1,6 @@ /* pdp11_rx.c: RX11/RX01 floppy disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -301,7 +301,7 @@ return SCPE_OK; t_stat rx_svc (UNIT *uptr) { int32 i, func; -t_addr da; +uint32 da; func = RXCS_GETFNC (rx_csr); /* get function */ switch (rx_state) { /* case on state */ diff --git a/PDP11/pdp11_ry.c b/PDP11/pdp11_ry.c index c3a74f6b..1a17cd9b 100644 --- a/PDP11/pdp11_ry.c +++ b/PDP11/pdp11_ry.c @@ -25,6 +25,9 @@ ry RY11/RX02 floppy disk + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support + 14-Mar-03 RMS Fixed variable size interaction with save/restore 03-Mar-03 RMS Fixed autosizing 12-Oct-02 RMS Added autoconfigure support @@ -32,14 +35,16 @@ Tracks are numbered 0-76, sectors 1-26. */ -#if defined (USE_INT64) /* PDP-10 !! */ +#if defined (VM_PDP10) /* PDP10 version */ #include "pdp10_defs.h" -#define VM_PDP10 1 extern int32 int_req; extern int32 int_vec[32]; -#else -#include "pdp11_defs.h" /* PDP-11 */ -#define VM_PDP11 1 + +#elif defined (VM_VAX) /* VAX version */ +#error "RX211 not supported on VAX!" + +#else /* PDP-11 version */ +#include "pdp11_defs.h" extern int32 int_req[IPL_HLVL]; extern int32 int_vec[IPL_HLVL][32]; #endif @@ -51,7 +56,7 @@ extern int32 int_vec[IPL_HLVL][32]; #define RX_NUMBY 128 #define RX_SIZE (RX_NUMTR * RX_NUMSC * RX_NUMBY) #define RY_NUMBY 256 /* bytes/sector */ -#define RY_SIZE (RX_NUMTR * RX_NUMSC * RY_NUMBY) +#define RY_SIZE (RX_NUMTR * RX_NUMSC * RY_NUMBY) #define RX_NUMDR 2 /* drives/controller */ #define RX_M_NUMDR 01 #define UNIT_V_WLK (UNIT_V_UF) /* write locked */ @@ -190,6 +195,8 @@ REG ry_reg[] = { { DRDATA (XTIME, ry_xwait, 24), PV_LEFT }, { BRDATA (SBUF, rx2xb, 8, 8, RY_NUMBY) }, { FLDATA (STOP_IOE, ry_stopioe, 0) }, + { URDATA (CAPAC, ry_unit[0].capac, 10, T_ADDR_W, 0, + RX_NUMDR, REG_HRO | PV_LEFT) }, { ORDATA (DEVADDR, ry_dib.ba, 32), REG_HRO }, { ORDATA (DEVVEC, ry_dib.vec, 16), REG_HRO }, { NULL } }; @@ -333,7 +340,7 @@ t_stat ry_svc (UNIT *uptr) { int32 i, t, func, bps; static uint8 estat[8]; -t_addr ba, da; +uint32 ba, da; func = RYCS_GETFNC (ry_csr); /* get function */ bps = (ry_csr & RYCS_DEN)? RY_NUMBY: RX_NUMBY; /* get sector size */ @@ -512,7 +519,7 @@ return auto_config (0, 0); /* run autoconfig */ t_stat ry_attach (UNIT *uptr, char *cptr) { -t_addr sz; +uint32 sz; if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) { if (sz > RX_SIZE) uptr->flags = uptr->flags | UNIT_DEN; diff --git a/PDP11/pdp11_stddev.c b/PDP11/pdp11_stddev.c index a3bdc31c..f9c4b24d 100644 --- a/PDP11/pdp11_stddev.c +++ b/PDP11/pdp11_stddev.c @@ -26,6 +26,7 @@ tti,tto DL11 terminal input/output clk KW11L line frequency clock + 25-Apr-03 RMS Revised for extended file support 01-Mar-03 RMS Added SET/SHOW CLOCK FREQ, SET TTI CTRL-C 22-Nov-02 RMS Changed terminal default to 7B for UNIX 01-Nov-02 RMS Added 7B/8B support to terminal @@ -106,7 +107,7 @@ REG tti_reg[] = { { FLDATA (ERR, tti_csr, CSR_V_ERR) }, { FLDATA (DONE, tti_csr, CSR_V_DONE) }, { FLDATA (IE, tti_csr, CSR_V_IE) }, - { DRDATA (POS, tti_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; @@ -147,7 +148,7 @@ REG tto_reg[] = { { FLDATA (ERR, tto_csr, CSR_V_ERR) }, { FLDATA (DONE, tto_csr, CSR_V_DONE) }, { FLDATA (IE, tto_csr, CSR_V_IE) }, - { DRDATA (POS, tto_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT }, { NULL } }; diff --git a/PDP11/pdp11_sys.c b/PDP11/pdp11_sys.c index ecc8c78c..2a140b75 100644 --- a/PDP11/pdp11_sys.c +++ b/PDP11/pdp11_sys.c @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 06-May-03 RMS Added support for second DEQNA/DELQA 09-Jan-03 RMS Added DELUA support 17-Oct-02 RMS Fixed bugs in branch, SOB address parsing 09-Oct-02 RMS Added DELQA support @@ -62,7 +63,8 @@ extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev; extern DEVICE dt_dev; extern DEVICE tm_dev, ts_dev; extern DEVICE tq_dev; -extern DEVICE xq_dev, xu_dev; +extern DEVICE xq_dev, xqb_dev; +extern DEVICE xu_dev; extern UNIT cpu_unit; extern REG cpu_reg[]; extern uint16 *M; @@ -109,6 +111,7 @@ DEVICE *sim_devices[] = { &ts_dev, &tq_dev, &xq_dev, + &xqb_dev, &xu_dev, NULL }; @@ -161,7 +164,7 @@ const char *sim_stop_messages[] = { t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) { int32 csum, count, state, i; -t_addr origin; +uint32 origin; if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; state = csum = 0; diff --git a/PDP11/pdp11_tc.c b/PDP11/pdp11_tc.c index 64c02bbb..414dee28 100644 --- a/PDP11/pdp11_tc.c +++ b/PDP11/pdp11_tc.c @@ -1,6 +1,6 @@ /* pdp11_tc.c: PDP-11 DECtape simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ tc TC11/TU56 DECtape + 25-Apr-03 RMS Revised for extended file support + 14-Mar-03 RMS Fixed variable size interaction with save/restore 29-Sep-02 RMS Added variable address support to bootstrap Added vector change/display support Added 16b format support @@ -342,7 +344,7 @@ REG dt_reg[] = { { DRDATA (DCTIME, dt_dctime, 31), REG_NZ }, { ORDATA (SUBSTATE, dt_substate, 1) }, { DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN }, - { URDATA (POS, dt_unit[0].pos, 10, 32, 0, + { URDATA (POS, dt_unit[0].pos, 10, T_ADDR_W, 0, DT_NUMDR, PV_LEFT | REG_RO) }, { URDATA (STATT, dt_unit[0].STATE, 8, 18, 0, DT_NUMDR, REG_RO) }, @@ -715,7 +717,7 @@ int32 dir = mot & DTS_DIR; int32 fnc = DTS_GETFNC (uptr->STATE); int32 *bptr = uptr->filebuf; int32 blk, wrd, relpos, dat; -t_addr ma, mma, ba; +uint32 ba, ma, mma; /* Motion cases @@ -1065,34 +1067,34 @@ t_stat dt_attach (UNIT *uptr, char *cptr) { uint16 pdp8b[D8_NBSIZE]; uint16 pdp11b[D18_BSIZE]; -uint32 k, p, *bptr; +uint32 ba, sz, k, *bptr; +int32 u = uptr - dt_dev.units; t_stat r; -t_addr ba; r = attach_unit (uptr, cptr); /* attach */ if (r != SCPE_OK) return r; /* fail? */ -uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; /* default 16b */ -if (sim_switches & SWMASK ('R')) /* att 12b? */ - uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT; -else if (sim_switches & SWMASK ('T')) /* att 18b? */ - uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); -else if (!(sim_switches & SWMASK ('S')) && /* autosize? */ - (fseek (uptr->fileref, 0, SEEK_END) == 0) && - ((p = ftell (uptr->fileref)) > D16_FILSIZ)) { - if (p <= D8_FILSIZ) +if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */ + uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; /* default 16b */ + if (sim_switches & SWMASK ('R')) /* att 12b? */ uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT; - else uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); } + else if (sim_switches & SWMASK ('T')) /* att 18b? */ + uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); + else if (!(sim_switches & SWMASK ('S')) && /* autosize? */ + ((sz = sim_fsize (cptr)) > D16_FILSIZ)) { + if (sz <= D8_FILSIZ) + uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT; + else uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); } } uptr->capac = DTU_CAPAC (uptr); /* set capacity */ uptr->filebuf = calloc (uptr->capac, sizeof (int32)); if (uptr->filebuf == NULL) { /* can't alloc? */ detach_unit (uptr); return SCPE_MEM; } bptr = uptr->filebuf; /* file buffer */ -if (uptr->flags & UNIT_8FMT) printf ("TC: 12b format"); -else if (uptr->flags & UNIT_11FMT) printf ("TC: 16b format"); -else printf ("TC: 18b/36b format"); +printf ("%s%d: ", sim_dname (&dt_dev), u); +if (uptr->flags & UNIT_8FMT) printf ("12b format"); +else if (uptr->flags & UNIT_11FMT) printf ("16b format"); +else printf ("18b/36b format"); printf (", buffering file in memory\n"); -rewind (uptr->fileref); /* start of file */ if (uptr->flags & UNIT_8FMT) { /* 12b? */ for (ba = 0; ba < uptr->capac; ) { /* loop thru file */ k = fxread (pdp8b, sizeof (int16), D8_NBSIZE, uptr->fileref); @@ -1135,21 +1137,20 @@ t_stat dt_detach (UNIT* uptr) { uint16 pdp8b[D8_NBSIZE]; uint16 pdp11b[D18_BSIZE]; -uint32 k, *bptr; -int32 unum = uptr - dt_dev.units; -t_addr ba; +uint32 ba, k, *bptr; +int32 u = uptr - dt_dev.units; if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; if (sim_is_active (uptr)) { /* active? cancel op */ sim_cancel (uptr); - if ((unum == CSR_GETUNIT (tccm)) && ((tccm & CSR_DONE) == 0)) { + if ((u == CSR_GETUNIT (tccm)) && ((tccm & CSR_DONE) == 0)) { tcst = tcst | STA_SEL; tccm = tccm | CSR_ERR | CSR_DONE; if (tccm & CSR_IE) SET_INT (DTA); } uptr->STATE = uptr->pos = 0; } bptr = uptr->filebuf; /* file buffer */ if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */ - printf ("TC: writing buffer to file\n"); + printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u); rewind (uptr->fileref); /* start of file */ if (uptr->flags & UNIT_8FMT) { /* 12b? */ for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */ diff --git a/PDP11/pdp11_tm.c b/PDP11/pdp11_tm.c index 50389c28..e6872b36 100644 --- a/PDP11/pdp11_tm.c +++ b/PDP11/pdp11_tm.c @@ -25,6 +25,8 @@ tm TM11/TU10 magtape + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support 28-Feb-03 RMS Revised for magtape library, added logging 30-Oct-02 RMS Revised BOT handling, added error record handling 30-Sep-02 RMS Added variable address support to bootstrap @@ -207,7 +209,7 @@ REG tm_reg[] = { { FLDATA (STOP_IOE, tm_stopioe, 0) }, { DRDATA (TIME, tm_time, 24), PV_LEFT }, { URDATA (UST, tm_unit[0].USTAT, 8, 16, 0, TM_NUMDR, 0) }, - { URDATA (POS, tm_unit[0].pos, 10, 32, 0, + { URDATA (POS, tm_unit[0].pos, 10, T_ADDR_W, 0, TM_NUMDR, PV_LEFT | REG_RO) }, { ORDATA (DEVADDR, tm_dib.ba, 32), REG_HRO }, { ORDATA (DEVVEC, tm_dib.vec, 16), REG_HRO }, @@ -216,6 +218,8 @@ REG tm_reg[] = { MTAB tm_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", &tm_vlock }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &tm_vlock }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { MTAB_XTD|MTAB_VDV, 020, "ADDRESS", "ADDRESS", &set_addr, &show_addr, NULL }, { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", @@ -352,7 +356,7 @@ return; t_stat tm_svc (UNIT *uptr) { int32 f, t, u; -t_addr xma; +uint32 xma; t_mtrlnt tbc, cbc; t_stat st, r = SCPE_OK; diff --git a/PDP11/pdp11_tq.c b/PDP11/pdp11_tq.c index ae18ce85..d310372b 100644 --- a/PDP11/pdp11_tq.c +++ b/PDP11/pdp11_tq.c @@ -1,4 +1,4 @@ -/* pdp11_tq.c: TQK50 tape controller simulator +/* pdp11_tq.c: TMSCP tape controller simulator Copyright (c) 2002-2003, Robert M Supnik @@ -25,6 +25,9 @@ tq TQK50 tape controller + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support 28-Feb-03 RMS Added variable controller, user-defined drive support 26-Feb-03 RMS Fixed bug in vector calculation for VAXen 22-Feb-03 RMS Fixed ordering bug in queue process @@ -33,15 +36,18 @@ 17-Oct-02 RMS Fixed bug in read reverse (found by Hans Pufal) */ -#if defined (USE_INT64) -#include "vax_defs.h" -#define VM_VAX 1 -#define TQ_RDX 16 +#if defined (VM_PDP10) /* PDP10 version */ +#error "TQK50 not supported on PDP-10!" -#else +#elif defined (VM_VAX) /* VAX version */ +#include "vax_defs.h" +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; + +#else /* PDP-11 version */ #include "pdp11_defs.h" -#define VM_PDP11 1 -#define TQ_RDX 8 +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; extern int32 cpu_18b, cpu_ubm; #endif @@ -167,6 +173,7 @@ struct tqpkt { #define TQU_FMT (TF_CTP|TF_CTP_LO) /* menu */ #define TQU_MINC 30 /* min cap MB */ #define TQU_MAXC 2000 /* max cap MB */ +#define TQU_EMAXC 2000000000 /* ext max cap MB */ #define TQ_DRV(d) \ d##_UQPM, \ @@ -180,7 +187,7 @@ struct drvtyp { uint32 cmod; /* ctrl model */ uint32 med; /* MSCP media */ uint32 fmt; /* flags */ - uint32 cap; /* capacity */ + t_addr cap; /* capacity */ uint32 umod; /* unit model */ uint32 cver; uint32 fver; @@ -202,6 +209,7 @@ extern int32 tmr_poll, clk_tps; extern int32 cpu_log; extern UNIT cpu_unit; extern FILE *sim_log; +extern uint32 sim_taddr_64; uint8 *tqxb = NULL; /* xfer buffer */ uint32 tq_sa = 0; /* status, addr */ @@ -353,28 +361,28 @@ UNIT tq_unit[] = { #define TQ_QUEUE (TQ_TIMER + 1) REG tq_reg[] = { - { GRDATA (SA, tq_sa, TQ_RDX, 16, 0) }, - { GRDATA (SAW, tq_saw, TQ_RDX, 16, 0) }, - { GRDATA (S1DAT, tq_s1dat, TQ_RDX, 16, 0) }, - { GRDATA (CQBA, tq_cq.ba, TQ_RDX, 22, 0) }, - { GRDATA (CQLNT, tq_cq.lnt, TQ_RDX, 8, 2), REG_NZ }, - { GRDATA (CQIDX, tq_cq.idx, TQ_RDX, 8, 2) }, - { GRDATA (TQBA, tq_rq.ba, TQ_RDX, 22, 0) }, - { GRDATA (TQLNT, tq_rq.lnt, TQ_RDX, 8, 2), REG_NZ }, - { GRDATA (TQIDX, tq_rq.idx, TQ_RDX, 8, 2) }, + { GRDATA (SA, tq_sa, DEV_RDX, 16, 0) }, + { GRDATA (SAW, tq_saw, DEV_RDX, 16, 0) }, + { GRDATA (S1DAT, tq_s1dat, DEV_RDX, 16, 0) }, + { GRDATA (CQBA, tq_cq.ba, DEV_RDX, 22, 0) }, + { GRDATA (CQLNT, tq_cq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (CQIDX, tq_cq.idx, DEV_RDX, 8, 2) }, + { GRDATA (TQBA, tq_rq.ba, DEV_RDX, 22, 0) }, + { GRDATA (TQLNT, tq_rq.lnt, DEV_RDX, 8, 2), REG_NZ }, + { GRDATA (TQIDX, tq_rq.idx, DEV_RDX, 8, 2) }, { DRDATA (FREE, tq_freq, 5) }, { DRDATA (RESP, tq_rspq, 5) }, { DRDATA (PBSY, tq_pbsy, 5) }, - { GRDATA (CFLGS, tq_cflgs, TQ_RDX, 16, 0) }, - { GRDATA (CSTA, tq_csta, TQ_RDX, 4, 0) }, - { GRDATA (PERR, tq_perr, TQ_RDX, 9, 0) }, + { GRDATA (CFLGS, tq_cflgs, DEV_RDX, 16, 0) }, + { GRDATA (CSTA, tq_csta, DEV_RDX, 4, 0) }, + { GRDATA (PERR, tq_perr, DEV_RDX, 9, 0) }, { DRDATA (CRED, tq_credits, 5) }, { DRDATA (HAT, tq_hat, 17) }, { DRDATA (HTMO, tq_htmo, 17) }, { URDATA (CPKT, tq_unit[0].cpkt, 10, 5, 0, TQ_NUMDR, 0) }, { URDATA (PKTQ, tq_unit[0].pktq, 10, 5, 0, TQ_NUMDR, 0) }, - { URDATA (UFLG, tq_unit[0].uf, TQ_RDX, 16, 0, TQ_NUMDR, 0) }, - { URDATA (POS, tq_unit[0].pos, 10, 32, 0, TQ_NUMDR, 0) }, + { URDATA (UFLG, tq_unit[0].uf, DEV_RDX, 16, 0, TQ_NUMDR, 0) }, + { URDATA (POS, tq_unit[0].pos, 10, T_ADDR_W, 0, TQ_NUMDR, 0) }, { URDATA (OBJP, tq_unit[0].objp, 10, 32, 0, TQ_NUMDR, 0) }, { FLDATA (PRGI, tq_prgi, 0), REG_HIDDEN }, { FLDATA (PIP, tq_pip, 0), REG_HIDDEN }, @@ -383,11 +391,11 @@ REG tq_reg[] = { { DRDATA (I4TIME, tq_itime4, 24), PV_LEFT + REG_NZ }, { DRDATA (QTIME, tq_qtime, 24), PV_LEFT + REG_NZ }, { DRDATA (XTIME, tq_xtime, 24), PV_LEFT + REG_NZ }, - { BRDATA (PKTS, tq_pkt, TQ_RDX, 16, TQ_NPKTS * (TQ_PKT_SIZE_W + 1)) }, + { BRDATA (PKTS, tq_pkt, DEV_RDX, 16, TQ_NPKTS * (TQ_PKT_SIZE_W + 1)) }, { DRDATA (DEVTYPE, tq_typ, 2), REG_HRO }, - { DRDATA (DEVCAP, drv_tab[TQU_TYPE].cap, 31), REG_HRO }, - { GRDATA (DEVADDR, tq_dib.ba, TQ_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, tq_dib.vec, TQ_RDX, 16, 0), REG_HRO }, + { DRDATA (DEVCAP, drv_tab[TQU_TYPE].cap, T_ADDR_W), PV_LEFT | REG_HRO }, + { GRDATA (DEVADDR, tq_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, tq_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { NULL } }; MTAB tq_mod[] = { @@ -415,6 +423,8 @@ MTAB tq_mod[] = { NULL, &tq_show_ctrl, NULL }, { MTAB_XTD | MTAB_VUN | MTAB_NMO, 0, "UNITQ", NULL, NULL, &tq_show_unitq, NULL }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, #if defined (VM_PDP11) { MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS", &set_addr, &show_addr, NULL }, @@ -428,7 +438,7 @@ MTAB tq_mod[] = { DEVICE tq_dev = { "TQ", tq_unit, tq_reg, tq_mod, - TQ_NUMDR + 2, 10, 31, 1, TQ_RDX, 8, + TQ_NUMDR + 2, 10, 31, 1, DEV_RDX, 8, NULL, NULL, &tq_reset, &tq_boot, &tq_attach, &tq_detach, &tq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS }; @@ -478,7 +488,7 @@ return SCPE_OK; t_bool tq_step4 (void) { int32 i, lnt; -t_addr base; +uint32 base; uint16 zero[SA_COMM_MAX >> 1]; tq_rq.ioff = SA_COMM_RI; /* set intr offset */ @@ -1246,7 +1256,7 @@ uint32 st, skrec; *skipped = 0; while (*skipped < cnt) { /* loop */ - st = tq_spacef (uptr, INT_MAX, &skrec, TRUE); /* rec spc fwd */ + st = tq_spacef (uptr, 0x7FFFFFFF, &skrec, TRUE);/* rec spc fwd */ if (st == ST_TMK) *skipped = *skipped + 1; /* count files */ else if (st != ST_SUC) return st; } return ST_SUC; @@ -1274,7 +1284,7 @@ uint32 st, skrec; *skipped = 0; while (*skipped < cnt) { /* loopo */ - st = tq_spacer (uptr, INT_MAX, &skrec, TRUE); /* rec spc rev */ + st = tq_spacer (uptr, 0x7FFFFFFF, &skrec, TRUE);/* rec spc rev */ if (st == ST_TMK) *skipped = *skipped + 1; /* tape mark? */ else if (st != 0) return st; } /* error? */ return ST_SUC; @@ -1459,8 +1469,7 @@ return; t_bool tq_getpkt (int32 *pkt) { -uint32 desc; -t_addr addr; +uint32 addr, desc; if (!tq_getdesc (&tq_cq, &desc)) return ERR; /* get cmd desc */ if ((desc & UQ_DESC_OWN) == 0) { /* none */ @@ -1481,8 +1490,7 @@ return tq_putdesc (&tq_cq, desc); /* release desc */ t_bool tq_putpkt (int32 pkt, t_bool qt) { -uint32 desc, lnt, cr; -t_addr addr; +uint32 addr, desc, lnt, cr; if (pkt == 0) return OK; /* any packet? */ if (DBG_LOG (LOG_TQ)) { @@ -1517,7 +1525,7 @@ return tq_putdesc (&tq_rq, desc); /* release desc */ t_bool tq_getdesc (struct uq_ring *ring, uint32 *desc) { -t_addr addr = ring->ba + ring->idx; +uint32 addr = ring->ba + ring->idx; uint16 d[2]; if (Map_ReadW (addr, 4, d, MAP)) /* fetch desc */ @@ -1535,7 +1543,7 @@ return OK; t_bool tq_putdesc (struct uq_ring *ring, uint32 desc) { uint32 prvd, newd = (desc & ~UQ_DESC_OWN) | UQ_DESC_F; -t_addr prva, addr = ring->ba + ring->idx; +uint32 prva, addr = ring->ba + ring->idx; uint16 d[2]; d[0] = newd & 0xFFFF; /* 32b to 16b */ @@ -1638,7 +1646,7 @@ return; void tq_ring_int (struct uq_ring *ring) { -t_addr iadr = tq_comm + ring->ioff; /* addr intr wd */ +uint32 iadr = tq_comm + ring->ioff; /* addr intr wd */ uint16 flag = 1; Map_WriteW (iadr, 2, &flag, MAP); /* write flag */ @@ -1976,7 +1984,8 @@ return SCPE_OK; tq_set_type (UNIT *uptr, int32 val, char *cptr, void *desc) { -int32 i, cap; +uint32 i, cap; +uint32 max = sim_taddr_64? TQU_EMAXC: TQU_MAXC; t_stat r; if ((val < 0) || (val > TQU_TYPE) || ((val != TQU_TYPE) && cptr)) @@ -1984,9 +1993,9 @@ if ((val < 0) || (val > TQU_TYPE) || ((val != TQU_TYPE) && cptr)) for (i = 0; i < TQ_NUMDR; i++) { if (tq_unit[i].flags & UNIT_ATT) return SCPE_ALATT; } if (cptr) { - cap = (int32) get_uint (cptr, 10, TQU_MAXC, &r); + cap = (uint32) get_uint (cptr, 10, max, &r); if ((r != SCPE_OK) || (cap < TQU_MINC)) return SCPE_ARG; - drv_tab[TQU_TYPE].cap = cap << 20; } + drv_tab[TQU_TYPE].cap = ((t_addr) cap) << 20; } tq_typ = val; return SCPE_OK; } diff --git a/PDP11/pdp11_ts.c b/PDP11/pdp11_ts.c index 8dc6919d..caa95439 100644 --- a/PDP11/pdp11_ts.c +++ b/PDP11/pdp11_ts.c @@ -25,6 +25,9 @@ ts TS11/TSV05 magtape + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support 28-Feb-03 RMS Revised to use magtape library 30-Sep-02 RMS Added variable address support to bootstrap Added vector change/display support @@ -72,22 +75,23 @@ - VAX Q22 systems - the TS11 must go through the I/O map */ -#if defined (USE_INT64) /* VAX version */ +#if defined (VM_PDP10) /* PDP10 version */ +#error "TS11 not supported on PDP10!" + +#elif defined (VM_VAX) /* VAX version */ #include "vax_defs.h" -#define VM_VAX 1 -#define TS_RDX 16 #define TS_DIS 0 /* on by default */ #define ADDRTEST 0177700 #define DMASK 0xFFFF -extern int32 ReadB (t_addr pa); -extern void WriteB (t_addr pa, int32 val); -extern int32 ReadW (t_addr pa); -extern void WriteW (t_addr pa, int32 val); +extern int32 ReadB (uint32 pa); +extern void WriteB (uint32 pa, int32 val); +extern int32 ReadW (uint32 pa); +extern void WriteW (uint32 pa, int32 val); +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; -#else /* PDP11 version */ +#else /* PDP-11 version */ #include "pdp11_defs.h" -#define VM_PDP11 1 -#define TS_RDX 8 #define TS_DIS DEV_DIS /* off by default */ #define ADDRTEST (UNIBUS? 0177774: 0177700) extern uint16 *M; @@ -311,39 +315,41 @@ DIB ts_dib = { IOBA_TS, IOLN_TS, &ts_rd, &ts_wr, UNIT ts_unit = { UDATA (&ts_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) }; REG ts_reg[] = { - { GRDATA (TSSR, tssr, TS_RDX, 16, 0) }, - { GRDATA (TSBA, tsba, TS_RDX, 22, 0) }, - { GRDATA (TSDBX, tsdbx, TS_RDX, 8, 0) }, - { GRDATA (CHDR, cmdhdr, TS_RDX, 16, 0) }, - { GRDATA (CADL, cmdadl, TS_RDX, 16, 0) }, - { GRDATA (CADH, cmdadh, TS_RDX, 16, 0) }, - { GRDATA (CLNT, cmdlnt, TS_RDX, 16, 0) }, - { GRDATA (MHDR, msghdr, TS_RDX, 16, 0) }, - { GRDATA (MRFC, msgrfc, TS_RDX, 16, 0) }, - { GRDATA (MXS0, msgxs0, TS_RDX, 16, 0) }, - { GRDATA (MXS1, msgxs1, TS_RDX, 16, 0) }, - { GRDATA (MXS2, msgxs2, TS_RDX, 16, 0) }, - { GRDATA (MXS3, msgxs3, TS_RDX, 16, 0) }, - { GRDATA (MSX4, msgxs4, TS_RDX, 16, 0) }, - { GRDATA (WADL, wchadl, TS_RDX, 16, 0) }, - { GRDATA (WADH, wchadh, TS_RDX, 16, 0) }, - { GRDATA (WLNT, wchlnt, TS_RDX, 16, 0) }, - { GRDATA (WOPT, wchopt, TS_RDX, 16, 0) }, - { GRDATA (WXOPT, wchxopt, TS_RDX, 16, 0) }, + { GRDATA (TSSR, tssr, DEV_RDX, 16, 0) }, + { GRDATA (TSBA, tsba, DEV_RDX, 22, 0) }, + { GRDATA (TSDBX, tsdbx, DEV_RDX, 8, 0) }, + { GRDATA (CHDR, cmdhdr, DEV_RDX, 16, 0) }, + { GRDATA (CADL, cmdadl, DEV_RDX, 16, 0) }, + { GRDATA (CADH, cmdadh, DEV_RDX, 16, 0) }, + { GRDATA (CLNT, cmdlnt, DEV_RDX, 16, 0) }, + { GRDATA (MHDR, msghdr, DEV_RDX, 16, 0) }, + { GRDATA (MRFC, msgrfc, DEV_RDX, 16, 0) }, + { GRDATA (MXS0, msgxs0, DEV_RDX, 16, 0) }, + { GRDATA (MXS1, msgxs1, DEV_RDX, 16, 0) }, + { GRDATA (MXS2, msgxs2, DEV_RDX, 16, 0) }, + { GRDATA (MXS3, msgxs3, DEV_RDX, 16, 0) }, + { GRDATA (MSX4, msgxs4, DEV_RDX, 16, 0) }, + { GRDATA (WADL, wchadl, DEV_RDX, 16, 0) }, + { GRDATA (WADH, wchadh, DEV_RDX, 16, 0) }, + { GRDATA (WLNT, wchlnt, DEV_RDX, 16, 0) }, + { GRDATA (WOPT, wchopt, DEV_RDX, 16, 0) }, + { GRDATA (WXOPT, wchxopt, DEV_RDX, 16, 0) }, { FLDATA (INT, IREQ (TS), INT_V_TS) }, { FLDATA (ATTN, ts_qatn, 0) }, { FLDATA (BOOT, ts_bcmd, 0) }, { FLDATA (OWNC, ts_ownc, 0) }, { FLDATA (OWNM, ts_ownm, 0) }, { DRDATA (TIME, ts_time, 24), PV_LEFT + REG_NZ }, - { DRDATA (POS, ts_unit.pos, 32), PV_LEFT + REG_RO }, - { GRDATA (DEVADDR, ts_dib.ba, TS_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, ts_dib.vec, TS_RDX, 16, 0), REG_HRO }, + { DRDATA (POS, ts_unit.pos, T_ADDR_W), PV_LEFT + REG_RO }, + { GRDATA (DEVADDR, ts_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, ts_dib.vec, DEV_RDX, 16, 0), REG_HRO }, { NULL } }; MTAB ts_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, - { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, + { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS", &set_addr, &show_addr, NULL }, { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", @@ -352,7 +358,7 @@ MTAB ts_mod[] = { DEVICE ts_dev = { "TS", &ts_unit, ts_reg, ts_mod, - 1, 10, 31, 1, TS_RDX, 8, + 1, 10, 31, 1, DEV_RDX, 8, NULL, NULL, &ts_reset, &ts_boot, &ts_attach, &ts_detach, &ts_dib, DEV_DISABLE | TS_DIS | DEV_UBUS | DEV_QBUS }; @@ -378,7 +384,7 @@ return SCPE_OK; t_stat ts_wr (int32 data, int32 PA, int32 access) { int32 i; -t_addr pa; +uint32 pa; switch ((PA >> 1) & 01) { /* decode PA<1> */ case 0: /* TSDB */ @@ -531,7 +537,7 @@ int32 ts_readf (UNIT *uptr, uint32 fc) { t_stat st; t_mtrlnt i, tbc, wbc; -t_addr wa, pa; +uint32 wa, pa; msgrfc = fc; st = sim_tape_rdrecf (uptr, tsxb, &tbc, MT_MAXFR); /* read rec fwd */ @@ -558,7 +564,7 @@ int32 ts_readr (UNIT *uptr, uint32 fc) { t_stat st; t_mtrlnt i, tbc, wbc; -t_addr wa, pa; +uint32 wa, pa; msgrfc = fc; st = sim_tape_rdrecr (uptr, tsxb, &tbc, MT_MAXFR); /* read rec rev */ @@ -584,7 +590,7 @@ return 0; int32 ts_write (UNIT *uptr, int32 fc) { int32 i; -t_addr wa, pa; +uint32 wa, pa; t_stat st; msgrfc = fc; @@ -620,7 +626,7 @@ return XTC (XS0_TMK, TC0); t_stat ts_svc (UNIT *uptr) { int32 i, fnc, mod, st0, st1; -t_addr pa; +uint32 pa; static const int32 fnc_mod[CMD_N_FNC] = { /* max mod+1 0 ill */ 0, 4, 0, 0, 1, 2, 1, 0, /* 00 - 07 */ @@ -854,7 +860,7 @@ return; void ts_endcmd (int32 tc, int32 xs0, int32 msg) { int32 i; -t_addr pa; +uint32 pa; msgxs0 = ts_updxs0 (msgxs0 | xs0); /* update XS0 */ if (wchxopt & WCHX_HDS) msgxs4 = msgxs4 | XS4_HDS; /* update XS4 */ diff --git a/PDP11/pdp11_uqssp.h b/PDP11/pdp11_uqssp.h index 4f31eb1c..257d41bc 100644 --- a/PDP11/pdp11_uqssp.h +++ b/PDP11/pdp11_uqssp.h @@ -1,6 +1,6 @@ /* pdp11_uqssp.h: Unibus/Qbus storage systems port definitions file - Copyright (c) 2001-2002, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Derived from work by Stephen F. Shirron Permission is hereby granted, free of charge, to any person obtaining a @@ -134,8 +134,8 @@ /* Command/response rings */ struct uq_ring { - int32 ioff; /* intr offset */ - t_addr ba; /* base addr */ + int32 ioff; /* intr offset */ + uint32 ba; /* base addr */ uint32 lnt; /* size in bytes */ uint32 idx; /* current index */ }; diff --git a/PDP11/pdp11_xq.c b/PDP11/pdp11_xq.c index a551b6a0..8b3e96a9 100644 --- a/PDP11/pdp11_xq.c +++ b/PDP11/pdp11_xq.c @@ -1,7 +1,7 @@ /* pdp11_xq.c: DEQNA/DELQA ethernet controller simulator ------------------------------------------------------------------------------ - Copyright (c) 2002, David T. Hittner + Copyright (c) 2002-2003, David T. Hittner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -33,36 +33,56 @@ http://www.spies.com/~aek/pdf/dec/qbus Certain adaptations have been made because this is an emulation: - The default MAC address is 08-00-2B-AA-BB-CC unless set otherwise. - Ethernet transceiver power flag CSR<12> is ON when attached. - External Loopback does not go out to the physical adapter, it is - implemented more like an extended Internal Loopback - Time Domain Reflectometry (TDR) numbers are faked - The 10-second approx. hardware/software reset delay does not exist - Some physical ethernet receive events like Runts, Overruns, etc. are - never reported back, since the packet-level driver never sees them + Ethernet transceiver power flag CSR<12> is ON when attached. + External Loopback does not go out to the physical adapter, it is + implemented more like an extended Internal Loopback + Time Domain Reflectometry (TDR) numbers are faked + The 10-second approx. hardware/software reset delay does not exist + Some physical ethernet receive events like Runts, Overruns, etc. are + never reported back, since the packet-level driver never sees them Certain advantages are derived from this emulation: - If the real ethernet controller is faster than 10Mbit, the speed is - passed on since there are no minimum response times. + If the real ethernet controller is faster than 10Mbit/sec, the speed is + seen by the simulated cpu since there are no minimum response times. - Known Bugs or Unsupported features: - 1) DEQNA and DEQNA-LOCK modes not implemented fully [done! 07-Jan-03] - 2) Sanity Timer not implemented [done! 16-Oct-02] - 3) MOP functionality not implemented - 4) Multicast support is weak [done! 22-Oct-02] - 5) Promiscuous mode not implemented [done! 22-Oct-02] - 6) Cannot VMScluster node [done! 27-Dec-02] - 7) Cannot bootstrap module on VAX (>>> B XQA0) [done! 12-Oct-02] - 8) PDP11 bootstrap code missing - 9) Automatic ID broadcast every 8-10 minutes [done! 30-Dec-02] - 10) External loopback packet processing [done! 02-Jan-03] - 11) NXM detection/protection [done! 21-Oct-02] + Known Bugs or Unsupported features, in priority order: + 1) PDP11 (modified) bootrom loader [done! 10-Apr-03] + 2) Second controller [done! 05-May-03] + 3) Cannot split inbound packet into multiple buffers [done! 05-Jun-03] + 4) PDP11 bootstrap + 5) MOP functionality not implemented + 6) Local packet processing not implemented + + Regression Tests used by the Author: + VAX: + 1. Console SHOW DEVICE + 2. VMS v7.2 boots/initializes/shows device + 3. VMS DECNET - SET HOST and COPY tests + 4. VMS MultiNet - SET HOST/TELNET and FTP tests + 5. VMS LAT - SET HOST/LAT tests + 6. VMS Cluster - SHOW CLUSTER, SHOW DEVICE, and cluster disk COPY tests + 7. Console boot into VMSCluster (>>>B XQAO) + PDP11: + 1. RT-11 v5.3 - FTPSB copy test ------------------------------------------------------------------------------ Modification history: + 05-Jun-03 DTH Added receive packet splitting + 03-Jun-03 DTH Added SHOW XQ FILTERS + 02-Jun-03 DTH Added SET/SHOW XQ STATS (packet statistics), runt & giant processing + 28-May-03 DTH Modified message queue for dynamic size to shrink executable + 28-May-03 MP Fixed bug in xq_setmac + 06-May-03 DTH Changed 32-bit t_addr to uint32 for v3.0 + Removed SET ADDRESS functionality + 05-May-03 DTH Added second controller + 26-Mar-03 DTH Added PDP11 bootrom loader + Adjusted xq_ex and xq_dev to allow pdp11 to look at bootrom + Patched bootrom to allow "pass" of diagnostics on RSTS/E + 06-Mar-03 DTH Corrected interrupts on IE state transition (code by Tom Evans) + Added interrupt clear on soft reset (first noted by Bob Supnik) + Removed interrupt when setting XL or RL (multiple people) 16-Jan-03 DTH Merged Mark Pizzolato's enhancements with main source Corrected PDP11 XQ_DEBUG compilation 15-Jan-03 MP Fixed the number of units in the xq device structure. @@ -133,8 +153,8 @@ 12-Oct-02 DTH Fixed VAX network bootstrap; setup packets must return TDR > 0 11-Oct-02 DTH Added SET/SHOW XQ TYPE and SET/SHOW XQ SANITY commands 10-Oct-02 DTH Beta 3 released; Integrated with 2.10-0b1 - Fixed off-by-1 bug on xq.setup.macs[7..13] - Added make_checksum + Fixed off-by-1 bug on xq->setup.macs[7..13] + Added xq_make_checksum Added rejection of multicast addresses in SET XQ MAC 08-Oct-02 DTH Beta 2 released; Integrated with 2.10-0p4 Added variable vector (fixes PDP11) and copyrights @@ -165,17 +185,13 @@ #include #include "pdp11_xq.h" +#include "pdp11_xq_bootrom.h" + +#define XQ_MAX_CONTROLLERS 2 /* maximum controllers allowed */ extern int32 int_req[IPL_HLVL]; extern int32 tmr_poll, clk_tps; - -struct xq_device xq = { - 2500, /* rtime */ - {0x08, 0x00, 0x2B, 0xAA, 0xBB, 0xCC}, /* mac */ - XQ_T_DELQA, /* type */ - {0} /* sanity */ - }; - +extern FILE *sim_log; /* forward declarations */ t_stat xq_rd(int32* data, int32 PA, int32 access); @@ -188,94 +204,152 @@ t_stat xq_attach (UNIT * uptr, char * cptr); t_stat xq_detach (UNIT * uptr); t_stat xq_showmac (FILE* st, UNIT* uptr, int32 val, void* desc); t_stat xq_setmac (UNIT* uptr, int32 val, char* cptr, void* desc); +t_stat xq_show_filters (FILE* st, UNIT* uptr, int32 val, void* desc); +t_stat xq_show_stats (FILE* st, UNIT* uptr, int32 val, void* desc); +t_stat xq_set_stats (UNIT* uptr, int32 val, char* cptr, void* desc); t_stat xq_show_type (FILE* st, UNIT* uptr, int32 val, void* desc); t_stat xq_set_type (UNIT* uptr, int32 val, char* cptr, void* desc); t_stat xq_show_sanity (FILE* st, UNIT* uptr, int32 val, void* desc); t_stat xq_set_sanity (UNIT* uptr, int32 val, char* cptr, void* desc); -t_stat xq_show_bootrom (FILE* st, UNIT* uptr, int32 val, void* desc); -t_stat xq_set_bootrom (UNIT* uptr, int32 val, char* cptr, void* desc); t_stat xq_showeth (FILE* st, UNIT* uptr, int32 val, void* desc); -t_stat xq_process_xbdl(void); -t_stat xq_dispatch_xbdl(void); +t_stat xq_process_xbdl(CTLR* xq); +t_stat xq_dispatch_xbdl(CTLR* xq); void xq_start_receiver(void); -void xq_sw_reset(void); +void xq_sw_reset(CTLR* xq); int32 xq_inta (void); +int32 xq_intb (void); t_stat xq_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); t_stat xq_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); -void xq_start_santmr(void); -void xq_cancel_santmr(void); -void xq_reset_santmr(void); +void xq_start_santmr(CTLR* xq); +void xq_cancel_santmr(CTLR* xq); +void xq_reset_santmr(CTLR* xq); t_stat xq_boot_host(void); -void xq_start_idtmr(void); -t_stat xq_system_id(const ETH_MAC dst, uint16 receipt_id); +void xq_start_idtmr(CTLR* xq); +t_stat xq_system_id(CTLR* xq, const ETH_MAC dst, uint16 receipt_id); +void xqa_read_callback(int status); +void xqb_read_callback(int status); +void xqa_write_callback(int status); +void xqb_write_callback(int status); + +struct xq_device xqa = { + xqa_read_callback, /* read callback routine */ + xqa_write_callback, /* write callback routine */ + {0x08, 0x00, 0x2B, 0xAA, 0xBB, 0xCC}, /* mac */ + XQ_T_DELQA, /* type */ + {0} /* sanity */ + }; + +struct xq_device xqb = { + xqb_read_callback, /* read callback routine */ + xqb_write_callback, /* write callback routine */ + {0x08, 0x00, 0x2B, 0xBB, 0xCC, 0xDD}, /* mac */ + XQ_T_DELQA, /* type */ + {0} /* sanity */ + }; /* SIMH device structures */ -DIB xq_dib = { IOBA_XQ, IOLN_XQ, &xq_rd, &xq_wr, +DIB xqa_dib = { IOBA_XQ, IOLN_XQ, &xq_rd, &xq_wr, 1, IVCL (XQ), 0, { &xq_inta } }; -UNIT xq_unit[] = { - { UDATA (&xq_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) }, /* receive timer */ +UNIT xqa_unit[] = { + { UDATA (&xq_svc, UNIT_ATTABLE + UNIT_DISABLE, 2047) }, /* receive timer */ { UDATA (&xq_sansvc, UNIT_DIS, 0) }, /* sanity timer */ { UDATA (&xq_idsvc, UNIT_DIS, 0) } /* system id timer */ }; -REG xq_reg[] = { - { GRDATA ( SA0, xq.addr[0], XQ_RDX, 16, 0), REG_RO}, - { GRDATA ( SA1, xq.addr[1], XQ_RDX, 16, 0), REG_RO}, - { GRDATA ( SA2, xq.addr[2], XQ_RDX, 16, 0), REG_RO}, - { GRDATA ( SA3, xq.addr[3], XQ_RDX, 16, 0), REG_RO}, - { GRDATA ( SA4, xq.addr[4], XQ_RDX, 16, 0), REG_RO}, - { GRDATA ( SA5, xq.addr[5], XQ_RDX, 16, 0), REG_RO}, - { GRDATA ( RBDL, xq.rbdl, XQ_RDX, 32, 0) }, - { GRDATA ( XBDL, xq.xbdl, XQ_RDX, 32, 0) }, - { GRDATA ( VAR, xq.var, XQ_RDX, 16, 0) }, - { GRDATA ( CSR, xq.csr, XQ_RDX, 16, 0) }, - { GRDATA ( SETUP_PRM, xq.setup.promiscuous, XQ_RDX, 32, 0), REG_HRO}, - { GRDATA ( SETUP_MLT, xq.setup.multicast, XQ_RDX, 32, 0), REG_HRO}, - { GRDATA ( SETUP_L1, xq.setup.l1, XQ_RDX, 32, 0), REG_HRO}, - { GRDATA ( SETUP_L2, xq.setup.l2, XQ_RDX, 32, 0), REG_HRO}, - { GRDATA ( SETUP_L3, xq.setup.l3, XQ_RDX, 32, 0), REG_HRO}, - { GRDATA ( SETUP_SAN, xq.setup.sanity_timer, XQ_RDX, 32, 0), REG_HRO}, - { BRDATA ( SETUP_MACS, &xq.setup.macs, XQ_RDX, 8, sizeof(xq.setup.macs)), REG_HRO}, +REG xqa_reg[] = { + { GRDATA ( SA0, xqa.addr[0], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA1, xqa.addr[1], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA2, xqa.addr[2], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA3, xqa.addr[3], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA4, xqa.addr[4], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA5, xqa.addr[5], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( RBDL, xqa.rbdl, XQ_RDX, 32, 0) }, + { GRDATA ( XBDL, xqa.xbdl, XQ_RDX, 32, 0) }, + { GRDATA ( VAR, xqa.var, XQ_RDX, 16, 0) }, + { GRDATA ( CSR, xqa.csr, XQ_RDX, 16, 0) }, + { GRDATA ( SETUP_PRM, xqa.setup.promiscuous, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_MLT, xqa.setup.multicast, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_L1, xqa.setup.l1, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_L2, xqa.setup.l2, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_L3, xqa.setup.l3, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_SAN, xqa.setup.sanity_timer, XQ_RDX, 32, 0), REG_HRO}, + { BRDATA ( SETUP_MACS, &xqa.setup.macs, XQ_RDX, 8, sizeof(xqa.setup.macs)), REG_HRO}, + { NULL }, +}; + +DIB xqb_dib = { IOBA_XQB, IOLN_XQB, &xq_rd, &xq_wr, + 1, IVCL (XQ), 0, { &xq_intb } }; + +UNIT xqb_unit[] = { + { UDATA (&xq_svc, UNIT_ATTABLE + UNIT_DISABLE, 2047) }, /* receive timer */ + { UDATA (&xq_sansvc, UNIT_DIS, 0) }, /* sanity timer */ + { UDATA (&xq_idsvc, UNIT_DIS, 0) } /* system id timer */ +}; + +REG xqb_reg[] = { + { GRDATA ( SA0, xqb.addr[0], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA1, xqb.addr[1], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA2, xqb.addr[2], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA3, xqb.addr[3], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA4, xqb.addr[4], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( SA5, xqb.addr[5], XQ_RDX, 16, 0), REG_RO}, + { GRDATA ( RBDL, xqb.rbdl, XQ_RDX, 32, 0) }, + { GRDATA ( XBDL, xqb.xbdl, XQ_RDX, 32, 0) }, + { GRDATA ( VAR, xqb.var, XQ_RDX, 16, 0) }, + { GRDATA ( CSR, xqb.csr, XQ_RDX, 16, 0) }, + { GRDATA ( SETUP_PRM, xqb.setup.promiscuous, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_MLT, xqb.setup.multicast, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_L1, xqb.setup.l1, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_L2, xqb.setup.l2, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_L3, xqb.setup.l3, XQ_RDX, 32, 0), REG_HRO}, + { GRDATA ( SETUP_SAN, xqb.setup.sanity_timer, XQ_RDX, 32, 0), REG_HRO}, + { BRDATA ( SETUP_MACS, &xqb.setup.macs, XQ_RDX, 8, sizeof(xqb.setup.macs)), REG_HRO}, { NULL }, }; MTAB xq_mod[] = { -#if defined (VM_PDP11) - { MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS", - &set_addr, &show_addr, NULL }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO | MTAB_NC, 0, "BOOTROM", "BOOTROM", - &xq_set_bootrom, &xq_show_bootrom, NULL }, -#else { MTAB_XTD|MTAB_VDV, 004, "ADDRESS", NULL, NULL, &show_addr, NULL }, -#endif { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec, NULL }, { MTAB_XTD | MTAB_VDV, 0, "MAC", "MAC", - &xq_setmac, &xq_showmac, &xq.mac }, + &xq_setmac, &xq_showmac, NULL }, { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "ETH", NULL, NULL, &xq_showeth, NULL }, + { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "FILTERS", NULL, + NULL, &xq_show_filters, NULL }, + { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATS", "STATS", + &xq_set_stats, &xq_show_stats, NULL }, { MTAB_XTD | MTAB_VDV, 0, "TYPE", "TYPE", &xq_set_type, &xq_show_type, NULL }, - { MTAB_XTD | MTAB_VDV|MTAB_NMO, 0, "SANITY", "SANITY", + { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "SANITY", "SANITY", &xq_set_sanity, &xq_show_sanity, NULL }, { 0 }, }; DEVICE xq_dev = { - "XQ", xq_unit, xq_reg, xq_mod, - 3, XQ_RDX, 0, 1, XQ_RDX, 8, + "XQ", xqa_unit, xqa_reg, xq_mod, + 3, XQ_RDX, 11, 1, XQ_RDX, 16, &xq_ex, &xq_dep, &xq_reset, NULL, &xq_attach, &xq_detach, - &xq_dib, DEV_DISABLE | DEV_QBUS + &xqa_dib, DEV_DISABLE | DEV_QBUS +}; + +DEVICE xqb_dev = { + "XQB", xqb_unit, xqb_reg, xq_mod, + 3, XQ_RDX, 11, 1, XQ_RDX, 16, + &xq_ex, &xq_dep, &xq_reset, + NULL, &xq_attach, &xq_detach, + &xqb_dib, DEV_DISABLE | DEV_DIS | DEV_QBUS +}; + +CTLR xq_ctrl[] = { + {&xq_dev, xqa_unit, &xqa_dib, &xqa}, /* XQA controller */ + {&xqb_dev, xqb_unit, &xqb_dib, &xqb} /* XQB controller */ }; #ifdef XQ_DEBUG -#if defined(VM_VAX) -extern int32 PSL; /* PSL */ -extern int32 fault_PC; /* fault PC */ -#endif const char* const xq_recv_regnames[] = { "MAC0", "MAC1", "MAC2", "MAC3", "MAC4", "MAC5", "VAR", "CSR" @@ -291,11 +365,11 @@ const char* const xq_csr_bits[] = { }; /* internal debugging routines */ -void xq_debug_setup(void); -void xq_dump_csr(void); -void xq_dump_var(void); -void xq_csr_changes(uint16 data); -void xq_var_changes(uint16 data); +void xq_debug_setup(CTLR* xq); +void xq_dump_csr(CTLR* xq); +void xq_dump_var(CTLR* xq); +void xq_csr_changes(CTLR* xq, uint16 data); +void xq_var_changes(CTLR* xq, uint16 data); /* sanity timer debugging */ #include @@ -309,6 +383,25 @@ struct timeb start, finish; ================================================================================ */ +t_stat xq_init_queue(CTLR* xq, struct xq_msg_que* que) +{ + /* create dynamic queue if it does not exist */ + if (!que->item) { + size_t size = sizeof(struct xq_msg_itm) * XQ_QUE_MAX; + que->item = malloc(size); + if (que->item) { + /* init dynamic memory */ + memset(que->item, 0, size); + } else { + /* failed to allocate memory */ + printf("%s: failed to allocate dynamic queue\n", xq->dev->name); + if (sim_log) fprintf(sim_log, "%s: failed to allocate dynamic queue\n", xq->dev->name); + return SCPE_MEM; + }; + }; + return SCPE_OK; +} + void xq_clear_queue(struct xq_msg_que* que) { int i; @@ -318,8 +411,9 @@ void xq_clear_queue(struct xq_msg_que* que) item = &que->item[i]; item->type = 0; item->packet.len = 0; + item->packet.used = 0; item->status = 0; - } + }; que->count = que->head = que->tail = que->loss = 0; } @@ -330,6 +424,7 @@ void xq_remove_queue(struct xq_msg_que* que) if (que->count) { item->type = 0; item->packet.len = 0; + item->packet.used = 0; item->status = 0; if (++que->head == XQ_QUE_MAX) que->head = 0; @@ -360,11 +455,14 @@ void xq_insert_queue(struct xq_msg_que* que, int32 type, ETH_PACK* packet, int32 fprintf(stderr, "Packet Lost\n"); #endif } + if (que->count > que->high) + que->high = que->count; /* set information in (new) tail item */ item = &que->item[que->tail]; item->type = type; item->packet.len = packet->len; + item->packet.used = 0; memcpy(item->packet.msg, packet->msg, packet->len); item->status = status; } @@ -373,11 +471,54 @@ void xq_insert_queue(struct xq_msg_que* que, int32 type, ETH_PACK* packet, int32 ================================================================================ */ +/*============================================================================*/ + +/* Multicontroller support */ + +CTLR* xq_unit2ctlr(UNIT* uptr) +{ + unsigned int i,j; + for (i=0; inumunits; j++) + if (&xq_ctrl[i].unit[j] == uptr) return &xq_ctrl[i]; + /* not found */ + return 0; +} + +CTLR* xq_dev2ctlr(DEVICE* dptr) +{ + int i; + for (i=0; i= xq_ctrl[i].dib->ba) && (PA < (xq_ctrl[i].dib->ba + xq_ctrl[i].dib->lnt))) + return &xq_ctrl[i]; + /* not found */ + return 0; +} + +/*============================================================================*/ /* stop simh from reading non-existant unit data stream */ t_stat xq_ex (t_value* vptr, t_addr addr, UNIT* uptr, int32 sw) { + /* on PDP-11, allow EX command to look at bootrom */ +#ifdef VM_PDP11 + if (addr <= sizeof(xq_bootrom)/2) + *vptr = xq_bootrom[addr]; + else + *vptr = 0; + return SCPE_OK; +#else return SCPE_NOFNC; +#endif } /* stop simh from writing non-existant unit data stream */ @@ -388,17 +529,15 @@ t_stat xq_dep (t_value val, t_addr addr, UNIT* uptr, int32 sw) t_stat xq_showmac (FILE* st, UNIT* uptr, int32 val, void* desc) { - ETH_MAC* mac = (ETH_MAC*) desc; + CTLR* xq = xq_unit2ctlr(uptr); char buffer[20]; - if (!desc) return SCPE_IERR; - eth_mac_fmt(mac, buffer); - + eth_mac_fmt((ETH_MAC*)xq->var->mac, buffer); fprintf(st, "MAC=%s", buffer); return SCPE_OK; } -void make_checksum(void) +void xq_make_checksum(CTLR* xq) { /* checksum calculation routine detailed in vaxboot.zip/xqbtdrivr.mar */ uint32 checksum = 0; @@ -409,7 +548,7 @@ void make_checksum(void) checksum <<= 1; if (checksum > wmask) checksum -= wmask; - checksum += (xq.mac[i] << 8) | xq.mac[i+1]; + checksum += (xq->var->mac[i] << 8) | xq->var->mac[i+1]; if (checksum > wmask) checksum -= wmask; } @@ -417,8 +556,8 @@ void make_checksum(void) checksum = 0; /* set checksum bytes */ - xq.mac_checksum[0] = checksum & 0xFF; - xq.mac_checksum[1] = checksum >> 8; + xq->var->mac_checksum[0] = checksum & 0xFF; + xq->var->mac_checksum[1] = checksum >> 8; } t_stat xq_setmac (UNIT* uptr, int32 val, char* cptr, void* desc) @@ -428,8 +567,9 @@ t_stat xq_setmac (UNIT* uptr, int32 val, char* cptr, void* desc) ETH_MAC newmac = {0,0,0,0,0,0}; const ETH_MAC zeros = {0,0,0,0,0,0}; const ETH_MAC ones = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + CTLR* xq = xq_unit2ctlr(uptr); - if ((!cptr) || (!desc)) return SCPE_IERR; + if (!cptr) return SCPE_IERR; /* parse new mac and validate */ len = strlen(cptr); if (len != 17) return SCPE_ARG; @@ -452,9 +592,9 @@ t_stat xq_setmac (UNIT* uptr, int32 val, char* cptr, void* desc) ) return SCPE_ARG; /* set mac, it's OK */ - memcpy(xq.mac, newmac, sizeof(ETH_MAC)); + memcpy(xq->var->mac, newmac, sizeof(ETH_MAC)); /* calculate MAC checksum */ - make_checksum(); + xq_make_checksum(xq); return SCPE_OK; } @@ -474,10 +614,62 @@ t_stat xq_showeth (FILE* st, UNIT* uptr, int32 val, void* desc) return SCPE_OK; } +t_stat xq_set_stats (UNIT* uptr, int32 val, char* cptr, void* desc) +{ + /* this sets all ints in the stats structure to the integer passed */ + CTLR* xq = xq_unit2ctlr(uptr); +#ifdef XQ_DEBUG + /* set individual stats to passed parameter value */ + int init = cptr ? atoi(cptr) : 0; + int* stat_array = (int*) &xq->var->stats; + int elements = sizeof(struct xq_stats)/sizeof(int); + int i; + for (i=0; ivar->stats, 0, sizeof(struct xq_stats)); +#endif + return SCPE_OK; +} + +t_stat xq_show_stats (FILE* st, UNIT* uptr, int32 val, void* desc) +{ + char* fmt = " %-15s%d\n"; + CTLR* xq = xq_unit2ctlr(uptr); + + fprintf(st, "Ethernet statistics:\n"); + fprintf(st, fmt, "Recv:", xq->var->stats.recv); + fprintf(st, fmt, "Filtered:", xq->var->stats.filter); + fprintf(st, fmt, "Xmit:", xq->var->stats.xmit); + fprintf(st, fmt, "Xmit Fail:", xq->var->stats.fail); + fprintf(st, fmt, "Runts:", xq->var->stats.runt); + fprintf(st, fmt, "Oversize:", xq->var->stats.giant); + fprintf(st, fmt, "Setup:", xq->var->stats.setup); + fprintf(st, fmt, "Loopback:", xq->var->stats.loop); + fprintf(st, fmt, "ReadQ high:", xq->var->ReadQ.high); + return SCPE_OK; +} + +t_stat xq_show_filters (FILE* st, UNIT* uptr, int32 val, void* desc) +{ + CTLR* xq = xq_unit2ctlr(uptr); + char buffer[20]; + int i; + + fprintf(st, "Filters:\n"); + for (i=0; ivar->setup.macs[i], buffer); + fprintf(st, " [%2d]: %s\n", i, buffer); + }; + return SCPE_OK; +} + t_stat xq_show_type (FILE* st, UNIT* uptr, int32 val, void* desc) { + CTLR* xq = xq_unit2ctlr(uptr); fprintf(st, "type="); - switch (xq.type) { + switch (xq->var->type) { case XQ_T_DEQNA: fprintf(st, "DEQNA"); break; case XQ_T_DELQA: fprintf(st, "DELQA"); break; } @@ -486,11 +678,12 @@ t_stat xq_show_type (FILE* st, UNIT* uptr, int32 val, void* desc) t_stat xq_set_type (UNIT* uptr, int32 val, char* cptr, void* desc) { + CTLR* xq = xq_unit2ctlr(uptr); if (!cptr) return SCPE_IERR; /* this assumes that the parameter has already been upcased */ - if (!strcmp(cptr, "DEQNA")) xq.type = XQ_T_DEQNA; - else if (!strcmp(cptr, "DELQA")) xq.type = XQ_T_DELQA; + if (!strcmp(cptr, "DEQNA")) xq->var->type = XQ_T_DEQNA; + else if (!strcmp(cptr, "DELQA")) xq->var->type = XQ_T_DELQA; else return SCPE_ARG; return SCPE_OK; @@ -498,8 +691,10 @@ t_stat xq_set_type (UNIT* uptr, int32 val, char* cptr, void* desc) t_stat xq_show_sanity (FILE* st, UNIT* uptr, int32 val, void* desc) { + CTLR* xq = xq_unit2ctlr(uptr); + fprintf(st, "sanity="); - switch (xq.sanity.enabled) { + switch (xq->var->sanity.enabled) { case 0: fprintf(st, "OFF"); break; case 1: fprintf(st, "ON"); break; } @@ -508,44 +703,27 @@ t_stat xq_show_sanity (FILE* st, UNIT* uptr, int32 val, void* desc) t_stat xq_set_sanity (UNIT* uptr, int32 val, char* cptr, void* desc) { + CTLR* xq = xq_unit2ctlr(uptr); if (!cptr) return SCPE_IERR; /* this assumes that the parameter has already been upcased */ - if (!strcmp(cptr, "ON")) xq.sanity.enabled = 1; - else if (!strcmp(cptr, "OFF")) xq.sanity.enabled = 0; + if (!strcmp(cptr, "ON")) xq->var->sanity.enabled = 1; + else if (!strcmp(cptr, "OFF")) xq->var->sanity.enabled = 0; else return SCPE_ARG; return SCPE_OK; } -t_stat xq_show_bootrom (FILE* st, UNIT* uptr, int32 val, void* desc) -{ - /* format includes \n for MTAB_NMO compatibility */ - fprintf(st, "bootrom=%s\n", xq.bootrom); - return SCPE_OK; -} - -t_stat xq_set_bootrom (UNIT* uptr, int32 val, char* cptr, void* desc) -{ - size_t len; - if (!cptr) return SCPE_IERR; - len = strlen(cptr) + 1; - if (len > sizeof(xq.bootrom)) return SCPE_ARG; - - memcpy(xq.bootrom, cptr, strlen(cptr)+1); - return SCPE_OK; -} - -t_stat xq_nxm_error(void) +t_stat xq_nxm_error(CTLR* xq) { #ifdef XQ_DEBUG - fprintf(stderr,"XQ: Non Existent Memory Error\n"); + fprintf(stderr,"%s: Non Existent Memory Error\n", xq->dev->name); #endif /* set NXM and associated bits in CSR */ - xq.csr |= (XQ_CSR_NI | XQ_CSR_XI | XQ_CSR_XL | XQ_CSR_RL); + xq->var->csr |= (XQ_CSR_NI | XQ_CSR_XI | XQ_CSR_XL | XQ_CSR_RL); /* interrupt if required */ - if (xq.csr & XQ_CSR_IE) + if (xq->var->csr & XQ_CSR_IE) SET_INT(XQ); return SCPE_OK; @@ -554,59 +732,74 @@ t_stat xq_nxm_error(void) /* ** write callback */ -void xq_write_callback (int status) +void xq_write_callback (CTLR* xq, int status) { t_stat rstatus; int32 wstatus; - const uint16 TDR = 100 + xq.write_buffer.len * 8; /* arbitrary value */ + const uint16 TDR = 100 + xq->var->write_buffer.len * 8; /* arbitrary value */ uint16 write_success[2] = {0}; uint16 write_failure[2] = {XQ_DSC_C}; write_success[1] = TDR & 0x03FF; /* Does TDR get set on successful packets ?? */ write_failure[1] = TDR & 0x03FF; /* TSW2<09:00> */ + xq->var->stats.xmit += 1; /* update write status words */ if (status == 0) { /* success */ - wstatus = Map_WriteW(xq.xbdl_ba + 8, 4, write_success, NOMAP); + wstatus = Map_WriteW(xq->var->xbdl_ba + 8, 4, write_success, NOMAP); } else { /* failure */ #ifdef XQ_DEBUG - fprintf(stderr, "XQ: Packet Write Error\n"); + fprintf(stderr, "%s: Packet Write Error\n", xq->dev->name); #endif - wstatus = Map_WriteW(xq.xbdl_ba + 8, 4, write_failure, NOMAP); + xq->var->stats.fail += 1; + wstatus = Map_WriteW(xq->var->xbdl_ba + 8, 4, write_failure, NOMAP); } if (wstatus) { - xq_nxm_error(); + xq_nxm_error(xq); return; } /* update csr */ - xq.csr |= XQ_CSR_XI; - if (xq.csr & XQ_CSR_IE) + xq->var->csr |= XQ_CSR_XI; + if (xq->var->csr & XQ_CSR_IE) SET_INT(XQ); /* reset sanity timer */ - xq_reset_santmr(); + xq_reset_santmr(xq); /* clear write buffer */ - xq.write_buffer.len = 0; + xq->var->write_buffer.len = 0; /* next descriptor (implicit) */ - xq.xbdl_ba += 12; + xq->var->xbdl_ba += 12; /* finish processing xbdl */ - rstatus = xq_process_xbdl(); + rstatus = xq_process_xbdl(xq); +} + +void xqa_write_callback (int status) +{ + xq_write_callback(&xq_ctrl[0], status); +} + +void xqb_write_callback (int status) +{ + xq_write_callback(&xq_ctrl[1], status); } /* read registers: */ t_stat xq_rd(int32* data, int32 PA, int32 access) { + CTLR* xq = xq_pa2ctlr(PA); int index = (PA >> 1) & 07; /* word index */ #ifdef XQ_DEBUG if (index != 7) #if defined(VM_VAX) - fprintf (stderr,"XQ: %s %08X %08X read: %X\n", xq_recv_regnames[index], fault_PC, PSL, *data); + fprintf (stderr,"%s: %s %08X %08X read: %X\n", + xq->dev->name, xq_recv_regnames[index], fault_PC, PSL, *data); #else - fprintf (stderr,"XQ: %s read: %X\n", xq_recv_regnames[index], *data); + fprintf (stderr,"%s: %s read: %X\n", + xq->dev->name, xq_recv_regnames[index], *data); #endif /* VM_VAX */ #endif @@ -614,30 +807,30 @@ t_stat xq_rd(int32* data, int32 PA, int32 access) case 0: case 1: /* return checksum in external loopback mode */ - if (xq.csr & XQ_CSR_EL) - *data = 0xFF00 | xq.mac_checksum[index]; + if (xq->var->csr & XQ_CSR_EL) + *data = 0xFF00 | xq->var->mac_checksum[index]; else - *data = 0xFF00 | xq.mac[index]; + *data = 0xFF00 | xq->var->mac[index]; break; case 2: case 3: case 4: case 5: - *data = 0xFF00 | xq.mac[index]; + *data = 0xFF00 | xq->var->mac[index]; break; case 6: #if 0 #ifdef XQ_DEBUG - xq_dump_var(); + xq_dump_var(xq); #endif #endif - *data = xq.var; + *data = xq->var->var; break; case 7: #ifdef XQ_DEBUG - xq_dump_csr(); + xq_dump_csr(xq); #endif - *data = xq.csr; + *data = xq->var->csr; break; } return SCPE_OK; @@ -647,126 +840,164 @@ t_stat xq_rd(int32* data, int32 PA, int32 access) /* dispatch ethernet read request procedure documented in sec. 3.2.2 */ -t_stat xq_process_rbdl(void) +t_stat xq_process_rbdl(CTLR* xq) { int32 rstatus, wstatus; uint16 b_length, w_length, rbl; - t_addr address; + uint32 address; struct xq_msg_itm* item; + char* rbuf; #ifdef XQ_DEBUG - fprintf(stderr,"XQ: CSR - Processing read\n"); + fprintf(stderr,"%s: CSR - Processing read\n", xq->dev->name); #endif /* process buffer descriptors */ while(1) { /* get receive bdl from memory */ - xq.rbdl_buf[0] = 0xFFFF; - wstatus = Map_WriteW(xq.rbdl_ba, 2, &xq.rbdl_buf[0], NOMAP); - rstatus = Map_ReadW (xq.rbdl_ba + 2, 6, &xq.rbdl_buf[1], NOMAP); - if (rstatus || wstatus) return xq_nxm_error(); + xq->var->rbdl_buf[0] = 0xFFFF; + wstatus = Map_WriteW(xq->var->rbdl_ba, 2, &xq->var->rbdl_buf[0], NOMAP); + rstatus = Map_ReadW (xq->var->rbdl_ba + 2, 6, &xq->var->rbdl_buf[1], NOMAP); + if (rstatus || wstatus) return xq_nxm_error(xq); /* invalid buffer? */ - if (~xq.rbdl_buf[1] & XQ_DSC_V) { - xq.csr |= XQ_CSR_RL; - if (xq.csr & XQ_CSR_IE) - SET_INT(XQ); + if (~xq->var->rbdl_buf[1] & XQ_DSC_V) { + xq->var->csr |= XQ_CSR_RL; return SCPE_OK; } /* explicit chain buffer? */ - if (xq.rbdl_buf[1] & XQ_DSC_C) { - xq.rbdl_ba = ((xq.rbdl_buf[1] & 0x3F) << 16) | xq.rbdl_buf[2]; + if (xq->var->rbdl_buf[1] & XQ_DSC_C) { + xq->var->rbdl_ba = ((xq->var->rbdl_buf[1] & 0x3F) << 16) | xq->var->rbdl_buf[2]; continue; } /* stop processing if nothing in read queue */ - if (!xq.ReadQ.count) break; + if (!xq->var->ReadQ.count) break; /* get status words */ - rstatus = Map_ReadW(xq.rbdl_ba + 8, 4, &xq.rbdl_buf[4], NOMAP); - if (rstatus) return xq_nxm_error(); + rstatus = Map_ReadW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4], NOMAP); + if (rstatus) return xq_nxm_error(xq); /* get host memory address */ - address = ((xq.rbdl_buf[1] & 0x3F) << 16) | xq.rbdl_buf[2]; + address = ((xq->var->rbdl_buf[1] & 0x3F) << 16) | xq->var->rbdl_buf[2]; /* decode buffer length - two's complement (in words) */ - w_length = ~xq.rbdl_buf[3] + 1; + w_length = ~xq->var->rbdl_buf[3] + 1; b_length = w_length * 2; - if (xq.rbdl_buf[1] & XQ_DSC_H) b_length -= 1; - if (xq.rbdl_buf[1] & XQ_DSC_L) b_length -= 1; + if (xq->var->rbdl_buf[1] & XQ_DSC_H) b_length -= 1; + if (xq->var->rbdl_buf[1] & XQ_DSC_L) b_length -= 1; - item = &xq.ReadQ.item[xq.ReadQ.head]; + item = &xq->var->ReadQ.item[xq->var->ReadQ.head]; rbl = item->packet.len; + rbuf = item->packet.msg; - /* make sure entire packet fits in buffer */ - assert(rbl <= b_length); + /* see if packet must be size-adjusted or is splitting */ + if (item->packet.used) { + int used = item->packet.used; + rbl -= used; + rbuf = &item->packet.msg[used]; + } else { + /* adjust runt packets */ + if (rbl < ETH_MIN_PACKET) { + xq->var->stats.runt += 1; +#ifdef XQ_DEBUG + printf("%s: Runt detected, size = %d\n", xq->dev->name, rbl); +#endif + /* pad runts with zeros up to minimum size - this allows "legal" (size - 60) + processing of those weird short ARP packets that seem to occur occasionally */ + memset(&item->packet.msg[rbl], 0, ETH_MIN_PACKET); + rbl = ETH_MIN_PACKET; + }; + /* adjust oversized packets */ + if (rbl > ETH_MAX_PACKET) { + xq->var->stats.giant += 1; +#ifdef XQ_DEBUG + printf("%s: Giant detected, size = %d\n", xq->dev->name, rbl); +#endif + /* trim giants down to maximum size - no documentation on how to handle the data loss */ + item->packet.len = ETH_MAX_PACKET; + rbl = ETH_MAX_PACKET; + }; + }; + + /* make sure entire packet fits in buffer - if not, will need to split into multiple buffers */ + /* assert(rbl <= b_length); */ /* abort if packet won't fit into single buffer */ + if (rbl > b_length) + rbl = b_length; + item->packet.used += rbl; + /* send data to host */ - wstatus = Map_WriteB(address, item->packet.len, item->packet.msg, NOMAP); - if (wstatus) return xq_nxm_error(); + wstatus = Map_WriteB(address, rbl, rbuf, NOMAP); + if (wstatus) return xq_nxm_error(xq); /* set receive size into RBL - RBL<10:8> maps into Status1<10:8>, RBL<7:0> maps into Status2<7:0>, and Status2<15:8> (copy) */ - xq.rbdl_buf[4] = 0; + xq->var->rbdl_buf[4] = 0; switch (item->type) { case 0: /* setup packet */ - xq.rbdl_buf[4] = 0x2700; /* set esetup and RBL 10:8 */ + xq->var->stats.setup += 1; + xq->var->rbdl_buf[4] = 0x2700; /* set esetup and RBL 10:8 */ break; case 1: /* loopback packet */ - xq.rbdl_buf[4] = 0x2000; /* loopback flag */ - xq.rbdl_buf[4] |= (rbl & 0x0700); /* high bits of rbl */ + xq->var->stats.loop += 1; + xq->var->rbdl_buf[4] = 0x2000; /* loopback flag */ + xq->var->rbdl_buf[4] |= (rbl & 0x0700); /* high bits of rbl */ break; case 2: /* normal packet */ rbl -= 60; /* keeps max packet size in 11 bits */ - xq.rbdl_buf[4] = (rbl & 0x0700); /* high bits of rbl */ + xq->var->rbdl_buf[4] = (rbl & 0x0700); /* high bits of rbl */ break; } - xq.rbdl_buf[5] = ((rbl & 0x00FF) << 8) | (rbl & 0x00FF); - if (xq.ReadQ.loss) { + if (item->packet.used < item->packet.len) + xq->var->rbdl_buf[4] |= 0xC000; /* not last segment */ + xq->var->rbdl_buf[5] = ((rbl & 0x00FF) << 8) | (rbl & 0x00FF); + if (xq->var->ReadQ.loss) { #ifdef XQ_DEBUG - fprintf(stderr, "XQ: ReadQ overflow\n"); + fprintf(stderr, "%s: ReadQ overflow\n", xq->dev->name); #endif - xq.rbdl_buf[4] |= 0x0001; /* set overflow bit */ - xq.ReadQ.loss = 0; /* reset loss counter */ + xq->var->rbdl_buf[4] |= 0x0001; /* set overflow bit */ + xq->var->ReadQ.loss = 0; /* reset loss counter */ } /* update read status words*/ - wstatus = Map_WriteW(xq.rbdl_ba + 8, 4, &xq.rbdl_buf[4], NOMAP); - if (wstatus) return xq_nxm_error(); + wstatus = Map_WriteW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4], NOMAP); + if (wstatus) return xq_nxm_error(xq); /* remove packet from queue */ - xq_remove_queue(&xq.ReadQ); + if (item->packet.used >= item->packet.len) + xq_remove_queue(&xq->var->ReadQ); /* reset sanity timer */ - xq_reset_santmr(); + xq_reset_santmr(xq); /* mark transmission complete */ - xq.csr |= XQ_CSR_RI; - if (xq.csr & XQ_CSR_IE) + xq->var->csr |= XQ_CSR_RI; + if (xq->var->csr & XQ_CSR_IE) SET_INT(XQ); /* set to next bdl (implicit chain) */ - xq.rbdl_ba += 12; + xq->var->rbdl_ba += 12; } /* while */ return SCPE_OK; } -t_stat xq_process_mop(void) +t_stat xq_process_mop(CTLR* xq) { - t_addr address; + uint32 address; uint16 size; int32 wstatus; - struct xq_meb* meb = (struct xq_meb*) &xq.write_buffer.msg[0200]; - const struct xq_meb* limit = (struct xq_meb*) &xq.write_buffer.msg[0400]; + struct xq_meb* meb = (struct xq_meb*) &xq->var->write_buffer.msg[0200]; + const struct xq_meb* limit = (struct xq_meb*) &xq->var->write_buffer.msg[0400]; #ifdef XQ_DEBUG - fprintf(stderr, "XQ: Processing MOP data\n"); + fprintf(stderr, "%s: Processing MOP data\n", xq->dev->name); #endif - if (xq.type == XQ_T_DEQNA) /* DEQNA's don't MOP */ + if (xq->var->type == XQ_T_DEQNA) /* DEQNA's don't MOP */ return SCPE_NOFNC; while ((meb->type != 0) && (meb < limit)) { @@ -776,14 +1007,14 @@ t_stat xq_process_mop(void) /* MOP stuff here - NOT YET FULLY IMPLEMENTED */ #ifdef XQ_DEBUG - printf("XQ: Processing MEB type: %d\n", meb->type); + printf("%s: Processing MEB type: %d\n", xq->dev->name, meb->type); #endif switch (meb->type) { case 0: /* MOP Termination */ break; case 1: /* MOP Read Ethernet Address */ - wstatus = Map_WriteB(address, sizeof(ETH_MAC), (uint8*) &xq.setup.macs[0], NOMAP); - if (wstatus) return xq_nxm_error(); + wstatus = Map_WriteB(address, sizeof(ETH_MAC), (uint8*) &xq->var->setup.macs[0], NOMAP); + if (wstatus) return xq_nxm_error(xq); break; case 2: /* MOP Reset System ID */ break; @@ -810,7 +1041,7 @@ t_stat xq_process_mop(void) return SCPE_OK; } -t_stat xq_process_setup(void) +t_stat xq_process_setup(CTLR* xq) { int i,j; int count = 0; @@ -820,28 +1051,28 @@ t_stat xq_process_setup(void) ETH_MAC filters[XQ_FILTER_MAX + 1]; /* extract filter addresses from setup packet */ - memset(xq.setup.macs, '\0', sizeof(xq.setup.macs)); + memset(xq->var->setup.macs, '\0', sizeof(xq->var->setup.macs)); for (i = 0; i < 7; i++) for (j = 0; j < 6; j++) { - xq.setup.macs[i] [j] = xq.write_buffer.msg[(i + 01) + (j * 8)]; - if (xq.write_buffer.len > 112) - xq.setup.macs[i+7][j] = xq.write_buffer.msg[(i + 0101) + (j * 8)]; + xq->var->setup.macs[i] [j] = xq->var->write_buffer.msg[(i + 01) + (j * 8)]; + if (xq->var->write_buffer.len > 112) + xq->var->setup.macs[i+7][j] = xq->var->write_buffer.msg[(i + 0101) + (j * 8)]; } /* process high byte count */ - if (xq.write_buffer.len > 128) { - uint16 len = xq.write_buffer.len; + if (xq->var->write_buffer.len > 128) { + uint16 len = xq->var->write_buffer.len; uint16 led, san; if (len & XQ_SETUP_MC) - xq.setup.multicast = 1; + xq->var->setup.multicast = 1; if (len & XQ_SETUP_PM) - xq.setup.promiscuous = 1; + xq->var->setup.promiscuous = 1; if (led = (len & XQ_SETUP_LD) >> 2) { switch (led) { - case 1: xq.setup.l1 = 0; break; - case 2: xq.setup.l2 = 0; break; - case 3: xq.setup.l3 = 0; break; + case 1: xq->var->setup.l1 = 0; break; + case 2: xq->var->setup.l2 = 0; break; + case 3: xq->var->setup.l3 = 0; break; } /* switch */ } /* if led */ /* set sanity timer timeout */ @@ -856,31 +1087,31 @@ t_stat xq_process_setup(void) case 6: secs = 16 * 60; break; /* 16 minutes */ case 7: secs = 64 * 60; break; /* 64 minutes */ } - xq.sanity.quarter_secs = (int) (secs * 4); + xq->var->sanity.quarter_secs = (int) (secs * 4); /* if sanity timer enabled, start sanity timer */ - if (xq.csr & XQ_CSR_SE || xq.sanity.enabled) - xq_start_santmr(); + if (xq->var->csr & XQ_CSR_SE || xq->var->sanity.enabled) + xq_start_santmr(xq); else - xq_cancel_santmr(); + xq_cancel_santmr(xq); } /* set ethernet filter */ - /* memcpy (filters[count++], xq.mac, sizeof(ETH_MAC)); */ + /* memcpy (filters[count++], xq->mac, sizeof(ETH_MAC)); */ for (i = 0; i < XQ_FILTER_MAX; i++) - if (memcmp(zeros, &xq.setup.macs[i], sizeof(ETH_MAC))) - memcpy (filters[count++], xq.setup.macs[i], sizeof(ETH_MAC)); - status = eth_filter (xq.etherface, count, filters, xq.setup.multicast, xq.setup.promiscuous); + if (memcmp(zeros, &xq->var->setup.macs[i], sizeof(ETH_MAC))) + memcpy (filters[count++], xq->var->setup.macs[i], sizeof(ETH_MAC)); + status = eth_filter (xq->var->etherface, count, filters, xq->var->setup.multicast, xq->var->setup.promiscuous); /* process MOP information */ - if (xq.write_buffer.msg[0]) - status = xq_process_mop(); + if (xq->var->write_buffer.msg[0]) + status = xq_process_mop(xq); /* mark setup block valid */ - xq.setup.valid = 1; + xq->var->setup.valid = 1; #ifdef XQ_DEBUG - xq_debug_setup(); + xq_debug_setup(xq); #endif return SCPE_OK; } @@ -892,113 +1123,112 @@ t_stat xq_process_setup(void) can be written in one transmit operation, so a maximum of 1 packet is assumed. */ -t_stat xq_process_xbdl() +t_stat xq_process_xbdl(CTLR* xq) { const uint16 implicit_chain_status[2] = {XQ_DSC_V | XQ_DSC_C, 1}; const uint16 write_success[2] = {0, 1 /*Non-Zero TDR*/}; uint16 b_length, w_length; int32 rstatus, wstatus; - t_addr address; + uint32 address; t_stat status; #ifdef XQ_DEBUG - fprintf(stderr,"XQ: xq_process_xbdl - Processing write\n"); + fprintf(stderr,"%s: xq_process_xbdl - Processing write\n", xq->dev->name); #endif /* clear write buffer */ - xq.write_buffer.len = 0; + xq->var->write_buffer.len = 0; /* process buffer descriptors until not valid */ while (1) { /* Get transmit bdl from memory */ - rstatus = Map_ReadW (xq.xbdl_ba, 12, &xq.xbdl_buf[0], NOMAP); - xq.xbdl_buf[0] = 0xFFFF; - wstatus = Map_WriteW(xq.xbdl_ba, 2, &xq.xbdl_buf[0], NOMAP); - if (rstatus || wstatus) return xq_nxm_error(); + rstatus = Map_ReadW (xq->var->xbdl_ba, 12, &xq->var->xbdl_buf[0], NOMAP); + xq->var->xbdl_buf[0] = 0xFFFF; + wstatus = Map_WriteW(xq->var->xbdl_ba, 2, &xq->var->xbdl_buf[0], NOMAP); + if (rstatus || wstatus) return xq_nxm_error(xq); /* invalid buffer? */ - if (~xq.xbdl_buf[1] & XQ_DSC_V) { - xq.csr |= XQ_CSR_XL; - if (xq.csr & XQ_CSR_IE) - SET_INT(XQ); + if (~xq->var->xbdl_buf[1] & XQ_DSC_V) { + xq->var->csr |= XQ_CSR_XL; #ifdef XQ_DEBUG - fprintf(stderr,"XQ: xq_process_xbdl - List Empty - Done Processing write\n"); + fprintf(stderr,"%s: xq_process_xbdl - List Empty - Done Processing write\n", xq->dev->name); #endif return SCPE_OK; } #ifdef XQ_DEBUG - fprintf(stderr,"XQ: xq_process_xbdl: Buffer Descriptor Information: %04X %04X %04X %04X %04X \n", - xq.xbdl_buf[1], xq.xbdl_buf[2], xq.xbdl_buf[3], xq.xbdl_buf[4], xq.xbdl_buf[5]); + fprintf(stderr,"%s: xq_process_xbdl: Buffer Descriptor Information: %04X %04X %04X %04X %04X \n", + xq->dev->name, xq->var->xbdl_buf[1], xq->var->xbdl_buf[2], + xq->var->xbdl_buf[3], xq->var->xbdl_buf[4], xq->var->xbdl_buf[5]); #endif /* compute host memory address */ - address = ((xq.xbdl_buf[1] & 0x3F) << 16) | xq.xbdl_buf[2]; + address = ((xq->var->xbdl_buf[1] & 0x3F) << 16) | xq->var->xbdl_buf[2]; /* decode buffer length - two's complement (in words) */ - w_length = ~xq.xbdl_buf[3] + 1; + w_length = ~xq->var->xbdl_buf[3] + 1; b_length = w_length * 2; - if (xq.xbdl_buf[1] & XQ_DSC_H) b_length -= 1; - if (xq.xbdl_buf[1] & XQ_DSC_L) b_length -= 1; + if (xq->var->xbdl_buf[1] & XQ_DSC_H) b_length -= 1; + if (xq->var->xbdl_buf[1] & XQ_DSC_L) b_length -= 1; /* explicit chain buffer? */ - if (xq.xbdl_buf[1] & XQ_DSC_C) { - xq.xbdl_ba = address; + if (xq->var->xbdl_buf[1] & XQ_DSC_C) { + xq->var->xbdl_ba = address; #ifdef XQ_DEBUG - fprintf(stderr,"XQ: xq_process_xbdl: Chained Buffer Encountered: %d\n", b_length); + fprintf(stderr,"%s: xq_process_xbdl: Chained Buffer Encountered: %d\n", xq->dev->name, b_length); #endif continue; } /* add to transmit buffer, making sure it's not too big */ - if ((xq.write_buffer.len + b_length) > sizeof(xq.write_buffer.msg)) - b_length = sizeof(xq.write_buffer.msg) - xq.write_buffer.len; - rstatus = Map_ReadB(address, b_length, &xq.write_buffer.msg[xq.write_buffer.len], NOMAP); - if (rstatus) return xq_nxm_error(); - xq.write_buffer.len += b_length; + if ((xq->var->write_buffer.len + b_length) > sizeof(xq->var->write_buffer.msg)) + b_length = sizeof(xq->var->write_buffer.msg) - xq->var->write_buffer.len; + rstatus = Map_ReadB(address, b_length, &xq->var->write_buffer.msg[xq->var->write_buffer.len], NOMAP); + if (rstatus) return xq_nxm_error(xq); + xq->var->write_buffer.len += b_length; /* end of message? */ - if (xq.xbdl_buf[1] & XQ_DSC_E) { - if (((~xq.csr & XQ_CSR_RE) && ((~xq.csr & XQ_CSR_IL) || (xq.csr & XQ_CSR_EL))) || /* loopback */ - (xq.xbdl_buf[1] & XQ_DSC_S)) { /* or setup packet (forces loopback regardless of state) */ - if (xq.xbdl_buf[1] & XQ_DSC_S) { /* setup packet */ - status = xq_process_setup(); + if (xq->var->xbdl_buf[1] & XQ_DSC_E) { + if (((~xq->var->csr & XQ_CSR_RE) && ((~xq->var->csr & XQ_CSR_IL) || (xq->var->csr & XQ_CSR_EL))) || /* loopback */ + (xq->var->xbdl_buf[1] & XQ_DSC_S)) { /* or setup packet (forces loopback regardless of state) */ + if (xq->var->xbdl_buf[1] & XQ_DSC_S) { /* setup packet */ + status = xq_process_setup(xq); /* put packet in read buffer */ - xq_insert_queue (&xq.ReadQ, 0, &xq.write_buffer, status); + xq_insert_queue (&xq->var->ReadQ, 0, &xq->var->write_buffer, status); } else { /* loopback */ /* put packet in read buffer */ - xq_insert_queue (&xq.ReadQ, 1, &xq.write_buffer, 0); + xq_insert_queue (&xq->var->ReadQ, 1, &xq->var->write_buffer, 0); } /* update write status */ - wstatus = Map_WriteW(xq.xbdl_ba + 8, 4, (uint16*) write_success, NOMAP); - if (wstatus) return xq_nxm_error(); + wstatus = Map_WriteW(xq->var->xbdl_ba + 8, 4, (uint16*) write_success, NOMAP); + if (wstatus) return xq_nxm_error(xq); /* clear write buffer */ - xq.write_buffer.len = 0; + xq->var->write_buffer.len = 0; /* reset sanity timer */ - xq_reset_santmr(); + xq_reset_santmr(xq); /* mark transmission complete */ - xq.csr |= XQ_CSR_XI; - if (xq.csr & XQ_CSR_IE) + xq->var->csr |= XQ_CSR_XI; + if (xq->var->csr & XQ_CSR_IE) SET_INT(XQ); /* now trigger "read" of setup or loopback packet */ - if (~xq.csr & XQ_CSR_RL) - status = xq_process_rbdl(); + if (~xq->var->csr & XQ_CSR_RL) + status = xq_process_rbdl(xq); } else { /* not loopback */ - status = eth_write(xq.etherface, &xq.write_buffer, &xq_write_callback); + status = eth_write(xq->var->etherface, &xq->var->write_buffer, xq->var->wcallback); if (status != SCPE_OK) /* not implemented or unattached */ - xq_write_callback(1); /* fake failure */ + xq_write_callback(xq, 1); /* fake failure */ else - xq_svc(&xq_unit[0]); /* service any received data */ + xq_svc(&xq->unit[0]); /* service any received data */ #ifdef XQ_DEBUG - fprintf(stderr,"XQ: xq_process_xbdl: Completed Processing write\n"); + fprintf(stderr,"%s: xq_process_xbdl: Completed Processing write\n", xq->dev->name); #endif return SCPE_OK; @@ -1006,86 +1236,85 @@ t_stat xq_process_xbdl() } else { /* not at end-of-message */ #ifdef XQ_DEBUG - fprintf(stderr,"XQ: xq_process_xbdl: Processing Implicit Chained Buffer Segment\n"); + fprintf(stderr,"%s: xq_process_xbdl: Processing Implicit Chained Buffer Segment\n", xq->dev->name); #endif /* update bdl status words */ - wstatus = Map_WriteW(xq.xbdl_ba + 8, 4, (uint16*) implicit_chain_status, NOMAP); - if(wstatus) return xq_nxm_error(); + wstatus = Map_WriteW(xq->var->xbdl_ba + 8, 4, (uint16*) implicit_chain_status, NOMAP); + if(wstatus) return xq_nxm_error(xq); } /* set to next bdl (implicit chain) */ - xq.xbdl_ba += 12; + xq->var->xbdl_ba += 12; } /* while */ } -t_stat xq_dispatch_rbdl(void) +t_stat xq_dispatch_rbdl(CTLR* xq) { int i; int32 rstatus, wstatus; t_stat status; #ifdef XQ_DEBUG - fprintf(stderr,"XQ: CSR - Dispatching read\n"); + fprintf(stderr,"%s: CSR - Dispatching read\n", xq->dev->name); #endif + /* mark receive bdl valid */ - xq.csr &= ~XQ_CSR_RL; + xq->var->csr &= ~XQ_CSR_RL; /* init receive bdl buffer */ for (i=0; i<6; i++) - xq.rbdl_buf[i] = 0; + xq->var->rbdl_buf[i] = 0; /* get address of first receive buffer */ - xq.rbdl_ba = ((xq.rbdl[1] & 0x3F) << 16) | (xq.rbdl[0] & ~01); + xq->var->rbdl_ba = ((xq->var->rbdl[1] & 0x3F) << 16) | (xq->var->rbdl[0] & ~01); /* get first receive buffer */ - xq.rbdl_buf[0] = 0xFFFF; - wstatus = Map_WriteW(xq.rbdl_ba, 2, &xq.rbdl_buf[0], NOMAP); - rstatus = Map_ReadW (xq.rbdl_ba + 2, 6, &xq.rbdl_buf[1], NOMAP); - if (rstatus || wstatus) return xq_nxm_error(); + xq->var->rbdl_buf[0] = 0xFFFF; + wstatus = Map_WriteW(xq->var->rbdl_ba, 2, &xq->var->rbdl_buf[0], NOMAP); + rstatus = Map_ReadW (xq->var->rbdl_ba + 2, 6, &xq->var->rbdl_buf[1], NOMAP); + if (rstatus || wstatus) return xq_nxm_error(xq); /* is buffer valid? */ - if (~xq.rbdl_buf[1] & XQ_DSC_V) { - xq.csr |= XQ_CSR_RL; - if (xq.csr & XQ_CSR_IE) - SET_INT(XQ); + if (~xq->var->rbdl_buf[1] & XQ_DSC_V) { + xq->var->csr |= XQ_CSR_RL; return SCPE_OK; } /* process any waiting packets in receive queue */ - if (xq.ReadQ.count) - status = xq_process_rbdl(); + if (xq->var->ReadQ.count) + status = xq_process_rbdl(xq); return SCPE_OK; } -t_stat xq_dispatch_xbdl() +t_stat xq_dispatch_xbdl(CTLR* xq) { int i; t_stat status; #ifdef XQ_DEBUG - fprintf(stderr,"XQ: CSR - Dispatching write\n"); + fprintf(stderr,"%s: CSR - Dispatching write\n", xq->dev->name); #endif /* mark transmit bdl valid */ - xq.csr &= ~XQ_CSR_XL; + xq->var->csr &= ~XQ_CSR_XL; /* initialize transmit bdl buffers */ for (i=0; i<6; i++) - xq.xbdl_buf[i] = 0; + xq->var->xbdl_buf[i] = 0; /* clear transmit buffer */ - xq.write_buffer.len = 0; + xq->var->write_buffer.len = 0; /* get base address of first transmit descriptor */ - xq.xbdl_ba = ((xq.xbdl[1] & 0x3F) << 16) | (xq.xbdl[0] & ~01); + xq->var->xbdl_ba = ((xq->var->xbdl[1] & 0x3F) << 16) | (xq->var->xbdl[0] & ~01); /* process xbdl */ - status = xq_process_xbdl(); + status = xq_process_xbdl(xq); return status; } -t_stat xq_process_loopback(ETH_PACK* pack) +t_stat xq_process_loopback(CTLR* xq, ETH_PACK* pack) { ETH_PACK reply; ETH_MAC physical_address; @@ -1098,7 +1327,7 @@ t_stat xq_process_loopback(ETH_PACK* pack) /* create reply packet */ memcpy (&reply, pack, sizeof(ETH_PACK)); - memcpy (physical_address, xq.setup.valid ? xq.setup.macs[0] : xq.mac, sizeof(ETH_MAC)); + memcpy (physical_address, xq->var->setup.valid ? xq->var->setup.macs[0] : xq->var->mac, sizeof(ETH_MAC)); memcpy (&reply.msg[0], &reply.msg[offset+2], sizeof(ETH_MAC)); memcpy (&reply.msg[6], physical_address, sizeof(ETH_MAC)); memcpy (&reply.msg[offset+2], physical_address, sizeof(ETH_MAC)); @@ -1108,12 +1337,12 @@ t_stat xq_process_loopback(ETH_PACK* pack) reply.msg[15] = (offset >> 8) & 0xFF; /* send reply packet */ - status = eth_write(xq.etherface, &reply, NULL); + status = eth_write(xq->var->etherface, &reply, NULL); return status; } -t_stat xq_process_remote_console (ETH_PACK* pack) +t_stat xq_process_remote_console (CTLR* xq, ETH_PACK* pack) { t_stat status; ETH_MAC source; @@ -1126,7 +1355,7 @@ t_stat xq_process_remote_console (ETH_PACK* pack) memcpy(source, &pack->msg[6], sizeof(ETH_MAC)); /* send system id to requestor */ - status = xq_system_id (source, receipt); + status = xq_system_id (xq, source, receipt); return status; break; case 0x06: /* boot */ @@ -1152,146 +1381,374 @@ t_stat xq_process_remote_console (ETH_PACK* pack) return SCPE_NOFNC; } -t_stat xq_process_local (ETH_PACK* pack) +t_stat xq_process_local (CTLR* xq, ETH_PACK* pack) { /* returns SCPE_OK if local processing occurred, otherwise returns SCPE_NOFNC or some other code */ int protocol; /* DEQNA's have no local processing capability */ - if (xq.type == XQ_T_DEQNA) + if (xq->var->type == XQ_T_DEQNA) return SCPE_NOFNC; protocol = pack->msg[12] | (pack->msg[13] << 8); switch (protocol) { case 0x0090: /* ethernet loopback */ - return xq_process_loopback(pack); + return xq_process_loopback(xq, pack); break; case 0x0260: /* MOP remote console */ - return xq_process_remote_console(pack); + return xq_process_remote_console(xq, pack); break; } return SCPE_NOFNC; } -void xq_read_callback(int status) +void xq_read_callback(CTLR* xq, int status) { - if (xq.csr & XQ_CSR_RE) { /* receiver enabled */ + xq->var->stats.recv += 1; + if (xq->var->csr & XQ_CSR_RE) { /* receiver enabled */ /* process any packets locally that can be */ - t_stat status = xq_process_local (&xq.read_buffer); + t_stat status = xq_process_local (xq, &xq->var->read_buffer); /* add packet to read queue */ if (status != SCPE_OK) - xq_insert_queue(&xq.ReadQ, 2, &xq.read_buffer, status); + xq_insert_queue(&xq->var->ReadQ, 2, &xq->var->read_buffer, status); } #ifdef XQ_DEBUG else - fprintf(stderr, "XQ: packet received with receiver disabled\n"); + fprintf(stderr, "%s: packet received with receiver disabled\n", xq->dev->name); #endif } -void xq_sw_reset(void) +void xqa_read_callback(int status) { - /* cancel sanity timer */ - xq_cancel_santmr(); + xq_read_callback(&xq_ctrl[0], status); +} - /* disconnect ethernet reception */ - sim_cancel(&xq_unit[0]); +void xqb_read_callback(int status) +{ + xq_read_callback(&xq_ctrl[1], status); +} - /* stop system_id timer */ - sim_cancel(&xq_unit[2]); +void xq_sw_reset(CTLR* xq) +{ + int i; + + /* cancel all timers (ethernet, sanity, system_id) */ + for (i=0; i<3; i++) + sim_cancel(&xq->unit[i]); /* reset csr bits */ - xq.csr = XQ_CSR_XL | XQ_CSR_RL; + xq->var->csr = XQ_CSR_XL | XQ_CSR_RL; - if (xq.etherface) - xq.csr |= XQ_CSR_OK; + if (xq->var->etherface) + xq->var->csr |= XQ_CSR_OK; + + /* clear CPU interrupts */ + CLR_INT(XQ); /* flush read queue */ - xq_clear_queue(&xq.ReadQ); + xq_clear_queue(&xq->var->ReadQ); /* clear setup info */ - memset (&xq.setup, 0, sizeof(xq.setup)); - + memset (&xq->var->setup, 0, sizeof(xq->var->setup)); } /* write registers: */ -t_stat xq_wr_var(int32 data) +t_stat xq_wr_var(CTLR* xq, int32 data) { + #ifdef XQ_DEBUG - xq_var_changes(data); + xq_var_changes(xq, data); #endif - switch (xq.type) { + switch (xq->var->type) { case XQ_T_DEQNA: - xq.var = (data & XQ_VEC_IV); + xq->var->var = (data & XQ_VEC_IV); break; case XQ_T_DELQA: - xq.var = (xq.var & XQ_VEC_RO) | (data & XQ_VEC_RW); + xq->var->var = (xq->var->var & XQ_VEC_RO) | (data & XQ_VEC_RW); /* if switching to DEQNA-LOCK mode clear VAR<14:10> */ - if (~xq.var & XQ_VEC_MS) - xq.var &= ~(XQ_VEC_OS | XQ_VEC_RS | XQ_VEC_ST); + if (~xq->var->var & XQ_VEC_MS) + xq->var->var &= ~(XQ_VEC_OS | XQ_VEC_RS | XQ_VEC_ST); break; } /* set vector of SIMH device */ if (data & XQ_VEC_IV) - xq_dib.vec = (data & XQ_VEC_IV) + VEC_Q; + xq->dib->vec = (data & XQ_VEC_IV) + VEC_Q; else - xq_dib.vec = 0; + xq->dib->vec = 0; return SCPE_OK; } -t_stat xq_wr_csr(int32 data) +#ifdef VM_PDP11 +t_stat xq_process_bootrom (CTLR* xq) { - uint16 saved_csr = xq.csr; + /* + NOTE: BOOT ROMs are a PDP-11ism, since they contain PDP-11 binary code. + the host is responsible for creating two *2KB* receive buffers. + + RSTS/E v10.1 source (INIONE.MAR/XHLOOK:) indicates that both the DEQNA and + DELQA will set receive status word 1 bits 15 & 14 on both packets. It also + states that a hardware bug in the DEQNA will set receive status word 1 bit 15 + (only) in the *third* receive buffer (oops!). + + RSTS/E v10.1 will run the Citizenship test from the bootrom after loading it. + Documentation on the Boot ROM can be found in INIQNA.MAR. + */ + + int32 rstatus, wstatus; + uint16 b_length, w_length; + uint32 address; + uint8* bootrom = (uint8*) xq_bootrom; + int i, checksum; + #ifdef XQ_DEBUG - xq_csr_changes(data); + fprintf(stderr,"%s: CSR - Processing boot rom load\n", xq->dev->name); +#endif + + /* + RSTS/E v10.1 invokes the Citizenship tests in the Bootrom. For some + reason, the current state of the XQ emulator cannot pass these. So, + to get moving on RSTE/E support, we will replace the following line in + INIQNA.MAR/CITQNA:: + 70$: MOV (R2),R0 ;get the status word + with + 70$: CLR R0 ;force success + to cause the Citizenship test to return success to RSTS/E. + + At some point, the real problem (failure to pass citizenship diagnostics) + does need to be corrected to find incompatibilities in the emulation, and to + ultimately allow it to pass Digital hardware diagnostic tests. + */ + for (i=0; ivar->rbdl_buf[0] = 0xFFFF; + wstatus = Map_WriteW(xq->var->rbdl_ba, 2, &xq->var->rbdl_buf[0], NOMAP); + rstatus = Map_ReadW (xq->var->rbdl_ba + 2, 6, &xq->var->rbdl_buf[1], NOMAP); + if (rstatus || wstatus) return xq_nxm_error(xq); + + /* invalid buffer? */ + if (~xq->var->rbdl_buf[1] & XQ_DSC_V) { + xq->var->csr |= XQ_CSR_RL; + return SCPE_OK; + } + + /* get status words */ + rstatus = Map_ReadW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4], NOMAP); + if (rstatus) return xq_nxm_error(xq); + + /* get host memory address */ + address = ((xq->var->rbdl_buf[1] & 0x3F) << 16) | xq->var->rbdl_buf[2]; + +#ifdef XQ_DEBUG + fprintf(stderr,"%s: BootRom1 load address: 0%o\n", xq->dev->name, address); +#endif + + /* decode buffer length - two's complement (in words) */ + w_length = ~xq->var->rbdl_buf[3] + 1; + b_length = w_length * 2; + if (xq->var->rbdl_buf[1] & XQ_DSC_H) b_length -= 1; + if (xq->var->rbdl_buf[1] & XQ_DSC_L) b_length -= 1; + + /* make sure entire packet fits in buffer */ + assert(b_length >= sizeof(xq_bootrom)/2); + + /* send data to host */ + wstatus = Map_WriteB(address, sizeof(xq_bootrom)/2, bootrom, NOMAP); + if (wstatus) return xq_nxm_error(xq); + + /* update read status words */ + xq->var->rbdl_buf[4] = XQ_DSC_V | XQ_DSC_C; /* valid, chain */ + xq->var->rbdl_buf[5] = 0; + + /* update read status words*/ + wstatus = Map_WriteW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4], NOMAP); + if (wstatus) return xq_nxm_error(xq); + + /* set to next bdl (implicit chain) */ + xq->var->rbdl_ba += 12; + + /* --------------------------- bootrom part 2 -----------------------------*/ + + /* get receive bdl from memory */ + xq->var->rbdl_buf[0] = 0xFFFF; + wstatus = Map_WriteW(xq->var->rbdl_ba, 2, &xq->var->rbdl_buf[0], NOMAP); + rstatus = Map_ReadW (xq->var->rbdl_ba + 2, 6, &xq->var->rbdl_buf[1], NOMAP); + if (rstatus || wstatus) return xq_nxm_error(xq); + + /* invalid buffer? */ + if (~xq->var->rbdl_buf[1] & XQ_DSC_V) { + xq->var->csr |= XQ_CSR_RL; + return SCPE_OK; + } + + /* get status words */ + rstatus = Map_ReadW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4], NOMAP); + if (rstatus) return xq_nxm_error(xq); + + /* get host memory address */ + address = ((xq->var->rbdl_buf[1] & 0x3F) << 16) | xq->var->rbdl_buf[2]; + +#ifdef XQ_DEBUG + fprintf(stderr,"%s: BootRom2 load address: 0%o\n", xq->dev->name, address); +#endif + + /* decode buffer length - two's complement (in words) */ + w_length = ~xq->var->rbdl_buf[3] + 1; + b_length = w_length * 2; + if (xq->var->rbdl_buf[1] & XQ_DSC_H) b_length -= 1; + if (xq->var->rbdl_buf[1] & XQ_DSC_L) b_length -= 1; + + /* make sure entire packet fits in buffer */ + assert(b_length >= sizeof(xq_bootrom)/2); + + /* send data to host */ + wstatus = Map_WriteB(address, sizeof(xq_bootrom)/2, &bootrom[2048], NOMAP); + if (wstatus) return xq_nxm_error(xq); + + /* update read status words */ + xq->var->rbdl_buf[4] = XQ_DSC_V | XQ_DSC_C; /* valid, chain */ + xq->var->rbdl_buf[5] = 0; + + /* update read status words*/ + wstatus = Map_WriteW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4], NOMAP); + if (wstatus) return xq_nxm_error(xq); + + /* set to next bdl (implicit chain) */ + xq->var->rbdl_ba += 12; + + /* --------------------------- bootrom part 3 -----------------------------*/ + + switch (xq->var->type) { + case XQ_T_DEQNA: + + /* get receive bdl from memory */ + xq->var->rbdl_buf[0] = 0xFFFF; + wstatus = Map_WriteW(xq->var->rbdl_ba, 2, &xq->var->rbdl_buf[0], NOMAP); + rstatus = Map_ReadW (xq->var->rbdl_ba + 2, 6, &xq->var->rbdl_buf[1], NOMAP); + if (rstatus || wstatus) return xq_nxm_error(xq); + + /* invalid buffer? */ + if (~xq->var->rbdl_buf[1] & XQ_DSC_V) { + xq->var->csr |= XQ_CSR_RL; + return SCPE_OK; + } + + /* get status words */ + rstatus = Map_ReadW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4], NOMAP); + if (rstatus) return xq_nxm_error(xq); + + /* update read status words */ + xq->var->rbdl_buf[4] = XQ_DSC_V; /* valid */ + xq->var->rbdl_buf[5] = 0; + + /* update read status words*/ + wstatus = Map_WriteW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4], NOMAP); + if (wstatus) return xq_nxm_error(xq); + + /* set to next bdl (implicit chain) */ + xq->var->rbdl_ba += 12; + break; + } /* switch */ + + /* --------------------------- Done, finish up -----------------------------*/ + + /* mark transmission complete */ + xq->var->csr |= XQ_CSR_RI; + if (xq->var->csr & XQ_CSR_IE) + SET_INT(XQ); + + /* reset sanity timer */ + xq_reset_santmr(xq); + + return SCPE_OK; +} +#endif /* ifdef VM_PDP11 */ + +t_stat xq_wr_csr(CTLR* xq, int32 data) +{ +#ifdef VM_PDP11 + static const uint16 bd_bits_on = XQ_CSR_BD | XQ_CSR_EL; +#endif + int old_int_state, new_int_state; + const uint16 saved_csr = xq->var->csr; + +#ifdef XQ_DEBUG + xq_csr_changes(xq, data); #endif /* reset controller when SR transitions to cleared */ - if (xq.csr & XQ_CSR_SR & ~data) { - xq_sw_reset(); + if (xq->var->csr & XQ_CSR_SR & ~data) { + xq_sw_reset(xq); return SCPE_OK; } /* write the writeable bits */ - xq.csr = (xq.csr & XQ_CSR_RO) | (data & XQ_CSR_RW); + xq->var->csr = (xq->var->csr & XQ_CSR_RO) | (data & XQ_CSR_RW); /* clear write-one-to-clear bits */ - xq.csr &= ~(data & XQ_CSR_W1); + xq->var->csr &= ~(data & XQ_CSR_W1); if (data & XQ_CSR_XI) /* clearing XI clears NI too */ - xq.csr &= ~XQ_CSR_NI; + xq->var->csr &= ~XQ_CSR_NI; /* start receiver timer when RE transitions to set */ if (~saved_csr & XQ_CSR_RE & data) { - sim_activate(&xq_unit[0], (clk_tps * tmr_poll)/100); + sim_activate(&xq->unit[0], (clk_tps * tmr_poll)/100); } /* stop receiver timer when RE transitions to clear */ if (saved_csr & XQ_CSR_RE & ~data) { - sim_cancel(&xq_unit[0]); + sim_cancel(&xq->unit[0]); } + /* check and correct CPU interrupt state */ + old_int_state = (saved_csr & XQ_CSR_IE) && (saved_csr & (XQ_CSR_XI | XQ_CSR_RI)); + new_int_state = (xq->var->csr & XQ_CSR_IE) && (xq->var->csr & (XQ_CSR_XI | XQ_CSR_RI)); + if ( old_int_state && !new_int_state) CLR_INT(XQ); + if (!old_int_state && new_int_state) SET_INT(XQ); + +#ifdef VM_PDP11 + /* request boot/diagnostic rom? [PDP-11 only] */ + if ((bd_bits_on & data) == bd_bits_on) /* all bits must be on */ + xq_process_bootrom(xq); +#endif + return SCPE_OK; } t_stat xq_wr(int32 data, int32 PA, int32 access) { t_stat status; + CTLR* xq = xq_pa2ctlr(PA); int index = (PA >> 1) & 07; /* word index */ #ifdef XQ_DEBUG if (index != 7) + fprintf (stderr,"%s: %s", xq->dev->name, xq_xmit_regnames[index]); #if defined(VM_VAX) - fprintf (stderr,"XQ: %s %08X %08X write: %X\n", xq_xmit_regnames[index], fault_PC, PSL, data); -#else - fprintf (stderr,"XQ: %s write: %X\n", xq_xmit_regnames[index], data); + fprintf (stderr," %08X %08X", fault_PC, PSL); #endif /* VM_VAX */ + fprintf (stderr," write: %X\n", data); #endif switch (index) { @@ -1299,24 +1756,24 @@ t_stat xq_wr(int32 data, int32 PA, int32 access) case 1: break; case 2: /* receive bdl low bits */ - xq.rbdl[0] = data; + xq->var->rbdl[0] = data; break; case 3: /* receive bdl high bits */ - xq.rbdl[1] = data; - status = xq_dispatch_rbdl(); /* start receive operation */ + xq->var->rbdl[1] = data; + status = xq_dispatch_rbdl(xq); /* start receive operation */ break; case 4: /* transmit bdl low bits */ - xq.xbdl[0] = data; + xq->var->xbdl[0] = data; break; case 5: /* transmit bdl high bits */ - xq.xbdl[1] = data; - status = xq_dispatch_xbdl(); /* start transmit operation */ + xq->var->xbdl[1] = data; + status = xq_dispatch_xbdl(xq); /* start transmit operation */ break; case 6: /* vector address register */ - status = xq_wr_var(data); + status = xq_wr_var(xq, data); break; case 7: /* control and status register */ - status = xq_wr_csr(data); + status = xq_wr_csr(xq, data); break; } return SCPE_OK; @@ -1327,98 +1784,114 @@ t_stat xq_wr(int32 data, int32 PA, int32 access) t_stat xq_reset(DEVICE* dptr) { t_stat status; + CTLR* xq = xq_dev2ctlr(dptr); /* calculate MAC checksum */ - make_checksum(); + xq_make_checksum(xq); /* init vector address register */ - switch (xq.type) { + switch (xq->var->type) { case XQ_T_DEQNA: - xq.var = 0; + xq->var->var = 0; break; case XQ_T_DELQA: - xq.var = XQ_VEC_MS | XQ_VEC_OS; + xq->var->var = XQ_VEC_MS | XQ_VEC_OS; break; } - xq_dib.vec = 0; + xq->dib->vec = 0; /* init control status register */ - xq.csr = XQ_CSR_RL | XQ_CSR_XL; + xq->var->csr = XQ_CSR_RL | XQ_CSR_XL; /* reset ethernet interface */ - if (xq.etherface) { - status = eth_filter (xq.etherface, 1, &xq.mac, 0, 0); - xq.csr |= XQ_CSR_OK; + if (xq->var->etherface) { + status = eth_filter (xq->var->etherface, 1, &xq->var->mac, 0, 0); + xq->var->csr |= XQ_CSR_OK; } + /* init read queue (first time only) */ + status = xq_init_queue (xq, &xq->var->ReadQ); + if (status != SCPE_OK) + return status; + /* clear read queue */ - xq_clear_queue(&xq.ReadQ); + xq_clear_queue(&xq->var->ReadQ); /* start sanity timer if power-on SANITY is set */ - switch (xq.type) { + switch (xq->var->type) { case XQ_T_DEQNA: - if (xq.sanity.enabled) { - xq.sanity.quarter_secs = 4 * (4 * 60); /* default is 4 minutes */; - xq_start_santmr(); + if (xq->var->sanity.enabled) { + xq->var->sanity.quarter_secs = 4 * (4 * 60); /* default is 4 minutes */; + xq_start_santmr(xq); } break; case XQ_T_DELQA: /* note that the DELQA in NORMAL mode has no power-on SANITY state! */ - xq_start_idtmr(); + xq_start_idtmr(xq); break; }; return SCPE_OK; } -void xq_start_santmr(void) +void xq_start_santmr(CTLR* xq) { + UNIT* xq_santmr = &xq->unit[1]; /* sanity timer uses unit 1 */ + /* must be recalculated each time since tmr_poll is a dynamic number */ const int32 quarter_sec = (clk_tps * tmr_poll) / 4; #if 0 #ifdef XQ_DEBUG - fprintf(stderr,"XQ: SANITY TIMER: enabled, qsecs: %d, poll:%d\n", xq.sanity.quarter_secs, tmr_poll); + fprintf(stderr,"%s: SANITY TIMER ENABLED, qsecs: %d, poll:%d\n", + xq->dev->name, xq->var->sanity.quarter_secs, tmr_poll); #endif #endif - if (sim_is_active(&xq_unit[1])) /* cancel timer, just in case */ - sim_cancel(&xq_unit[1]); - xq_reset_santmr(); - sim_activate(&xq_unit[1], quarter_sec); + if (sim_is_active(xq_santmr)) /* cancel timer, just in case */ + sim_cancel(xq_santmr); + xq_reset_santmr(xq); + sim_activate(xq_santmr, quarter_sec); } -void xq_cancel_santmr(void) +void xq_cancel_santmr(CTLR* xq) { + UNIT* xq_santmr = &xq->unit[1]; /* sanity timer uses unit 1 */ + /* can't cancel hardware switch sanity timer */ - if (sim_is_active(&xq_unit[1]) && !xq.sanity.enabled) { + if (sim_is_active(xq_santmr) && !xq->var->sanity.enabled) { #if 0 #ifdef XQ_DEBUG - fprintf(stderr,"XQ: SANITY TIMER: cancelled, qsecs: %d\n", xq.sanity.quarter_secs); + fprintf(stderr,"%s: SANITY TIMER CANCELLED, qsecs: %d\n", + xq->dev->name, xq->var->sanity.quarter_secs); #endif #endif - sim_cancel(&xq_unit[1]); + sim_cancel(xq_santmr); } } -void xq_reset_santmr(void) +void xq_reset_santmr(CTLR* xq) { #if 0 #ifdef XQ_DEBUG ftime(&start); - fprintf(stderr,"XQ: SANITY TIMER: resetting, qsecs: %d\n", xq.sanity.quarter_secs); + fprintf(stderr,"%s: SANITY TIMER RESETTING, qsecs: %d\n", + xq->dev->name, xq->var->sanity.quarter_secs); #endif #endif - xq.sanity.countdown = xq.sanity.quarter_secs; + xq->var->sanity.countdown = xq->var->sanity.quarter_secs; } t_stat xq_sansvc(UNIT* uptr) { - if (--xq.sanity.countdown) { + CTLR* xq = xq_unit2ctlr(uptr); + UNIT* xq_santmr = &xq->unit[1]; /* sanity timer uses unit 1 */ + + if (--xq->var->sanity.countdown) { /* must be recalculated each time since tmr_poll is a dynamic number */ const int32 quarter_sec = (clk_tps * tmr_poll) / 4; /* haven't hit the end of the countdown timer yet, resubmit */ - sim_activate(&xq_unit[1], quarter_sec); + sim_activate(xq_santmr, quarter_sec); } else { /* If this section is entered, it means that the sanity timer has expired @@ -1427,8 +1900,8 @@ t_stat xq_sansvc(UNIT* uptr) #if 0 #ifdef XQ_DEBUG ftime(&finish); - fprintf(stderr,"XQ: SANITY TIMER: EXPIRED, qsecs: %d, poll: %d, elapsed: %d\n", - xq.sanity.quarter_secs, tmr_poll, finish.time - start.time); + fprintf(stderr,"%s: SANITY TIMER EXPIRED, qsecs: %d, poll: %d, elapsed: %d\n", + xq->dev->name, xq->var->sanity.quarter_secs, tmr_poll, finish.time - start.time); #endif #endif xq_boot_host(); @@ -1449,20 +1922,22 @@ t_stat xq_boot_host(void) return STOP_SANITY; } -void xq_start_idtmr(void) +void xq_start_idtmr(CTLR* xq) { + UNIT* xq_idtmr = &xq->unit[2]; /* system id timer uses unit 2 */ + /* must be recalculated each time since tmr_poll is a dynamic number */ const int32 one_sec = clk_tps * tmr_poll; - if (sim_is_active(&xq_unit[2])) /* cancel timer, just in case */ - sim_cancel(&xq_unit[2]); - xq.id.enabled = 1; + if (sim_is_active(xq_idtmr)) /* cancel timer, just in case */ + sim_cancel(xq_idtmr); + xq->var->id.enabled = 1; /* every 8-10 minutes (9 in this case) the DELQA broadcasts a system id message */ - xq.id.countdown = 9 * 60; - sim_activate(&xq_unit[2], one_sec); + xq->var->id.countdown = 9 * 60; + sim_activate(xq_idtmr, one_sec); } -t_stat xq_system_id (const ETH_MAC dest, uint16 receipt_id) +t_stat xq_system_id (CTLR* xq, const ETH_MAC dest, uint16 receipt_id) { static uint16 receipt = 0; ETH_PACK system_id; @@ -1471,7 +1946,7 @@ t_stat xq_system_id (const ETH_MAC dest, uint16 receipt_id) memset (&system_id, 0, sizeof(system_id)); memcpy (&msg[0], dest, sizeof(ETH_MAC)); - memcpy (&msg[6], xq.setup.valid ? xq.setup.macs[0] : xq.mac, sizeof(ETH_MAC)); + memcpy (&msg[6], xq->var->setup.valid ? xq->var->setup.macs[0] : xq->var->mac, sizeof(ETH_MAC)); msg[12] = 0x60; /* type */ msg[13] = 0x02; /* type */ msg[14] = 0x1C; /* character count */ @@ -1505,7 +1980,7 @@ t_stat xq_system_id (const ETH_MAC dest, uint16 receipt_id) msg[31] = 0x07; /* type */ msg[32] = 0x00; /* type */ msg[33] = 0x06; /* length */ - memcpy (&msg[34], xq.mac, sizeof(ETH_MAC)); /* ROM address */ + memcpy (&msg[34], xq->var->mac, sizeof(ETH_MAC)); /* ROM address */ /* DEVICE TYPE */ msg[40] = 37; /* type */ @@ -1515,33 +1990,36 @@ t_stat xq_system_id (const ETH_MAC dest, uint16 receipt_id) /* write system id */ system_id.len = 60; - status = eth_write(xq.etherface, &system_id, NULL); + status = eth_write(xq->var->etherface, &system_id, NULL); return status; } t_stat xq_idsvc(UNIT* uptr) { -/* must be recalculated each time since tmr_poll is a dynamic number */ -const int32 one_sec = clk_tps * tmr_poll; -const ETH_MAC mop_multicast = {0xAB, 0x00, 0x00, 0x02, 0x00, 0x00}; + CTLR* xq = xq_unit2ctlr(uptr); + UNIT* xq_idtmr = &xq->unit[2]; /* system id timer uses unit 2 */ + + /* must be recalculated each time since tmr_poll is a dynamic number */ + const int32 one_sec = clk_tps * tmr_poll; + const ETH_MAC mop_multicast = {0xAB, 0x00, 0x00, 0x02, 0x00, 0x00}; /* DEQNAs don't issue system id messages */ - if (xq.type == XQ_T_DEQNA) + if (xq->var->type == XQ_T_DEQNA) return SCPE_NOFNC; - if (--xq.id.countdown <= 0) { + if (--xq->var->id.countdown <= 0) { /* If this section is entered, it means that the 9 minute interval has elapsed so broadcast system id to MOP multicast address */ - xq_system_id(mop_multicast, 0); + xq_system_id(xq, mop_multicast, 0); /* every 8-10 minutes (9 in this case) the DELQA broadcasts a system id message */ - xq.id.countdown = 9 * 60; + xq->var->id.countdown = 9 * 60; } /* resubmit - for one second to get a well calibrated value of tmr_poll */ - sim_activate(&xq_unit[2], one_sec); + sim_activate(xq_idtmr, one_sec); return SCPE_OK; } @@ -1552,30 +2030,32 @@ t_stat xq_svc(UNIT* uptr) { t_stat status; int queue_size; + CTLR* xq = xq_unit2ctlr(uptr); + UNIT* xq_svctmr = &xq->unit[0]; /* Don't try a read if the receiver is disabled */ - if (!(xq.csr & XQ_CSR_RE)) return SCPE_OK; + if (!(xq->var->csr & XQ_CSR_RE)) return SCPE_OK; /* First pump any queued packets into the system */ - if ((xq.ReadQ.count > 0) && (~xq.csr & XQ_CSR_RL)) - status = xq_process_rbdl(); + if ((xq->var->ReadQ.count > 0) && (~xq->var->csr & XQ_CSR_RL)) + status = xq_process_rbdl(xq); /* Now read and queue packets that have arrived */ /* This is repeated as long as they are available and we have room */ do { - queue_size = xq.ReadQ.count; + queue_size = xq->var->ReadQ.count; /* read a packet from the ethernet - processing is via the callback */ - status = eth_read (xq.etherface, &xq.read_buffer, &xq_read_callback); - } while (queue_size != xq.ReadQ.count); + status = eth_read (xq->var->etherface, &xq->var->read_buffer, xq->var->rcallback); + } while (queue_size != xq->var->ReadQ.count); /* Now pump any still queued packets into the system */ - if ((xq.ReadQ.count > 0) && (~xq.csr & XQ_CSR_RL)) - status = xq_process_rbdl(); + if ((xq->var->ReadQ.count > 0) && (~xq->var->csr & XQ_CSR_RL)) + status = xq_process_rbdl(xq); /* resubmit if still receive enabled */ - if (xq.csr & XQ_CSR_RE) - sim_activate(&xq_unit[0], (clk_tps * tmr_poll)/100); + if (xq->var->csr & XQ_CSR_RE) + sim_activate(xq_svctmr, (clk_tps * tmr_poll)/100); return SCPE_OK; } @@ -1587,26 +2067,27 @@ t_stat xq_attach(UNIT* uptr, char* cptr) { t_stat status; char* tptr; + CTLR* xq = xq_unit2ctlr(uptr); tptr = malloc(strlen(cptr) + 1); if (tptr == NULL) return SCPE_MEM; strcpy(tptr, cptr); - xq.etherface = malloc(sizeof(ETH_DEV)); - if (!xq.etherface) return SCPE_MEM; + xq->var->etherface = malloc(sizeof(ETH_DEV)); + if (!xq->var->etherface) return SCPE_MEM; - status = eth_open(xq.etherface, cptr); + status = eth_open(xq->var->etherface, cptr); if (status != SCPE_OK) { free(tptr); - free(xq.etherface); - xq.etherface = 0; + free(xq->var->etherface); + xq->var->etherface = 0; return status; } uptr->filename = tptr; uptr->flags |= UNIT_ATT; /* turn on transceiver power indicator */ - xq.csr |= XQ_CSR_OK; + xq->var->csr |= XQ_CSR_OK; return SCPE_OK; } @@ -1616,25 +2097,31 @@ t_stat xq_attach(UNIT* uptr, char* cptr) t_stat xq_detach(UNIT* uptr) { t_stat status; + CTLR* xq = xq_unit2ctlr(uptr); if (uptr->flags & UNIT_ATT) { - status = eth_close (xq.etherface); - free(xq.etherface); - xq.etherface = 0; + status = eth_close (xq->var->etherface); + free(xq->var->etherface); + xq->var->etherface = 0; free(uptr->filename); uptr->filename = NULL; uptr->flags &= ~UNIT_ATT; } /* turn off transceiver power indicator */ - xq.csr &= ~XQ_CSR_OK; + xq->var->csr &= ~XQ_CSR_OK; return SCPE_OK; } int32 xq_inta (void) { - return xq_dib.vec; + return xqa_dib.vec; +} + +int32 xq_intb (void) +{ + return xqb_dib.vec; } /*============================================================================== @@ -1643,13 +2130,13 @@ int32 xq_inta (void) #ifdef XQ_DEBUG -void xq_dump_csr (void) +void xq_dump_csr (CTLR* xq) { static int cnt = 0; /* tell user what is changing in register */ int i; int mask = 1; - uint16 csr = xq.csr; + uint16 csr = xq->var->csr; char hi[256] = "Set: "; char lo[256] = "Reset: "; for (i=0; i<16; i++, mask <<= 1) { @@ -1657,17 +2144,17 @@ void xq_dump_csr (void) if ((~csr & mask)) strcat (lo, xq_csr_bits[i]); } #if defined (VM_VAX) - printf ("CSR %08X %08X read: %s %s\n", fault_PC, PSL, hi, lo); + printf ("%s: CSR %08X %08X read: %s %s\n", xq->dev->name, fault_PC, PSL, hi, lo); #else if (cnt < 20) - printf ("CSR read[%d]: %s %s\n", cnt++, hi, lo); + printf ("%s: CSR read[%d]: %s %s\n", xq->dev->name, cnt++, hi, lo); #endif /* VM_VAX */ } -void xq_dump_var (void) +void xq_dump_var (CTLR* xq) { /* tell user what is changing in register */ - uint16 var = xq.var; + uint16 var = xq->var->var; char hi[256] = "Set: "; char lo[256] = "Reset: "; int vec = (var & XQ_VEC_IV) >> 2; @@ -1679,15 +2166,15 @@ void xq_dump_var (void) strcat((var & XQ_VEC_S1) ? hi : lo, "S1 "); strcat((var & XQ_VEC_RR) ? hi : lo, "RR "); strcat((var & XQ_VEC_ID) ? hi : lo, "ID "); - printf ("VAR read: %s %s - Vec: %d \n", hi, lo, vec); + printf ("%s: VAR read: %s %s - Vec: %d \n", xq->dev->name, hi, lo, vec); } -void xq_csr_changes (uint16 data) +void xq_csr_changes (CTLR* xq, uint16 data) { /* tell user what is changing in register */ int i; int mask = 1; - uint16 csr = xq.csr; + uint16 csr = xq->var->csr; char hi[256] = "Setting: "; char lo[256] = "Resetting: "; for (i=0; i<16; i++, mask <<= 1) { @@ -1698,17 +2185,17 @@ void xq_csr_changes (uint16 data) if (data & XQ_CSR_RI) strcat(lo, "RI "); if (data & XQ_CSR_XI) strcat(lo, "XI "); #if defined(VM_VAX) - printf ("CSR %08X %08X write: %s %s\n", fault_PC, PSL, hi, lo); + printf ("%s: CSR %08X %08X write: %s %s\n", xq->dev->name, fault_PC, PSL, hi, lo); #else - printf ("CSR write: %s %s\n", hi, lo); + printf ("%s: CSR write: %s %s\n", xq->dev->name, hi, lo); #endif /* VM_VAX */ } -void xq_var_changes (uint16 data) +void xq_var_changes (CTLR* xq, uint16 data) { /* tell user what is changing in register */ uint16 vec; - uint16 var = xq.var; + uint16 var = xq->var->var; char hi[256] = "Setting: "; char lo[256] = "Resetting: "; if (~var & XQ_VEC_MS & data) strcat (hi, "MS "); @@ -1722,31 +2209,32 @@ void xq_var_changes (uint16 data) if ((var & XQ_VEC_IV) != (data & XQ_VEC_IV)) { vec = (data & XQ_VEC_IV) >> 2; - printf ("VAR write: %s %s - Vec: %d\n", hi, lo, vec); - } else - printf ("VAR write: %s %s\n", hi, lo); + printf ("%s: VAR write: %s %s - Vec: %d\n", xq->dev->name, hi, lo, vec); + } else + printf ("%s: VAR write: %s %s\n", xq->dev->name, hi, lo); } -void xq_debug_setup(void) +void xq_debug_setup(CTLR* xq) { int i; char buffer[20]; - if (xq.write_buffer.msg[0]) - printf ("Setup: MOP info present!\n"); + if (xq->var->write_buffer.msg[0]) + printf ("%s: Setup: MOP info present!\n", xq->dev->name); for (i = 0; i < XQ_FILTER_MAX; i++) { - eth_mac_fmt(&xq.setup.macs[i], buffer); - printf ("Setup: set addr[%d]: %s\n", i, buffer); + eth_mac_fmt(&xq->var->setup.macs[i], buffer); + printf ("%s: Setup: set addr[%d]: %s\n", xq->dev->name, i, buffer); } - if (xq.write_buffer.len > 128) { + if (xq->var->write_buffer.len > 128) { char buffer[20] = {0}; - uint16 len = xq.write_buffer.len; + uint16 len = xq->var->write_buffer.len; if (len & XQ_SETUP_MC) strcat(buffer, "MC "); if (len & XQ_SETUP_PM) strcat(buffer, "PM "); if (len & XQ_SETUP_LD) strcat(buffer, "LD "); if (len & XQ_SETUP_ST) strcat(buffer, "ST "); - printf ("Setup: Length [%d =0x%X, LD:%d, ST:%d] info: %s\n", len, len, (len & XQ_SETUP_LD) >> 2, (len & XQ_SETUP_ST) >> 4, buffer); + printf ("%s: Setup: Length [%d =0x%X, LD:%d, ST:%d] info: %s\n", + xq->dev->name, len, len, (len & XQ_SETUP_LD) >> 2, (len & XQ_SETUP_ST) >> 4, buffer); } } #endif diff --git a/PDP11/pdp11_xq.h b/PDP11/pdp11_xq.h index 2b978bab..6f174ceb 100644 --- a/PDP11/pdp11_xq.h +++ b/PDP11/pdp11_xq.h @@ -1,7 +1,7 @@ /* pdp11_xq.h: DEQNA/DELQA ethernet controller information ------------------------------------------------------------------------------ - Copyright (c) 2002, David T. Hittner + Copyright (c) 2002-2003, David T. Hittner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,10 +28,15 @@ Modification history: + 02-Jun-03 DTH Added struct xq_stats + 28-May-03 DTH Made xq_msg_que.item dynamic + 28-May-03 MP Optimized structures, removed rtime variable + 06-May-03 DTH Changed 32-bit t_addr to uint32 for v3.0 + 28-Apr-03 DTH Added callbacks for multicontroller identification + 25-Mar-03 DTH Removed bootrom field - no longer needed; Updated copyright 15-Jan-03 DTH Merged Mark Pizzolato's changes into main source - 13-Jan-03 MP Added xq_id to countdown the triggering of the System Id - multicast packets - 10-Jan-03 DTH Added bootrom + 13-Jan-03 MP Added countdown for System Id multicast packets + 10-Jan-03 DTH Added bootrom field 30-Dec-02 DTH Added setup valid field 21-Oct-02 DTH Corrected copyright again 15-Oct-02 DTH Fixed copyright, added sanity timer support @@ -46,20 +51,26 @@ #ifndef _PDP11_XQ_H #define _PDP11_XQ_H -#if defined (USE_INT64) +#if defined (VM_PDP10) /* PDP10 version */ +#error "DEQNA/DELQA not supported on PDP10!" + +#elif defined (VM_VAX) /* VAX version */ #include "vax_defs.h" -#define VM_VAX 1 #define XQ_RDX 16 #define XQ_WID 32 +extern int32 PSL; /* PSL */ +extern int32 fault_PC; /* fault PC */ +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; -#else +#else /* PDP-11 version */ #include "pdp11_defs.h" -#define VM_PDP11 1 #define XQ_RDX 8 #define XQ_WID 16 +extern int32 int_req[IPL_HLVL]; +extern int32 int_vec[IPL_HLVL][32]; #endif - #include "sim_ether.h" /* message queue arrays */ @@ -81,16 +92,17 @@ struct xq_id { struct xq_msg_itm { int type; /* receive (0=setup, 1=loopback, 2=normal) */ - ETH_PACK packet; /* packet */ int32 status; /* message size */ + ETH_PACK packet; /* packet */ }; struct xq_msg_que { - int count; - int head; - int tail; - struct xq_msg_itm item[XQ_QUE_MAX]; - int loss; + int count; + int head; + int tail; + int loss; + int high; + struct xq_msg_itm* item; }; struct xq_setup { @@ -104,6 +116,17 @@ struct xq_setup { ETH_MAC macs[XQ_FILTER_MAX]; /* MAC addresses to respond to */ }; +struct xq_stats { + int recv; /* received packets */ + int filter; /* filtered packets */ + int xmit; /* transmitted packets */ + int fail; /* transmit failed */ + int runt; /* runts */ + int giant; /* oversize packets */ + int setup; /* setup packets */ + int loop; /* loopback packets */ +}; + struct xq_meb { /* MEB block */ uint8 type; uint8 add_lo; @@ -115,7 +138,8 @@ struct xq_meb { /* MEB block */ struct xq_device { /*+ initialized values - DO NOT MOVE */ - int rtime; /* ethernet read timer */ + ETH_PCALLBACK rcallback; /* read callback routine */ + ETH_PCALLBACK wcallback; /* write callback routine */ ETH_MAC mac; /* MAC address */ enum xq_type type; /* controller type */ struct xq_sanity sanity; /* sanity timer information */ @@ -131,20 +155,29 @@ struct xq_device { /* buffers, etc. */ struct xq_setup setup; + struct xq_stats stats; uint8 mac_checksum[2]; uint16 rbdl_buf[6]; uint16 xbdl_buf[6]; -// ETH_MAC target_address[XQ_MAX_FILTERS]; - t_addr rbdl_ba; - t_addr xbdl_ba; + uint32 rbdl_ba; + uint32 xbdl_ba; ETH_DEV* etherface; int receiving; ETH_PACK read_buffer; ETH_PACK write_buffer; struct xq_msg_que ReadQ; - uint8 bootrom[256]; }; +struct xq_controller { + DEVICE* dev; /* device block */ + UNIT* unit; /* unit block */ + DIB* dib; /* device interface block */ + struct xq_device* var; /* controller-specific variables */ +}; + +typedef struct xq_controller CTLR; + + #define XQ_CSR_RI 0x8000 /* Receive Interrupt Request (RI) [RO/W1] */ #define XQ_CSR_PE 0x4000 /* Parity Error in Host Memory (PE) [RO] */ #define XQ_CSR_CA 0x2000 /* Carrier from Receiver Enabled (CA) [RO] */ diff --git a/PDP11/pdp11_xq_bootrom.h b/PDP11/pdp11_xq_bootrom.h new file mode 100644 index 00000000..9a0b954c --- /dev/null +++ b/PDP11/pdp11_xq_bootrom.h @@ -0,0 +1,312 @@ +/* pdp11_xq_bootrom.h: DEQNA/DELQA bootrom data + ------------------------------------------------------------------------------ + + Copyright (c) 2003, David T. Hittner + + 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 + THE AUTHOR 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. + + Except as contained in this notice, the name of the author shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the author. + + ------------------------------------------------------------------------------ + + Modification history: + + 26-Mar-03 DTH Removed 'static' declaration + 23-Mar-03 DTH Created by extracting from merged DEQNA bootrom dumps + + ------------------------------------------------------------------------------ +*/ + +#ifndef _PDP11_XQ_BOOTROM_H +#define _PDP11_XQ_BOOTROM_H + +#ifdef VM_PDP11 + /* + Bootrom code is from merged file 23-334e5.bin, offset 050000, for 4096. bytes. + + Word 0: NOP + Word 1: Branch to extended primary boot + Word 2: Branch/Vector to Citizenship tests + Word 3: Offset from beginning to checksum word + + See INIQNA.MAR for further information on format and contents. + */ + + uint16 xq_bootrom[] = { + 0000240,0000423,0000546,0007776,0000520,0000000,0100000,0100000, + 0002000,0176000,0000000,0000000,0100000,0100000,0006000,0176000, + 0000000,0000000,0100000,0020000,0140000,0012706,0001776,0010046, + 0012761,0000014,0000004,0005061,0000006,0012761,0001010,0000016, + 0005000,0005300,0001376,0005061,0000016,0005000,0005300,0001376, + 0012761,0000002,0000016,0005061,0000016,0042767,0037777,0177664, + 0026767,0177660,0177702,0001057,0042767,0037777,0177652,0026767, + 0177646,0177664,0001050,0042767,0037777,0177650,0026767,0177644, + 0177646,0001041,0012704,0007776,0005003,0005002,0116200,0002000, + 0005202,0042700,0177400,0060003,0005304,0001370,0013700,0000006, + 0026003,0002000,0001020,0000137,0002010,0012702,0012000,0004767, + 0000040,0005700,0001010,0011602,0001002,0000167,0004530,0022702, + 0000777,0103001,0000112,0013703,0000012,0001401,0000113,0000000, + 0000776,0010637,0000764,0062701,0000016,0032761,0100000,0177776, + 0001421,0052761,0020000,0177776,0012703,0000777,0005000,0005300, + 0001376,0032761,0016000,0177776,0001405,0005303,0001370,0012700, + 0000200,0000454,0004767,0000136,0052711,0000002,0042711,0000002, + 0012703,0017777,0005303,0001376,0004567,0003514,0177700,0001014, + 0005712,0001014,0032762,0002000,0000050,0001402,0052711,0002000, + 0004567,0003464,0177622,0001402,0052712,0000100,0012711,0000002, + 0005011,0012703,0017777,0005303,0001376,0011100,0042700,0064000, + 0022700,0010060,0001402,0052712,0000100,0011200,0162701,0000016, + 0000207,0052400,0177652,0013746,0000034,0013746,0000036,0010703, + 0062703,0000210,0010337,0000034,0012737,0000340,0000036,0104400, + 0012637,0000036,0012637,0000034,0013700,0000762,0052700,0000340, + 0062703,0000010,0010337,0000004,0010037,0000006,0010637,0000766, + 0010137,0000772,0010237,0000770,0062703,0000012,0010337,0000024, + 0010037,0000026,0062703,0000022,0012761,0000774,0177776,0052761, + 0100000,0177776,0010337,0000774,0010037,0000776,0005062,0000002, + 0005012,0012700,0000162,0060200,0012704,0000112,0005020,0005304, + 0001375,0004567,0003202,0177666,0001434,0005262,0000002,0022762, + 0000002,0000002,0003355,0000207,0016637,0000002,0000762,0000006, + 0052712,0002000,0013706,0000764,0000207,0052712,0020000,0013706, + 0000766,0013701,0000772,0013702,0000770,0000207,0052712,0004000, + 0000002,0106427,0000000,0010103,0162703,0000016,0010204,0062704, + 0000012,0012705,0000006,0012300,0110024,0005305,0001374,0010204, + 0062704,0000012,0010405,0005724,0001004,0005724,0001002,0005714, + 0001421,0010504,0012700,0177777,0020024,0001016,0020024,0001014, + 0020014,0001410,0001011,0010504,0022724,0000252,0001003,0122714, + 0000004,0103002,0052712,0000001,0012700,0177777,0004767,0003314, + 0013705,0000774,0010703,0062703,0000044,0010337,0000774,0052711, + 0000100,0010461,0177772,0005000,0010061,0177774,0012703,0010000, + 0005303,0001376,0052712,0004000,0000207,0062706,0000004,0010537, + 0000774,0005200,0001767,0011100,0032700,0000200,0001763,0011400, + 0042700,0037777,0022700,0140000,0001355,0005764,0000010,0001752, + 0005764,0000012,0001747,0052711,0000002,0042711,0000002,0012711, + 0002000,0106437,0000762,0004567,0002576,0177666,0001402,0000207, + 0010703,0062703,0177160,0010362,0000002,0010362,0000006,0062703, + 0000005,0010362,0000004,0005062,0000010,0010203,0062703,0000162, + 0012700,0000002,0012705,0000006,0105023,0012704,0000007,0026262, + 0000004,0000006,0003003,0016262,0000002,0000006,0117223,0000006, + 0005262,0000006,0005304,0001363,0005305,0001356,0012704,0000020, + 0105023,0005304,0001375,0005300,0001345,0004567,0002432,0177705, + 0001403,0052712,0000002,0000207,0005262,0000010,0022762,0000764, + 0000010,0003323,0042761,0100000,0177776,0005062,0000006,0010204, + 0062704,0000163,0010462,0000010,0005304,0012703,0000060,0105024, + 0005303,0001375,0062762,0000010,0000002,0016262,0000010,0000002, + 0012762,0000060,0000004,0105062,0000012,0000261,0106162,0000012, + 0103041,0106162,0000012,0062762,0000010,0000002,0000433,0016204, + 0000010,0005304,0012703,0000060,0112724,0000377,0005303,0001374, + 0012762,0000060,0000004,0016262,0000010,0000002,0112762,0000377, + 0000012,0000241,0106162,0000012,0103405,0106162,0000012,0062762, + 0000010,0000002,0016204,0000002,0012703,0000007,0105064,0177770, + 0116224,0000012,0005303,0001372,0004567,0002154,0177750,0001402, + 0000167,0000414,0005762,0000006,0001011,0000241,0106172,0000002, + 0103010,0106072,0000002,0106072,0000002,0000403,0000261,0106172, + 0000002,0016204,0000010,0010203,0062703,0004362,0012700,0000006, + 0111423,0062704,0000010,0005300,0001373,0012711,0000001,0012700, + 0177775,0004767,0002352,0010461,0177766,0005061,0177770,0004767, + 0002372,0010461,0177772,0005061,0177774,0012700,0077777,0032711, + 0100000,0001003,0005300,0001373,0000523,0005000,0004567,0002412, + 0000000,0040000,0001115,0016204,0000010,0005204,0010203,0062703, + 0004362,0012700,0000006,0111423,0062704,0000010,0005300,0001373, + 0042711,0100200,0012700,0177775,0004767,0002224,0010461,0177766, + 0005061,0177770,0012700,0177775,0004767,0002240,0010461,0177772, + 0005061,0177774,0012700,0077777,0032711,0100000,0001003,0005300, + 0001373,0000454,0005000,0004567,0002260,0000000,0000000,0001040, + 0042711,0000001,0010204,0062704,0001362,0010205,0062705,0004362, + 0012700,0000006,0122425,0001024,0005300,0001374,0005362,0000004, + 0001007,0005762,0000006,0001034,0005262,0000006,0000167,0177256, + 0005762,0000006,0001002,0000167,0177222,0000261,0000167,0177304, + 0052712,0000004,0000405,0052712,0004000,0000402,0052712,0001004, + 0052761,0100000,0177776,0000207,0000074,0001422,0002752,0177777, + 0052761,0100000,0177776,0052711,0001000,0010703,0062703,0176046, + 0010362,0000002,0010362,0000006,0062703,0000004,0010362,0000004, + 0010703,0062703,0177726,0010362,0000010,0010203,0062703,0004362, + 0017205,0000010,0026262,0000004,0000006,0003003,0016262,0000002, + 0000006,0117223,0000006,0005262,0000006,0005305,0001363,0017200, + 0000010,0004567,0001536,0103425,0017200,0000010,0004567,0001752, + 0000000,0020000,0001401,0000003,0010204,0062704,0001362,0010205, + 0062705,0004362,0017200,0000010,0122425,0001003,0005300,0001374, + 0000403,0052712,0000010,0000207,0062762,0000002,0000010,0022772, + 0177777,0000010,0001402,0000167,0177620,0012700,0177770,0004767, + 0001536,0010461,0177766,0005061,0177770,0010203,0062703,0000040, + 0010304,0012700,0000010,0012723,0100000,0012723,0100000,0010213, + 0062723,0000012,0012723,0177777,0005023,0005023,0005300,0001363, + 0010403,0052763,0000200,0000002,0052763,0000300,0000016,0012763, + 0177776,0000022,0052763,0000100,0000032,0062763,0000002,0000034, + 0062763,0000004,0000050,0012763,0040000,0000062,0010363,0000064, + 0062763,0000074,0000064,0010363,0000100,0062763,0000070,0000100, + 0012763,0177776,0000102,0012763,0120000,0000112,0012763,0177775, + 0000116,0012763,0020000,0000126,0010461,0177772,0005061,0177774, + 0012700,0077777,0032711,0100000,0001005,0005300,0001373,0052712, + 0001000,0000411,0012700,0000020,0004567,0001376,0100000,0020000, + 0001405,0052712,0040000,0052712,0000020,0000207,0010203,0062703, + 0000040,0012700,0000010,0016305,0000000,0042705,0037777,0022705, + 0140000,0001357,0022700,0000004,0001403,0022700,0000001,0001007, + 0005763,0000010,0001346,0005763,0000012,0001343,0000424,0022700, + 0000002,0001405,0032763,0100000,0000010,0001733,0000414,0016305, + 0000010,0042705,0026417,0022705,0000000,0001323,0016305,0000012, + 0042705,0176000,0001716,0062703,0000014,0005300,0001324,0010203, + 0062703,0000012,0010204,0062704,0001362,0010405,0022324,0001303, + 0022324,0001301,0022324,0001277,0005724,0001275,0005724,0001273, + 0022524,0001271,0022524,0001267,0022524,0001265,0010203,0062703, + 0000162,0010305,0012700,0000113,0005023,0005300,0001375,0010204, + 0062704,0000012,0004767,0000046,0062705,0000020,0004767,0000036, + 0004567,0000444,0177674,0001401,0000207,0012700,0177777,0032711, + 0020000,0001423,0005300,0001373,0052712,0100000,0000207,0010446, + 0012700,0000006,0005205,0012703,0000007,0111425,0005303,0001375, + 0005204,0005300,0001367,0012604,0000207,0005712,0001017,0052711, + 0001400,0012700,0000056,0004767,0000132,0012700,0000074,0004567, + 0000522,0103005,0042712,0001000,0052712,0100000,0000207,0012700, + 0000074,0004767,0000156,0001761,0001403,0052712,0000040,0000207, + 0012700,0000074,0004767,0000232,0001370,0012700,0002734,0004767, + 0000042,0012700,0002752,0004567,0000432,0103757,0012700,0002752, + 0004767,0000100,0001766,0001351,0012700,0002752,0004767,0000162, + 0001344,0000207,0010203,0062703,0004362,0010204,0062704,0000012, + 0010405,0012423,0012423,0012423,0012523,0012523,0012523,0012723, + 0000220,0005023,0012723,0000001,0110023,0005300,0001375,0005062, + 0000002,0000207,0004567,0000542,0000000,0020000,0001004,0062716, + 0000002,0005712,0000207,0016200,0000050,0042700,0137777,0001010, + 0016200,0000030,0032700,0137777,0001003,0042712,0040000,0000757, + 0005262,0000002,0022762,0000144,0000002,0003751,0042712,0040000, + 0000750,0010204,0062704,0001362,0010205,0062705,0004362,0122425, + 0001002,0005300,0001374,0000207,0010200,0062700,0000162,0010046, + 0011500,0005300,0004767,0000270,0010461,0177766,0005061,0177770, + 0012500,0004767,0000306,0012764,0130000,0000002,0011664,0000004, + 0010461,0177772,0005061,0177774,0012704,0017777,0032711,0100000, + 0001010,0005304,0001373,0052712,0001000,0005726,0052712,0010000, + 0000430,0016500,0177776,0006300,0005400,0004567,0000274,0000000, + 0020000,0001363,0016500,0177776,0006300,0005400,0010204,0062704, + 0001362,0012603,0122423,0001352,0005300,0001374,0022714,0051343, + 0001345,0000205,0005046,0006000,0005516,0061600,0005400,0004767, + 0000076,0010461,0177766,0005061,0177770,0004767,0000116,0005726, + 0001403,0052764,0000200,0000002,0010461,0177772,0005061,0177774, + 0012703,0000777,0005000,0032711,0100000,0001010,0005300,0001376, + 0005303,0001371,0052712,0001000,0000261,0000401,0000241,0000205, + 0010203,0062703,0001362,0012704,0000200,0012723,0051343,0005304, + 0001374,0004567,0000020,0000020,0001362,0000207,0004567,0000006, + 0000040,0004362,0000207,0012503,0060203,0010304,0012723,0100000, + 0012723,0120000,0012513,0060223,0010023,0012723,0100000,0012723, + 0100000,0012723,0100000,0005023,0000205,0010046,0005000,0011104, + 0052711,0100200,0042704,0077401,0022704,0100260,0001401,0010700, + 0016204,0000040,0042704,0037777,0022704,0140000,0001401,0010700, + 0016204,0000050,0100002,0042704,0077777,0042704,0076417,0022504, + 0001401,0010700,0016204,0000052,0042704,0176000,0001001,0010700, + 0016204,0000020,0042704,0037777,0022704,0140000,0001401,0010700, + 0016204,0000030,0010446,0042704,0007777,0022504,0001401,0010700, + 0012604,0042704,0174377,0022762,0177775,0000046,0001002,0005726, + 0000415,0032762,0010000,0000042,0001401,0005004,0016203,0000032, + 0042703,0177400,0060304,0022604,0001401,0010700,0010003,0001402, + 0052712,0040000,0000205,0000005,0012706,0017776,0010616,0011646, + 0162716,0003056,0010703,0062703,0000014,0010337,0000004,0011100, + 0000401,0000000,0004767,0000230,0011605,0012725,0022410,0012725, + 0000401,0105025,0105025,0012725,0000621,0112725,0000002,0012702, + 0002752,0110225,0000302,0110225,0012702,0000013,0005000,0004767, + 0000452,0001350,0012702,0002756,0004767,0000660,0001046,0011603, + 0112304,0005302,0120427,0000002,0001404,0105704,0001335,0162702, + 0000004,0105713,0001402,0121300,0001030,0112300,0105200,0005302, + 0003410,0012305,0005723,0162702,0000004,0003403,0112325,0005302, + 0003375,0105704,0001417,0005003,0011605,0112725,0000012,0110025, + 0110325,0005005,0012702,0000003,0000722,0105700,0001673,0012703, + 0000001,0000762,0004767,0001232,0112346,0112366,0000001,0000207, + 0042761,0000002,0000016,0016605,0000002,0010504,0062704,0177720, + 0010466,0000004,0012702,0000020,0005024,0077202,0010504,0062704, + 0177760,0005065,0177722,0010465,0177724,0005065,0177742,0010465, + 0177744,0052765,0100000,0177722,0012702,0002756,0006202,0005402, + 0010265,0177726,0052765,0120000,0177742,0016604,0000004,0010467, + 0001324,0005067,0001322,0062704,0000020,0010467,0001314,0005067, + 0001312,0116167,0000000,0001262,0116167,0000002,0001255,0116167, + 0000004,0001250,0116167,0000006,0001243,0116167,0000010,0001236, + 0116167,0000012,0001231,0105267,0001232,0042761,0000002,0000016, + 0052761,0000400,0000016,0004767,0001104,0005065,0000002,0016744, + 0001174,0016744,0001166,0016744,0001160,0012744,0000000,0012744, + 0001000,0012744,0000253,0004767,0000046,0000207,0016605,0000002, + 0010504,0010244,0012744,0000540,0016744,0001122,0016744,0001114, + 0016744,0001106,0016744,0001060,0016744,0001052,0016744,0001044, + 0062705,0177740,0062702,0000016,0020227,0000074,0002003,0012702, + 0000074,0000407,0032702,0000001,0001404,0052765,0000200,0000002, + 0005202,0006202,0005402,0010265,0000006,0005065,0000010,0005065, + 0000012,0016761,0001024,0000010,0016761,0001020,0000012,0012704, + 0000204,0004767,0000610,0103012,0001404,0032765,0001000,0000010, + 0001354,0042765,0000200,0000002,0000244,0000207,0042765,0000200, + 0000002,0032702,0040004,0001401,0000000,0000207,0016605,0000002, + 0062705,0177720,0005065,0000010,0005065,0000012,0016761,0000706, + 0000004,0016761,0000702,0000006,0052761,0000001,0000016,0012704, + 0100004,0004767,0000470,0103030,0001355,0052761,0000002,0000016, + 0012767,0000253,0000576,0012767,0000400,0000572,0012767,0000000, + 0000566,0105267,0000616,0005000,0042761,0000002,0000016,0052761, + 0000400,0000016,0000244,0000207,0042761,0000001,0000016,0052761, + 0000002,0000016,0016605,0000002,0016502,0177776,0042761,0000002, + 0000016,0052761,0000400,0000016,0022765,0000540,0177774,0001041, + 0105767,0000520,0001015,0026765,0000456,0177772,0001267,0026765, + 0000444,0177770,0001263,0026765,0000432,0177766,0001257,0000207, + 0122715,0000003,0001253,0016567,0177766,0000410,0016567,0177770, + 0000404,0016567,0177772,0000400,0105067,0000430,0000244,0005000, + 0000207,0022765,0000220,0177774,0001423,0022765,0001140,0177774, + 0001225,0122715,0000005,0001222,0004767,0000262,0016464,0177776, + 0177770,0016464,0177774,0177766,0016464,0177772,0177764,0000437, + 0010504,0060204,0010503,0062703,0177720,0016302,0000010,0042702, + 0174377,0156302,0000012,0062702,0000056,0022724,0000002,0001027, + 0062765,0000010,0177776,0032714,0000001,0001021,0010503,0062703, + 0177760,0012423,0012423,0012423,0010504,0062704,0177774,0016744, + 0000234,0016744,0000226,0016744,0000220,0004767,0177122,0000167, + 0177272,0016737,0000156,0000030,0016737,0000152,0000032,0016737, + 0000146,0000034,0052761,0000002,0000016,0000264,0000207,0012703, + 0037777,0000241,0012702,0000220,0030461,0000016,0001006,0005303, + 0001376,0005302,0001371,0000261,0000207,0016102,0000016,0010261, + 0000016,0032765,0040000,0000010,0001401,0000261,0000207,0010546, + 0010703,0062703,0000050,0012702,0000030,0012325,0005725,0112325, + 0005302,0001375,0012605,0010504,0012702,0000034,0010244,0012744, + 0001140,0000207,0000253,0000400,0000000,0000007,0000001,0001403, + 0000000,0000002,0000402,0003400,0003000,0000000,0000000,0000000, + 0000144,0022401,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000, + 0000000,0000000,0000000,0000000,0000000,0000000,0000000,0102206 + }; +#endif /* VM_PDP11 */ + +#endif /* _PDP11_XQ_BOOTROM_H */ diff --git a/PDP11/pdp11_xu.c b/PDP11/pdp11_xu.c index 9c462781..02867c65 100644 --- a/PDP11/pdp11_xu.c +++ b/PDP11/pdp11_xu.c @@ -26,14 +26,16 @@ xu DEUNA/DELUNA Ethernet interface (stub) */ -#if defined (USE_INT64) /* PDP-10 */ +#if defined (VM_PDP10) /* PDP10 version */ #include "pdp10_defs.h" -#define VM_PDP10 1 extern int32 int_req; extern int32 int_vec[32]; -#else -#include "pdp11_defs.h" /* PDP-11 */ -#define VM_PDP11 1 + +#elif defined (VM_VAX) /* VAX version */ +#error "DEUNA/DELUA not supported on VAX!" + +#else /* PDP-11 version */ +#include "pdp11_defs.h" extern int32 int_req[IPL_HLVL]; extern int32 int_vec[IPL_HLVL][32]; #endif diff --git a/PDP18B/pdp18b_cpu.c b/PDP18B/pdp18b_cpu.c index d8cc0844..f8236c5e 100644 --- a/PDP18B/pdp18b_cpu.c +++ b/PDP18B/pdp18b_cpu.c @@ -25,6 +25,7 @@ cpu PDP-4/7/9/15 central processor + 12-Mar-03 RMS Added logical name support 18-Feb-03 RMS Fixed three EAE bugs (found by Hans Pufal) 05-Oct-02 RMS Added DIBs, device number support 25-Jul-02 RMS Added DECtape support for PDP-4 @@ -379,6 +380,7 @@ REG cpu_reg[] = { { ORDATA (SR, SR, 18) }, { ORDATA (IORS, iors, 18), REG_RO }, { BRDATA (INT, int_hwre, 8, 32, API_HLVL+1), REG_RO }, + { FLDATA (INT_PEND, int_pend, 0), REG_RO }, { FLDATA (ION, ion, 0) }, { ORDATA (ION_DELAY, ion_defer, 2) }, #if defined (PDP7) @@ -475,7 +477,7 @@ extern UNIT clk_unit; #define JMS_WORD(t) (((LAC & 01000000) >> 1) | ((memm & 1) << 16) | \ (((t) & 1) << 15) | ((PC) & 077777)) #define INCR_ADDR(x) (((x) & epcmask) | (((x) + 1) & damask)) -#define SEXT(x) ((int) (((x) & 0400000)? (x) | ~0777777: (x) & 0777777)) +#define SEXT(x) ((int32) (((x) & 0400000)? (x) | ~0777777: (x) & 0777777)) /* The following macros implement addressing. They account for autoincrement addressing, extended addressing, and memory protection, if it exists. @@ -881,7 +883,7 @@ case 004: /* JMS, dir */ */ case 031: /* JMP, indir */ -CHECK_AUTO_INC; /* check auto inc */ + CHECK_AUTO_INC; /* check auto inc */ #if defined (PDP7) || defined (PDP9) if (emir_pending && (((M[MA] >> 16) & 1) == 0)) memm = 0; #endif @@ -1496,7 +1498,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) return SCPE_ARG; @@ -1542,7 +1544,7 @@ if (dptr == NULL) return SCPE_IERR; dibp = (DIB *) dptr->ctxt; if (dibp == NULL) return SCPE_IERR; fprintf (st, "devno=%02o", dibp->dev); -if (dibp-> num > 1) fprintf (st, "-%2o", dibp->dev + dibp->num - 1); +if (dibp->num > 1) fprintf (st, "-%2o", dibp->dev + dibp->num - 1); return SCPE_OK; } @@ -1582,10 +1584,10 @@ for (i = p = 0; (dptr = sim_devices[i]) != NULL; i++) { /* add devices */ if (dibp->dsp[j]) { /* any dispatch? */ if (dev_tab[dibp->dev + j]) { /* already filled? */ printf ("%s device number conflict at %02o\n", - dptr->name, dibp->dev + j); + sim_dname (dptr), dibp->dev + j); if (sim_log) fprintf (sim_log, "%s device number conflict at %02o\n", - dptr->name, dibp->dev + j); + sim_dname (dptr), dibp->dev + j); return TRUE; } dev_tab[dibp->dev + j] = dibp->dsp[j]; /* fill */ } /* end if dsp */ diff --git a/PDP18B/pdp18b_defs.h b/PDP18B/pdp18b_defs.h index 45ccff77..ee058761 100644 --- a/PDP18B/pdp18b_defs.h +++ b/PDP18B/pdp18b_defs.h @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 25-Apr-03 RMS Revised for extended file support 04-Feb-03 RMS Added RB09, LP09 support 22-Nov-02 RMS Added PDP-4 drum support 05-Oct-02 RMS Added DIB structure @@ -144,7 +145,7 @@ #define BLKMASK (ADDRMASK & (~IAMASK)) /* block mask */ #define MAXMEMSIZE (1 << ADDRSIZE) /* max memory size */ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) /* Architectural constants */ diff --git a/PDP18B/pdp18b_drm.c b/PDP18B/pdp18b_drm.c index d65c2887..fd882a67 100644 --- a/PDP18B/pdp18b_drm.c +++ b/PDP18B/pdp18b_drm.c @@ -1,6 +1,6 @@ /* pdp18b_drm.c: drum/fixed head disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -164,7 +164,7 @@ return AC; t_stat drm_svc (UNIT *uptr) { int32 i; -t_addr da; +uint32 da; if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ drm_err = 1; /* set error */ diff --git a/PDP18B/pdp18b_dt.c b/PDP18B/pdp18b_dt.c index 5a7f3956..8224ad5a 100644 --- a/PDP18B/pdp18b_dt.c +++ b/PDP18B/pdp18b_dt.c @@ -1,6 +1,6 @@ /* pdp18b_dt.c: 18b DECtape simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -27,6 +27,8 @@ (PDP-9) TC02/TU55 DECtape (PDP-15) TC15/TU56 DECtape + 25-Apr-03 RMS Revised for extended file support + 14-Mar-03 RMS Fixed variable size interaction with save/restore 17-Oct-02 RMS Fixed bug in end of reel logic 05-Oct-02 RMS Added DIB, device number support 12-Sep-02 RMS Added 16b format support @@ -393,11 +395,11 @@ REG dt_reg[] = { { ORDATA (SUBSTATE, dt_substate, 2) }, { ORDATA (LOG, dt_log, 4), REG_HIDDEN }, { DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN }, - { URDATA (POS, dt_unit[0].pos, 10, 32, 0, + { URDATA (POS, dt_unit[0].pos, 10, T_ADDR_W, 0, DT_NUMDR, PV_LEFT | REG_RO) }, { URDATA (STATT, dt_unit[0].STATE, 8, 18, 0, DT_NUMDR, REG_RO) }, - { URDATA (LASTT, dt_unit[0].LASTT, 10, 32, 0, + { URDATA (LASTT, dt_unit[0].LASTT, 10, T_ADDR_W, 0, DT_NUMDR, REG_HRO) }, { ORDATA (DEVNO, dt_dib.dev, 6), REG_HRO }, { NULL } }; @@ -760,7 +762,7 @@ if (((int32) uptr->pos < 0) || uptr->STATE = uptr->pos = 0; unum = uptr - dt_dev.units; if (unum == DTA_GETUNIT (dtsa)) /* if selected, */ - dt_seterr (uptr, DTB_SEL); /* error */ + dt_seterr (uptr, DTB_SEL); /* error */ return TRUE; } return FALSE; } @@ -778,7 +780,7 @@ int32 fnc = DTS_GETFNC (uptr->STATE); int32 *bptr = uptr->filebuf; int32 unum = uptr - dt_dev.units; int32 blk, wrd, ma, relpos; -t_addr ba; +uint32 ba; /* Motion cases @@ -1221,33 +1223,35 @@ t_stat dt_attach (UNIT *uptr, char *cptr) { uint16 pdp8b[D8_NBSIZE]; uint16 pdp11b[D18_BSIZE]; -uint32 k, p, *bptr; +uint32 ba, sz, k, *bptr; +int32 u = uptr - dt_dev.units; t_stat r; -t_addr ba; r = attach_unit (uptr, cptr); /* attach */ if (r != SCPE_OK) return r; /* error? */ -uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */ -if (sim_switches & SWMASK ('R')) /* att 12b? */ - uptr->flags = uptr->flags | UNIT_8FMT; -else if (sim_switches & SWMASK ('S')) /* att 16b? */ - uptr->flags = uptr->flags | UNIT_11FMT; -else if (!(sim_switches & SWMASK ('T')) && /* autosize? */ - (fseek (uptr->fileref, 0, SEEK_END) == 0) && - ((p = ftell (uptr->fileref)) != 0)) { - if (p == D8_FILSIZ) uptr->flags = uptr->flags | UNIT_8FMT; - if (p == D11_FILSIZ) uptr->flags = uptr->flags | UNIT_11FMT; } +if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */ + uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */ + if (sim_switches & SWMASK ('R')) /* att 12b? */ + uptr->flags = uptr->flags | UNIT_8FMT; + else if (sim_switches & SWMASK ('S')) /* att 16b? */ + uptr->flags = uptr->flags | UNIT_11FMT; + else if (!(sim_switches & SWMASK ('T')) && /* autosize? */ + (sz = sim_fsize (cptr))) { + if (sz == D8_FILSIZ) + uptr->flags = uptr->flags | UNIT_8FMT; + else if (sz == D11_FILSIZ) + uptr->flags = uptr->flags | UNIT_11FMT; } } uptr->capac = DTU_CAPAC (uptr); /* set capacity */ uptr->filebuf = calloc (uptr->capac, sizeof (int32)); if (uptr->filebuf == NULL) { /* can't alloc? */ detach_unit (uptr); return SCPE_MEM; } bptr = uptr->filebuf; /* file buffer */ -if (uptr->flags & UNIT_8FMT) printf ("DT: 12b format"); -else if (uptr->flags & UNIT_11FMT) printf ("DT: 16b format"); -else printf ("DT: 18b/36b format"); +printf ("%s%d: ", sim_dname (&dt_dev), u); +if (uptr->flags & UNIT_8FMT) printf ("12b format"); +else if (uptr->flags & UNIT_11FMT) printf ("16b format"); +else printf ("18b/36b format"); printf (", buffering file in memory\n"); -rewind (uptr->fileref); /* start of file */ if (uptr->flags & UNIT_8FMT) { /* 12b? */ for (ba = 0; ba < uptr->capac; ) { /* loop thru file */ k = fxread (pdp8b, sizeof (int16), D8_NBSIZE, uptr->fileref); @@ -1290,20 +1294,19 @@ t_stat dt_detach (UNIT* uptr) { uint16 pdp8b[D8_NBSIZE]; uint16 pdp11b[D18_BSIZE]; -uint32 k, *bptr; -int32 unum = uptr - dt_dev.units; -t_addr ba; +uint32 ba, k, *bptr; +int32 u = uptr - dt_dev.units; if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; if (sim_is_active (uptr)) { sim_cancel (uptr); - if ((unum == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) { + if ((u == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) { dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF; DT_UPDINT; } uptr->STATE = uptr->pos = 0; } bptr = uptr->filebuf; /* file buffer */ if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */ - printf ("DT: writing buffer to file\n"); + printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u); rewind (uptr->fileref); /* start of file */ if (uptr->flags & UNIT_8FMT) { /* 12b? */ for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */ diff --git a/PDP18B/pdp18b_lp.c b/PDP18B/pdp18b_lp.c index 030a41f9..c8ca5053 100644 --- a/PDP18B/pdp18b_lp.c +++ b/PDP18B/pdp18b_lp.c @@ -28,6 +28,7 @@ lp09 (PDP-9,15) LP09 line printer lp15 (PDP-15) LP15 line printer + 25-Apr-03 RMS Revised for extended file support 05-Feb-03 RMS Added LP09, fixed conditionalization 05-Oct-02 RMS Added DIB, device number support 30-May-02 RMS Widened POS to 32b @@ -97,7 +98,7 @@ REG lp62_reg[] = { { FLDATA (SPC, int_hwre[API_LPTSPC], INT_V_LPTSPC) }, { DRDATA (BPTR, lp62_bp, 6) }, { ORDATA (STATE, lp62_iot, 6), REG_HRO }, - { DRDATA (POS, lp62_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lp62_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lp62_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lp62_stopioe, 0) }, { BRDATA (LBUF, lp62_buf, 8, 8, LP62_BSIZE) }, @@ -264,7 +265,7 @@ REG lp647_reg[] = { { FLDATA (ERR, lp647_err, 0) }, { DRDATA (BPTR, lp647_bp, 7) }, { ORDATA (SCMD, lp647_iot, 6), REG_HRO }, - { DRDATA (POS, lp647_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lp647_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lp647_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lp647_stopioe, 0) }, { BRDATA (LBUF, lp647_buf, 8, 8, LP647_BSIZE) }, @@ -466,7 +467,7 @@ REG lp09_reg[] = { { FLDATA (DONE, lp09_don, 0) }, { FLDATA (ENABLE, lp09_ie, 0) }, { FLDATA (ERR, lp09_err, 0) }, - { DRDATA (POS, lp09_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lp09_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lp09_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lp09_stopioe, 0) }, { ORDATA (DEVNO, lp09_dib.dev, 6), REG_HRO }, @@ -635,7 +636,7 @@ REG lp15_reg[] = { { DRDATA (LCNT, lp15_lc, 9) }, { DRDATA (BPTR, lp15_bp, 8) }, { FLDATA (MODE, lp15_mode, 0) }, - { DRDATA (POS, lp15_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lp15_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lp15_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lp15_stopioe, 0) }, { BRDATA (LBUF, lp15_buf, 8, 8, LP15_BSIZE) }, diff --git a/PDP18B/pdp18b_mt.c b/PDP18B/pdp18b_mt.c index 0b2ea977..ae2c1ddf 100644 --- a/PDP18B/pdp18b_mt.c +++ b/PDP18B/pdp18b_mt.c @@ -26,6 +26,9 @@ mt (PDP-9) TC59 magtape (PDP-15) TC59D magtape + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support + 04-Mar-03 RMS Fixed bug in MTTR 01-Mar-03 RMS Fixed bug in interrupt handling Revised for magtape library 02-Feb-03 RMS Revised IOT decoding @@ -124,6 +127,7 @@ int32 mt_cu = 0; /* command/unit */ int32 mt_sta = 0; /* status register */ int32 mt_time = 10; /* record latency */ int32 mt_stopioe = 1; /* stop on error */ +int32 mt_log = 0; uint8 *mtxb = NULL; /* transfer buffer */ DEVICE mt_dev; @@ -166,15 +170,19 @@ REG mt_reg[] = { { FLDATA (STOP_IOE, mt_stopioe, 0) }, { DRDATA (TIME, mt_time, 24), PV_LEFT }, { URDATA (UST, mt_unit[0].USTAT, 8, 16, 0, MT_NUMDR, 0) }, - { URDATA (POS, mt_unit[0].pos, 10, 32, 0, + { URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0, MT_NUMDR, PV_LEFT | REG_RO) }, + { FLDATA (LOG, mt_log, 0), REG_HIDDEN }, { ORDATA (DEVNO, mt_dib.dev, 6), REG_HRO }, { NULL } }; MTAB mt_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, + { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", + &set_devno, &show_devno, NULL }, { 0 } }; DEVICE mt_dev = { @@ -195,13 +203,17 @@ uptr = mt_dev.units + GET_UNIT (mt_cu); /* get unit */ mt_updcsta (uptr, 0); /* update status */ sb = pulse & 060; /* subop */ if (pulse & 01) { - if ((sb == 000) && !sim_is_active (uptr)) /* MTTR */ + if ((sb == 000) && (uptr->flags & UNIT_ATT) && /* MTTR */ + !sim_is_active (uptr)) AC = IOT_SKP | AC; else if ((sb == 020) && !mt_busy ()) /* MTCR */ AC = IOT_SKP | AC; else if ((sb == 040) && (mt_sta & (STA_ERR | STA_DON))) /* MTSF */ AC = IOT_SKP | AC; } +if ((pulse & 06) && mt_log) + printf ("[MT%d: IOT=%o, AC=%o, sta=%o]\n", + GET_UNIT (mt_cu), 0707300 + pulse, AC, mt_sta); if (pulse & 02) { if (sb == 000) AC = AC | (mt_cu & 0777700); /* MTRC */ else if (sb == 020) { /* MTAF, MTLC */ @@ -252,6 +264,7 @@ if (uptr->USTAT & STA_REW) { /* rewind? */ if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_BOT; else uptr->USTAT = 0; if (u == GET_UNIT (mt_cu)) mt_updcsta (uptr, STA_DON); + if (mt_log) printf ("[MT%d: rewind complete, sta=%o]\n", u, mt_sta); return SCPE_OK; } if ((uptr->flags & UNIT_ATT) == 0) { /* if not attached */ @@ -345,6 +358,8 @@ case FN_SPACER: /* space reverse */ break; } /* end case */ mt_updcsta (uptr, STA_DON); /* set done */ +if (mt_log) printf ("MT%d: fnc=%d done, ma=%o, wc=%o, sta=%o]\n", + u, f, M[MT_CA], M[MT_WC], mt_sta); return r; } @@ -399,7 +414,7 @@ case MTSE_RECE: /* record in error */ mt_sta = mt_sta | STA_PAR | STA_ERR; /* set par err */ break; case MTSE_EOM: /* end of medium */ - mt_sta = mt_sta | STA_BAD | STA_ERR; /* set bad tape */ + mt_sta = mt_sta | STA_BAD | STA_ERR; /* set end tape */ break; case MTSE_BOT: /* reverse into BOT */ uptr->USTAT = uptr->USTAT | STA_BOT; /* set status */ diff --git a/PDP18B/pdp18b_rf.c b/PDP18B/pdp18b_rf.c index f81c1bbb..8636679e 100644 --- a/PDP18B/pdp18b_rf.c +++ b/PDP18B/pdp18b_rf.c @@ -26,6 +26,7 @@ rf (PDP-9) RF09/RF09 (PDP-15) RF15/RS09 + 14-Mar-03 RMS Fixed variable platter interaction with save/restore 03-Mar-03 RMS Fixed autosizing 12-Feb-03 RMS Removed 8 platter sizing hack 05-Feb-03 RMS Fixed decode bugs, added variable and autosizing @@ -54,6 +55,7 @@ #define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */ #define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */ #define UNIT_M_PLAT 07 +#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT) #define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1) #define UNIT_AUTO (1 << UNIT_V_AUTO) #define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT) @@ -144,6 +146,7 @@ REG rf_reg[] = { { DRDATA (TIME, rf_time, 24), PV_LEFT + REG_NZ }, { FLDATA (BURST, rf_burst, 0) }, { FLDATA (STOP_IOE, rf_stopioe, 0) }, + { DRDATA (CAPAC, rf_unit.capac, 31), PV_LEFT + REG_HRO }, { ORDATA (DEVNO, rf_dib.dev, 6), REG_HRO }, { NULL } }; @@ -205,7 +208,7 @@ if (pulse & 04) { sim_activate (&rf_unit, t * rf_time); } } /* schedule op */ else if (sb == 060) { /* DLAH */ rf_da = (rf_da & 0777777) | ((AC & 07) << 18); - if ((t_addr) rf_da >= rf_unit.capac) /* for sizing */ + if ((uint32) rf_da >= rf_unit.capac) /* for sizing */ rf_updsta (RFS_NED); } } rf_updsta (0); /* update status */ @@ -241,7 +244,7 @@ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ return IORETURN (rf_stopioe, SCPE_UNATT); } f = GET_FNC (rf_sta); /* get function */ -do { if ((t_addr) rf_da >= uptr->capac) { /* disk overflow? */ +do { if ((uint32) rf_da >= uptr->capac) { /* disk overflow? */ rf_updsta (RFS_NED); /* nx disk error */ break; } M[RF_WC] = (M[RF_WC] + 1) & 0777777; /* incr word count */ @@ -260,7 +263,7 @@ do { if ((t_addr) rf_da >= uptr->capac) { /* disk overflow? */ break; } else { *(((int32 *) uptr->filebuf) + rf_da) = M[pa]; - if (((t_addr) rf_da) >= uptr->hwmark) uptr->hwmark = rf_da + 1; } } + if (((uint32) rf_da) >= uptr->hwmark) uptr->hwmark = rf_da + 1; } } rf_da = rf_da + 1; /* incr disk addr */ } while ((M[RF_WC] != 0) && (rf_burst != 0)); /* brk if wc, no brst */ @@ -304,15 +307,15 @@ return ((rf_sta & (RFS_ERR | RFS_DON))? IOS_RF: 0); t_stat rf_attach (UNIT *uptr, char *cptr) { -t_addr p, sz; -t_addr ds_bytes = RF_DKSIZE * sizeof (int32); +uint32 p, sz; +uint32 ds_bytes = RF_DKSIZE * sizeof (int32); if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) { p = (sz + ds_bytes - 1) / ds_bytes; - if (p == 0) p = 1; - if (p > RF_NUMDK) p = RF_NUMDK; } -else p = UNIT_GETP (uptr->flags); -uptr->capac = p * RF_DKSIZE; + if (p >= RF_NUMDK) p = RF_NUMDK - 1; + uptr->flags = (uptr->flags & ~UNIT_PLAT) | + (p << UNIT_V_PLAT); } +uptr->capac = UNIT_GETP (uptr->flags) * RF_DKSIZE; return attach_unit (uptr, cptr); } diff --git a/PDP18B/pdp18b_rp.c b/PDP18B/pdp18b_rp.c index f8fdd57e..281a52d1 100644 --- a/PDP18B/pdp18b_rp.c +++ b/PDP18B/pdp18b_rp.c @@ -345,7 +345,7 @@ if (rp_sta & (STA_NXS | STA_NXF | STA_NXC)) { /* or bad disk addr? */ pa = rp_ma & ADDRMASK; /* get mem addr */ da = GET_DA (rp_da) * RP_NUMWD; /* get disk addr */ wc = 01000000 - rp_wc; /* get true wc */ -if (((t_addr) (pa + wc)) > MEMSIZE) { /* memory overrun? */ +if (((uint32) (pa + wc)) > MEMSIZE) { /* memory overrun? */ nexm = 1; /* set nexm flag */ wc = MEMSIZE - pa; } /* limit xfer */ if ((da + wc) > RP_SIZE) { /* disk overrun? */ diff --git a/PDP18B/pdp18b_stddev.c b/PDP18B/pdp18b_stddev.c index 3f2d2c0e..73c24f46 100644 --- a/PDP18B/pdp18b_stddev.c +++ b/PDP18B/pdp18b_stddev.c @@ -29,6 +29,8 @@ tto teleprinter clk clock + 25-Apr-03 RMS Revised for extended file support + 14-Mar-03 RMS Clean up flags on detach 01-Mar-03 RMS Added SET/SHOW CLK FREQ support, SET TTI CTRL-C support 22-Dec-02 RMS Added break support 01-Nov-02 RMS Added 7B/8B support to terminal @@ -160,7 +162,7 @@ REG ptr_reg[] = { { FLDATA (ERR, ptr_err, 0) }, #endif { ORDATA (STATE, ptr_state, 5), REG_HRO }, - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptr_stopioe, 0) }, { NULL } }; @@ -195,7 +197,7 @@ REG ptp_reg[] = { #if defined (IOS_PTPERR) { FLDATA (ERR, ptp_err, 0) }, #endif - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptp_stopioe, 0) }, { NULL } }; @@ -272,7 +274,7 @@ REG tti_reg[] = { #if defined (KSR28) { ORDATA (TTI_STATE, tti_state, (TTI_WIDTH + 3)), REG_HRO }, #endif - { DRDATA (POS, tti_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; @@ -334,7 +336,7 @@ REG tto_reg[] = { #if defined (KSR28) { FLDATA (TTO_STATE, tto_state, 0), REG_HRO }, #endif - { DRDATA (POS, tto_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT }, { NULL } }; @@ -520,6 +522,7 @@ return reason; t_stat ptr_detach (UNIT *uptr) { ptr_err = 1; +ptr_unit.flags = ptr_unit.flags & ~UNIT_RASCII; return detach_unit (uptr); } @@ -773,6 +776,7 @@ return reason; t_stat ptp_detach (UNIT *uptr) { ptp_err = 1; +ptp_unit.flags = ptp_unit.flags & ~UNIT_PASCII; return detach_unit (uptr); } diff --git a/PDP18B/pdp18b_tt1.c b/PDP18B/pdp18b_tt1.c index 49e33321..5a3912c0 100644 --- a/PDP18B/pdp18b_tt1.c +++ b/PDP18B/pdp18b_tt1.c @@ -1,6 +1,6 @@ /* pdp18b_tt1.c: 18b PDP's second Teletype - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,7 @@ tti1 keyboard tto1 teleprinter + 09-May-03 RMS Added network device flag 22-Dec-02 RMS Added break support 02-Nov-02 RMS Added 7B/8B support 05-Oct-02 RMS Added DIB, device number support @@ -110,7 +111,7 @@ DEVICE tti1_dev = { 1, 10, 31, 1, 8, 8, &tmxr_ex, &tmxr_dep, &tti1_reset, NULL, &tti1_attach, &tti1_detach, - &tti1_dib, DEV_DISABLE }; + &tti1_dib, DEV_NET | DEV_DISABLE }; /* TTO1 data structures diff --git a/PDP8/pdp8_cpu.c b/PDP8/pdp8_cpu.c index 6f33d562..dbada524 100644 --- a/PDP8/pdp8_cpu.c +++ b/PDP8/pdp8_cpu.c @@ -1,6 +1,6 @@ /* pdp8_cpu.c: PDP-8 CPU simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ cpu central processor + 12-Mar-03 RMS Added logical name support 04-Oct-02 RMS Revamped device dispatching, added device number support 06-Jan-02 RMS Added device enable/disable routines 30-Dec-01 RMS Added old PC queue @@ -286,7 +287,7 @@ DEVICE cpu_dev = { t_stat sim_instr (void) { int32 IR, MB, IF, DF, LAC, MQ; -t_addr PC, MA; +uint32 PC, MA; int32 device, pulse, temp, iot_data; t_stat reason; @@ -739,7 +740,7 @@ case 036:case 037: /* OPR, groups 2, 3 */ case 020: /* mode A, B: SCA */ LAC = LAC | SC; break; - case 0: /* mode A, B: NOP */ + case 000: /* mode A, B: NOP */ break; case 021: /* mode B: DAD */ if (emode) { @@ -752,13 +753,13 @@ case 036:case 037: /* OPR, groups 2, 3 */ PC = (PC + 1) & 07777; break; } LAC = LAC | SC; /* mode A: SCA then */ - case 1: /* mode B: ACS */ + case 001: /* mode B: ACS */ if (emode) { SC = LAC & 037; - LAC = LAC & 010000; - break; } - SC = (~M[IF | PC]) & 037; /* mode A: SCL */ - PC = (PC + 1) & 07777; + LAC = LAC & 010000; } + else { /* mode A: SCL */ + SC = (~M[IF | PC]) & 037; + PC = (PC + 1) & 07777; } break; case 022: /* mode B: DST */ if (emode) { @@ -770,7 +771,7 @@ case 036:case 037: /* OPR, groups 2, 3 */ PC = (PC + 1) & 07777; break; } LAC = LAC | SC; /* mode A: SCA then */ - case 2: /* MUY */ + case 002: /* MUY */ MA = IF | PC; if (emode) { INDIRECT; } /* mode B: defer */ temp = (MQ * M[MA]) + (LAC & 07777); @@ -785,7 +786,7 @@ case 036:case 037: /* OPR, groups 2, 3 */ case 023: /* mode B: SWBA */ if (emode) break; LAC = LAC | SC; /* mode A: SCA then */ - case 3: /* DVI */ + case 003: /* DVI */ MA = IF | PC; if (emode) { INDIRECT; } /* mode B: defer */ if ((LAC & 07777) >= M[MA]) { /* overflow? */ @@ -804,7 +805,7 @@ case 036:case 037: /* OPR, groups 2, 3 */ if (((LAC | MQ) & 07777) == 0) PC = (PC + 1) & 07777; break; } LAC = LAC | SC; /* mode A: SCA then */ - case 4: /* NMI */ + case 004: /* NMI */ temp = (LAC << 12) | MQ; /* preserve link */ for (SC = 0; ((temp & 017777777) != 0) && (temp & 040000000) == ((temp << 1) & 040000000); SC++) @@ -1053,7 +1054,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) return SCPE_ARG; @@ -1099,7 +1100,7 @@ if (dptr == NULL) return SCPE_IERR; dibp = (DIB *) dptr->ctxt; if (dibp == NULL) return SCPE_IERR; fprintf (st, "devno=%02o", dibp->dev); -if (dibp-> num > 1) fprintf (st, "-%2o", dibp->dev + dibp->num - 1); +if (dibp->num > 1) fprintf (st, "-%2o", dibp->dev + dibp->num - 1); return SCPE_OK; } @@ -1130,10 +1131,10 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* add devices */ if (dibp->dsp[j]) { /* any dispatch? */ if (dev_tab[dibp->dev + j]) { /* already filled? */ printf ("%s device number conflict at %02o\n", - dptr->name, dibp->dev + j); + sim_dname (dptr), dibp->dev + j); if (sim_log) fprintf (sim_log, "%s device number conflict at %02o\n", - dptr->name, dibp->dev + j); + sim_dname (dptr), dibp->dev + j); return TRUE; } dev_tab[dibp->dev + j] = dibp->dsp[j]; /* fill */ } /* end if dsp */ diff --git a/PDP8/pdp8_defs.h b/PDP8/pdp8_defs.h index 88eb99d8..74c9fed7 100644 --- a/PDP8/pdp8_defs.h +++ b/PDP8/pdp8_defs.h @@ -1,6 +1,6 @@ /* pdp8_defs.h: PDP-8 simulator definitions - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -51,7 +51,7 @@ #define MAXMEMSIZE 32768 /* max memory size */ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ #define ADDRMASK (MAXMEMSIZE - 1) /* address mask */ -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) /* IOT subroutine return codes */ diff --git a/PDP8/pdp8_df.c b/PDP8/pdp8_df.c index 35237cf3..190ecd4c 100644 --- a/PDP8/pdp8_df.c +++ b/PDP8/pdp8_df.c @@ -25,6 +25,7 @@ df DF32 fixed head disk + 14-Mar-03 RMS Fixed variable platter interaction with save/restore 03-Mar-03 RMS Fixed autosizing 02-Feb-03 RMS Added variable platter and autosizing support 04-Oct-02 RMS Added DIBs, device number support @@ -47,6 +48,7 @@ #define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */ #define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */ #define UNIT_M_PLAT 03 +#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT) #define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1) #define UNIT_AUTO (1 << UNIT_V_AUTO) #define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT) @@ -121,8 +123,8 @@ t_stat df_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); DIB df_dib = { DEV_DF, 3, { &df60, &df61, &df62 } }; UNIT df_unit = - { UDATA (&df_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, - DF_DKSIZE) }; + { UDATA (&df_svc, UNIT_FIX+UNIT_ATTABLE+ + UNIT_BUFABLE+UNIT_MUSTBUF, DF_DKSIZE) }; REG df_reg[] = { { ORDATA (STA, df_sta, 12) }, @@ -135,6 +137,7 @@ REG df_reg[] = { { DRDATA (TIME, df_time, 24), REG_NZ + PV_LEFT }, { FLDATA (BURST, df_burst, 0) }, { FLDATA (STOP_IOE, df_stopioe, 0) }, + { DRDATA (CAPAC, df_unit.capac, 18), REG_HRO }, { ORDATA (DEVNUM, df_dib.dev, 6), REG_HRO }, { NULL } }; @@ -226,7 +229,7 @@ return AC; t_stat df_svc (UNIT *uptr) { int32 pa, t, mex; -t_addr da; +uint32 da; UPDATE_PCELL; /* update photocell */ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ @@ -315,18 +318,19 @@ else { for (i = 0; i < OS8_LEN; i++) return SCPE_OK; } +/* Attach routine */ t_stat df_attach (UNIT *uptr, char *cptr) { -t_addr p, sz; -t_addr ds_bytes = DF_DKSIZE * sizeof (int16); +uint32 p, sz; +uint32 ds_bytes = DF_DKSIZE * sizeof (int16); if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) { p = (sz + ds_bytes - 1) / ds_bytes; - if (p == 0) p = 1; - if (p > DF_NUMDK) p = DF_NUMDK; } -else p = UNIT_GETP (uptr->flags); -uptr->capac = p * DF_DKSIZE; + if (p >= DF_NUMDK) p = DF_NUMDK - 1; + uptr->flags = (uptr->flags & ~UNIT_PLAT) | + (p << UNIT_V_PLAT); } +uptr->capac = UNIT_GETP (uptr->flags) * DF_DKSIZE; return attach_unit (uptr, cptr); } diff --git a/PDP8/pdp8_dt.c b/PDP8/pdp8_dt.c index 0bb1f2fe..f2c62316 100644 --- a/PDP8/pdp8_dt.c +++ b/PDP8/pdp8_dt.c @@ -1,6 +1,6 @@ /* pdp8_dt.c: PDP-8 DECtape simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ dt TC08/TU56 DECtape + 25-Apr-03 RMS Revised for extended file support + 14-Mar-03 RMS Fixed sizing interaction with save/restore 17-Oct-02 RMS Fixed bug in end of reel logic 04-Oct-02 RMS Added DIB, device number support 12-Sep-02 RMS Added support for 16b format @@ -323,7 +325,7 @@ REG dt_reg[] = { { ORDATA (SUBSTATE, dt_substate, 2) }, { ORDATA (LOG, dt_log, 4), REG_HIDDEN }, { DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN }, - { URDATA (POS, dt_unit[0].pos, 10, 32, 0, + { URDATA (POS, dt_unit[0].pos, 10, T_ADDR_W, 0, DT_NUMDR, PV_LEFT | REG_RO) }, { URDATA (STATT, dt_unit[0].STATE, 8, 18, 0, DT_NUMDR, REG_RO) }, @@ -614,7 +616,7 @@ if (((int32) uptr->pos < 0) || uptr->STATE = uptr->pos = 0; unum = uptr - dt_dev.units; if (unum == DTA_GETUNIT (dtsa)) /* if selected, */ - dt_seterr (uptr, DTB_SEL); /* error */ + dt_seterr (uptr, DTB_SEL); /* error */ return TRUE; } return FALSE; } @@ -632,7 +634,7 @@ int32 fnc = DTS_GETFNC (uptr->STATE); int16 *bptr = uptr->filebuf; int32 unum = uptr - dt_dev.units; int32 blk, wrd, ma, relpos, dat; -t_addr ba; +uint32 ba; /* Motion cases @@ -1060,34 +1062,36 @@ t_stat dt_attach (UNIT *uptr, char *cptr) { uint32 pdp18b[D18_NBSIZE]; uint16 pdp11b[D18_NBSIZE], *bptr; -int32 i, k, p; +int32 i, k; +int32 u = uptr - dt_dev.units; t_stat r; -t_addr ba; +uint32 ba, sz; r = attach_unit (uptr, cptr); /* attach */ if (r != SCPE_OK) return r; /* fail? */ -uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT; -if (sim_switches & SWMASK ('T')) /* att 18b? */ - uptr->flags = uptr->flags & ~UNIT_8FMT; -else if (sim_switches & SWMASK ('S')) /* att 16b? */ - uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; -else if (!(sim_switches & SWMASK ('R')) && /* autosize? */ - (fseek (uptr->fileref, 0, SEEK_END) == 0) && - ((p = ftell (uptr->fileref)) > 0)) { - if (p == D11_FILSIZ) - uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; - if (p > D8_FILSIZ) uptr->flags = uptr->flags & ~UNIT_8FMT; } +if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */ + uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT; + if (sim_switches & SWMASK ('T')) /* att 18b? */ + uptr->flags = uptr->flags & ~UNIT_8FMT; + else if (sim_switches & SWMASK ('S')) /* att 16b? */ + uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; + else if (!(sim_switches & SWMASK ('R')) && /* autosize? */ + (sz = sim_fsize (cptr))) { + if (sz == D11_FILSIZ) + uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; + else if (sz > D8_FILSIZ) + uptr->flags = uptr->flags & ~UNIT_8FMT; } } uptr->capac = DTU_CAPAC (uptr); /* set capacity */ uptr->filebuf = calloc (uptr->capac, sizeof (int16)); if (uptr->filebuf == NULL) { /* can't alloc? */ detach_unit (uptr); return SCPE_MEM; } bptr = uptr->filebuf; /* file buffer */ -if (uptr->flags & UNIT_8FMT) printf ("DT: 12b format"); -else if (uptr->flags & UNIT_11FMT) printf ("DT: 16b format"); -else printf ("DT: 18b/36b format"); +printf ("%s%d: ", sim_dname (&dt_dev), u); +if (uptr->flags & UNIT_8FMT) printf ("12b format"); +else if (uptr->flags & UNIT_11FMT) printf ("16b format"); +else printf ("18b/36b format"); printf (", buffering file in memory\n"); -rewind (uptr->fileref); /* start of file */ if (uptr->flags & UNIT_8FMT) /* 12b? */ uptr->hwmark = fxread (uptr->filebuf, sizeof (int16), uptr->capac, uptr->fileref); @@ -1126,19 +1130,19 @@ t_stat dt_detach (UNIT* uptr) uint32 pdp18b[D18_NBSIZE]; uint16 pdp11b[D18_NBSIZE], *bptr; int32 i, k; -int32 unum = uptr - dt_dev.units; -t_addr ba; +int32 u = uptr - dt_dev.units; +uint32 ba; if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; if (sim_is_active (uptr)) { sim_cancel (uptr); - if ((unum == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) { + if ((u == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) { dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF; DT_UPDINT; } uptr->STATE = uptr->pos = 0; } bptr = uptr->filebuf; /* file buffer */ if (uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any data? */ - printf ("DT: writing buffer to file\n"); + printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u); rewind (uptr->fileref); /* start of file */ if (uptr->flags & UNIT_8FMT) /* PDP8? */ fxwrite (uptr->filebuf, sizeof (int16), /* write file */ diff --git a/PDP8/pdp8_lp.c b/PDP8/pdp8_lp.c index b88d4b7a..48bda59f 100644 --- a/PDP8/pdp8_lp.c +++ b/PDP8/pdp8_lp.c @@ -1,6 +1,6 @@ /* pdp8_lp.c: PDP-8 line printer simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ lpt LP8E line printer + 25-Apr-03 RMS Revised for extended file support 04-Oct-02 RMS Added DIB, enable/disable, device number support 30-May-02 RMS Widened POS to 32b */ @@ -61,7 +62,7 @@ REG lpt_reg[] = { { FLDATA (DONE, dev_done, INT_V_LPT) }, { FLDATA (ENABLE, int_enable, INT_V_LPT) }, { FLDATA (INT, int_req, INT_V_LPT) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lpt_stopioe, 0) }, { ORDATA (DEVNUM, lpt_dib.dev, 6), REG_HRO }, @@ -127,7 +128,7 @@ if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) { perror ("LPT I/O error"); clearerr (lpt_unit.fileref); return SCPE_IOERR; } -lpt_unit.pos = ftell (lpt_unit.fileref); +lpt_unit.pos = lpt_unit.pos + 1; return SCPE_OK; } diff --git a/PDP8/pdp8_mt.c b/PDP8/pdp8_mt.c index 8e20e618..315105b8 100644 --- a/PDP8/pdp8_mt.c +++ b/PDP8/pdp8_mt.c @@ -25,6 +25,9 @@ mt TM8E/TU10 magtape + 25-Apr-03 RMS Revised for extended file support + 29-Mar-03 RMS Added multiformat support + 04-Mar-03 RMS Fixed bug in SKTR 01-Mar-03 RMS Fixed interrupt handling Revised for magtape library 30-Oct-02 RMS Revised BOT handling, added error record handling @@ -123,8 +126,6 @@ #define STA_CLR (FN_RMASK | 00020) /* always clear */ #define STA_DYN (STA_REW | STA_BOT | STA_REM | STA_EOF | \ STA_EOT | STA_WLK) /* kept in USTAT */ - /* set error */ -#define TUR(u) (!sim_is_active (u)) /* tape unit ready */ extern uint16 M[]; extern int32 int_req, stop_inst; @@ -189,7 +190,7 @@ REG mt_reg[] = { { FLDATA (STOP_IOE, mt_stopioe, 0) }, { DRDATA (TIME, mt_time, 24), PV_LEFT }, { URDATA (UST, mt_unit[0].USTAT, 8, 16, 0, MT_NUMDR, 0) }, - { URDATA (POS, mt_unit[0].pos, 10, 32, 0, + { URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0, MT_NUMDR, PV_LEFT | REG_RO) }, { FLDATA (DEVNUM, mt_dib.dev, 6), REG_HRO }, { NULL } }; @@ -197,6 +198,8 @@ REG mt_reg[] = { MTAB mt_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", &mt_vlock }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &mt_vlock }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_dev, &show_dev, NULL }, { 0 } }; @@ -241,7 +244,8 @@ case 6: /* LFGR */ mt_updcsta (uptr); /* update status */ return 0; } f = GET_FNC (mt_fn); /* get function */ - if (((uptr->flags & UNIT_ATT) == 0) || !TUR (uptr) || + if (((uptr->flags & UNIT_ATT) == 0) || + sim_is_active (uptr) || (((f == FN_WRITE) || (f == FN_WREOF)) && sim_tape_wrp (uptr)) || (((f == FN_SPACER) || (f == FN_REWIND)) && sim_tape_bot (uptr))) { mt_sta = mt_sta | STA_ILL | STA_ERR; /* illegal op error */ @@ -309,9 +313,10 @@ case 2: /* SKCB */ case 3: /* SKJD */ return mt_done? IOT_SKP + AC: AC; case 4: /* SKTR */ - return (TUR (uptr))? IOT_SKP + AC: AC; + return (!sim_is_active (uptr) && + (uptr->flags & UNIT_ATT))? IOT_SKP + AC: AC; case 5: /* CLF */ - if (TUR (uptr)) mt_reset (&mt_dev); /* if TUR, zap */ + if (!sim_is_active (uptr)) mt_reset (&mt_dev); /* if TUR, zap */ else { /* just ctrl zap */ mt_sta = 0; /* clear status */ mt_done = 0; /* clear done */ diff --git a/PDP8/pdp8_pt.c b/PDP8/pdp8_pt.c index 9e6b0c0a..92a39858 100644 --- a/PDP8/pdp8_pt.c +++ b/PDP8/pdp8_pt.c @@ -1,6 +1,6 @@ /* pdp8_pt.c: PDP-8 paper tape reader/punch simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ ptr,ptp PC8E paper tape reader/punch + 25-Apr-03 RMS Revised for extended file support 04-Oct-02 RMS Added DIBs 30-May-02 RMS Widened POS to 32b 30-Nov-01 RMS Added read only unit support @@ -63,7 +64,7 @@ REG ptr_reg[] = { { FLDATA (DONE, dev_done, INT_V_PTR) }, { FLDATA (ENABLE, int_enable, INT_V_PTR) }, { FLDATA (INT, int_req, INT_V_PTR) }, - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptr_stopioe, 0) }, { NULL } }; @@ -96,7 +97,7 @@ REG ptp_reg[] = { { FLDATA (DONE, dev_done, INT_V_PTP) }, { FLDATA (ENABLE, int_enable, INT_V_PTP) }, { FLDATA (INT, int_req, INT_V_PTP) }, - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptp_stopioe, 0) }, { NULL } }; diff --git a/PDP8/pdp8_rf.c b/PDP8/pdp8_rf.c index d7c5463a..002c4bb4 100644 --- a/PDP8/pdp8_rf.c +++ b/PDP8/pdp8_rf.c @@ -25,6 +25,7 @@ rf RF08 fixed head disk + 14-Mar-03 RMS Fixed variable platter interaction with save/restore 03-Mar-03 RMS Fixed autosizing 02-Feb-03 RMS Added variable platter and autosizing support 04-Oct-02 RMS Added DIB, device number support @@ -132,8 +133,8 @@ t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); DIB rf_dib = { DEV_RF, 5, { &rf60, &rf61, &rf62, NULL, &rf64 } }; UNIT rf_unit = - { UDATA (&rf_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, - RF_DKSIZE) }; + { UDATA (&rf_svc, UNIT_FIX+UNIT_ATTABLE+ + UNIT_BUFABLE+UNIT_MUSTBUF, RF_DKSIZE) }; UNIT pcell_unit = { UDATA (&pcell_svc, 0, 0) }; @@ -148,6 +149,7 @@ REG rf_reg[] = { { DRDATA (TIME, rf_time, 24), REG_NZ + PV_LEFT }, { FLDATA (BURST, rf_burst, 0) }, { FLDATA (STOP_IOE, rf_stopioe, 0) }, + { DRDATA (CAPAC, rf_unit.capac, 21), REG_HRO }, { ORDATA (DEVNUM, rf_dib.dev, 6), REG_HRO }, { NULL } }; @@ -256,7 +258,7 @@ case 4: /* DXAC w/o clear */ default: AC = (stop_inst << IOT_V_REASON) + AC; break; } /* end switch */ -if ((t_addr) rf_da >= rf_unit.capac) rf_sta = rf_sta | RFS_NXD; +if ((uint32) rf_da >= rf_unit.capac) rf_sta = rf_sta | RFS_NXD; else rf_sta = rf_sta & ~RFS_NXD; RF_INT_UPDATE; return AC; @@ -280,7 +282,7 @@ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ return IORETURN (rf_stopioe, SCPE_UNATT); } mex = GET_MEX (rf_sta); -do { if ((t_addr) rf_da >= rf_unit.capac) { /* disk overflow? */ +do { if ((uint32) rf_da >= rf_unit.capac) { /* disk overflow? */ rf_sta = rf_sta | RFS_NXD; break; } M[RF_WC] = (M[RF_WC] + 1) & 07777; /* incr word count */ @@ -294,7 +296,7 @@ do { if ((t_addr) rf_da >= rf_unit.capac) { /* disk overflow? */ if ((rf_wlk >> t) & 1) rf_sta = rf_sta | RFS_WLS; else { *(((int16 *) uptr->filebuf) + rf_da) = M[pa]; - if (((t_addr) rf_da) >= uptr->hwmark) uptr->hwmark = rf_da + 1; } } + if (((uint32) rf_da) >= uptr->hwmark) uptr->hwmark = rf_da + 1; } } rf_da = (rf_da + 1) & 03777777; } /* incr disk addr */ while ((M[RF_WC] != 0) && (rf_burst != 0)); /* brk if wc, no brst */ @@ -373,15 +375,15 @@ return SCPE_OK; t_stat rf_attach (UNIT *uptr, char *cptr) { -t_addr sz, p; -t_addr ds_bytes = RF_DKSIZE * sizeof (int16); +uint32 sz, p; +uint32 ds_bytes = RF_DKSIZE * sizeof (int16); if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) { p = (sz + ds_bytes - 1) / ds_bytes; - if (p == 0) p = 1; - if (p > RF_NUMDK) p = RF_NUMDK; } -else p = UNIT_GETP (uptr->flags); -uptr->capac = p * RF_DKSIZE; + if (p >= RF_NUMDK) p = RF_NUMDK - 1; + uptr->flags = (uptr->flags & ~UNIT_PLAT) | + (p << UNIT_V_PLAT); } +uptr->capac = UNIT_GETP (uptr->flags) * RF_DKSIZE; return attach_unit (uptr, cptr); } diff --git a/PDP8/pdp8_rk.c b/PDP8/pdp8_rk.c index ef172bc5..7273430e 100644 --- a/PDP8/pdp8_rk.c +++ b/PDP8/pdp8_rk.c @@ -1,6 +1,6 @@ /* pdp8_rk.c: RK8E cartridge disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ rk RK8E/RK05 cartridge disk + 25-Apr-03 RMS Revised for extended file support 04-Oct-02 RMS Added DIB, device number support 06-Jan-02 RMS Changed enable/disable support 30-Nov-01 RMS Added read only unit, extended SET/SHOW support diff --git a/PDP8/pdp8_rl.c b/PDP8/pdp8_rl.c index bd3acfa0..69a91459 100644 --- a/PDP8/pdp8_rl.c +++ b/PDP8/pdp8_rl.c @@ -1,6 +1,6 @@ /* pdp8_rl.c: RL8A cartridge disk simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ rl RL8A cartridge disk + 25-Apr-03 RMS Revised for extended file support 04-Oct-02 RMS Added DIB, device number support 06-Jan-02 RMS Changed enable/disable support 30-Nov-01 RMS Cloned from RL11 @@ -217,7 +218,7 @@ REG rl_reg[] = { { FLDATA (ERR, rl_erf, 0) }, { DRDATA (STIME, rl_swait, 24), PV_LEFT }, { DRDATA (RTIME, rl_rwait, 24), PV_LEFT }, - { URDATA (CAPAC, rl_unit[0].capac, 10, 31, 0, + { URDATA (CAPAC, rl_unit[0].capac, 10, T_ADDR_W, 0, RL_NUMDR, PV_LEFT + REG_HRO) }, { FLDATA (STOP_IOE, rl_stopioe, 0) }, { ORDATA (DEVNUM, rl_dib.dev, 6), REG_HRO }, @@ -370,7 +371,7 @@ t_stat rl_svc (UNIT *uptr) { int32 err, wc, maxc; int32 i, j, func, da, bc, wbc; -t_addr ma; +uint32 ma; func = GET_FUNC (rlcsb); /* get function */ if (func == RLCSB_GSTA) { /* get status? */ @@ -514,19 +515,19 @@ return SCPE_OK; t_stat rl_attach (UNIT *uptr, char *cptr) { -int32 p; +uint32 p; t_stat r; uptr->capac = (uptr->flags & UNIT_RL02)? RL02_SIZE: RL01_SIZE; - -r = attach_unit (uptr, cptr); -if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r; +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) return r; /* error? */ uptr->TRK = 0; /* cyl 0 */ uptr->STAT = RLDS_VCK; /* new volume */ -if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; -if ((p = ftell (uptr->fileref)) == 0) { +if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK; /* seek to end */ +if ((p = ftell (uptr->fileref)) == 0) { /* new disk image? */ if (uptr->flags & UNIT_RO) return SCPE_OK; return rl_set_bad (uptr, 0, NULL, NULL); } +if ((uptr->flags & UNIT_AUTO) == 0) return r; /* autosize? */ if (p > (RL01_SIZE * sizeof (int16))) { uptr->flags = uptr->flags | UNIT_RL02; uptr->capac = RL02_SIZE; } @@ -619,7 +620,7 @@ t_stat rl_boot (int32 unitno, DEVICE *dptr) int32 i; extern int32 saved_PC; -if (unitno) return SCPE_ARG; +if (unitno) return SCPE_ARG; /* only unit 0 */ if (rl_dib.dev != DEV_RL) return STOP_NOTSTD; /* only std devno */ rl_unit[unitno].TRK = 0; for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i]; diff --git a/PDP8/pdp8_rx.c b/PDP8/pdp8_rx.c index e808467d..ba68fcdd 100644 --- a/PDP8/pdp8_rx.c +++ b/PDP8/pdp8_rx.c @@ -25,6 +25,8 @@ rx RX8E/RX01, RX28/RX02 floppy disk + 25-Apr-03 RMS Revised for extended file support + 14-Mar-03 RMS Fixed variable size interaction with save/restore 03-Mar-03 RMS Fixed autosizing 08-Oct-02 RMS Added DIB, device number support Fixed reset to work with disabled device @@ -177,6 +179,8 @@ REG rx_reg[] = { { FLDATA (STOP_IOE, rx_stopioe, 0) }, { BRDATA (SBUF, rx_buf, 8, 8, RX2_NUMBY) }, { FLDATA (RX28, rx_28, 0), REG_HRO }, + { URDATA (CAPAC, rx_unit[0].capac, 10, T_ADDR_W, 0, + RX_NUMDR, REG_HRO | PV_LEFT) }, { ORDATA (DEVNUM, rx_dib.dev, 6), REG_HRO }, { NULL } }; @@ -325,7 +329,7 @@ return; t_stat rx_svc (UNIT *uptr) { int32 i, func, byptr, bps, wps; -t_addr da; +uint32 da; #define PTR12(x) (((x) + (x) + (x)) >> 1) if (rx_28 && (uptr->flags & UNIT_DEN)) @@ -509,7 +513,7 @@ return SCPE_OK; t_stat rx_attach (UNIT *uptr, char *cptr) { -t_addr sz; +uint32 sz; if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) { if (sz > RX_SIZE) uptr->flags = uptr->flags | UNIT_DEN; @@ -581,8 +585,11 @@ static const uint16 boot_rom[] = { 07450, /* 36, SNA ; more to do? */ 07610, /* 37, CLA SKP ; error */ 05046, /* 40, JMP 46 ; go empty */ - 07402, 07402, /* 41-45, HALT ; error */ - 07402, 07402, 07402, + 07402, /* 41-45, HALT ; error */ + 07402, + 07402, + 07402, + 07402, 06751, /* 46, LCD ; load empty */ 04053, /* 47, JMS LOAD ; get data */ 03002, /* 50, DCA 2 ; store */ diff --git a/PDP8/pdp8_sys.c b/PDP8/pdp8_sys.c index a74cddd5..9149e149 100644 --- a/PDP8/pdp8_sys.c +++ b/PDP8/pdp8_sys.c @@ -1,6 +1,6 @@ /* pdp8_sys.c: PDP-8 simulator interface - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 25-Apr-03 RMS Revised for extended file support 30-Dec-01 RMS Revised for new TTX 26-Nov-01 RMS Added RL8A support 17-Sep-01 RMS Removed multiconsole support @@ -106,7 +107,7 @@ const char *sim_stop_messages[] = { t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) { int32 rubout, word, low, high, csum, newf, state, i; -t_addr origin, field; +uint32 origin, field; if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; rubout = state = field = newf = origin = csum = 0; diff --git a/PDP8/pdp8_tt.c b/PDP8/pdp8_tt.c index cbe653e9..33712fb5 100644 --- a/PDP8/pdp8_tt.c +++ b/PDP8/pdp8_tt.c @@ -25,6 +25,7 @@ tti,tto KL8E terminal input/output + 25-Apr-03 RMS Revised for extended file support 02-Mar-02 RMS Added SET TTI CTRL-C 22-Dec-02 RMS Added break support 01-Nov-02 RMS Added 7B/8B support @@ -69,7 +70,7 @@ REG tti_reg[] = { { FLDATA (DONE, dev_done, INT_V_TTI) }, { FLDATA (ENABLE, int_enable, INT_V_TTI) }, { FLDATA (INT, int_req, INT_V_TTI) }, - { DRDATA (POS, tti_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { FLDATA (UC, tti_unit.flags, UNIT_V_KSR), REG_HRO }, { NULL } }; @@ -105,7 +106,7 @@ REG tto_reg[] = { { FLDATA (DONE, dev_done, INT_V_TTO) }, { FLDATA (ENABLE, int_enable, INT_V_TTO) }, { FLDATA (INT, int_req, INT_V_TTO) }, - { DRDATA (POS, tto_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT }, { NULL } }; diff --git a/PDP8/pdp8_ttx.c b/PDP8/pdp8_ttx.c index 4e54dac8..ac6d3125 100644 --- a/PDP8/pdp8_ttx.c +++ b/PDP8/pdp8_ttx.c @@ -1,6 +1,6 @@ /* pdp8_ttx.c: PDP-8 additional terminals simulator - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ ttix,ttox PT08/KL8JA terminal input/output + 09-May-03 RMS Added network device flag + 25-Apr-03 RMS Revised for extended file support 22-Dec-02 RMS Added break support 02-Nov-02 RMS Added 7B/8B support 04-Oct-02 RMS Added DIB, device number support @@ -116,7 +118,7 @@ DEVICE ttix_dev = { 1, 10, 31, 1, 8, 8, &tmxr_ex, &tmxr_dep, &ttix_reset, NULL, &ttx_attach, &ttx_detach, - &ttix_dib, DEV_DISABLE }; + &ttix_dib, DEV_NET | DEV_DISABLE }; /* TTOx data structures diff --git a/S3/s3_cd.c b/S3/s3_cd.c index 58db7428..77423b19 100644 --- a/S3/s3_cd.c +++ b/S3/s3_cd.c @@ -1,6 +1,6 @@ /* s3_cd.c: IBM 1442 card reader/punch - Copyright (c) 2001, Charles E. Owen + Copyright (c) 2001-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -27,6 +27,7 @@ cdp card punch cdp2 card punch stacker 2 + 25-Apr-03 RMS Revised for extended file support 08-Oct-02 RMS Added impossible function catcher Normally, cards are represented as ASCII text streams terminated by newlines. @@ -80,7 +81,7 @@ REG cdr_reg[] = { { HRDATA (LCR, LCR, 16) }, { FLDATA (EBCDIC, cdr_ebcdic, 0) }, { FLDATA (S2, s2sel, 0) }, - { DRDATA (POS, cdr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, cdr_unit.wait, 24), PV_LEFT }, { BRDATA (BUF, rbuf, 8, 8, CDR_WIDTH) }, { NULL } }; @@ -108,7 +109,7 @@ REG cdp_reg[] = { { FLDATA (NOTRDY, notready, 0) }, { HRDATA (DAR, DAR, 16) }, { HRDATA (LCR, LCR, 16) }, - { DRDATA (POS, cdp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT }, { NULL } }; DEVICE cdp_dev = { diff --git a/S3/s3_cpu.c b/S3/s3_cpu.c index 470d4b30..ae496175 100644 --- a/S3/s3_cpu.c +++ b/S3/s3_cpu.c @@ -1,6 +1,6 @@ /* s3_cpu.c: IBM System/3 CPU simulator - Copyright (c) 2001, Charles E. Owen + Copyright (c) 2001-2003, Charles E. Owen HPL & SLC instruction code Copyright (c) 2001 by Henk Stegeman Decimal Arithmetic Copyright (c) 2000 by Roger Bowler @@ -1812,7 +1812,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) return SCPE_ARG; diff --git a/S3/s3_defs.h b/S3/s3_defs.h index b24adad5..f018effa 100644 --- a/S3/s3_defs.h +++ b/S3/s3_defs.h @@ -1,6 +1,6 @@ -/* ibms3_defs.h: IBM System/3 simulator definitions +/* s3_defs.h: IBM System/3 simulator definitions - Copyright (c) 2001, Charles E. Owen + Copyright (c) 2001-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/S3/s3_disk.c b/S3/s3_disk.c index 48192194..21d54027 100644 --- a/S3/s3_disk.c +++ b/S3/s3_disk.c @@ -1,6 +1,6 @@ /* s3_disk.c: IBM 5444 Disk Drives - Copyright (c) 2001, Charles E. Owen + Copyright (c) 2001-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,6 +28,7 @@ r2 Removeable disk 2 f2 Fixed disk 2 + 25-Apr-03 RMS Revised for extended file support 08-Oct-02 RMS Added impossible function catcher */ @@ -93,7 +94,7 @@ REG r1_reg[] = { { HRDATA (ERR, diskerr[0], 16) }, { DRDATA (CYL, r1_unit.u3, 8) }, { DRDATA (HEAD, seekhead[0], 8) }, - { DRDATA (POS, r1_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, r1_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, r1_unit.wait, 24), PV_LEFT }, { BRDATA (BUF, dbuf, 8, 8, 256) }, { NULL } }; diff --git a/S3/s3_lp.c b/S3/s3_lp.c index 4ebadb5c..b643be61 100644 --- a/S3/s3_lp.c +++ b/S3/s3_lp.c @@ -1,6 +1,6 @@ /* s3_lp.c: IBM 1403 line printer simulator - Copyright (c) 2001, Charles E. Owen + Copyright (c) 2001-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,8 +23,9 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Charles E. Owen. - lpt 1403 line printer + lpt 1403 line printer + 25-Apr-03 RMS Revised for extended file support 08-Oct-02 RMS Added impossible function catcher */ @@ -80,7 +81,7 @@ REG lpt_reg[] = { { HRDATA (LPFLR, LPFLR, 8) }, { HRDATA (LPIAR, LPIAR, 16) }, { DRDATA (LINECT, linectr, 8) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { BRDATA (CCT, cct, 8, 32, CCT_LNT) }, { DRDATA (LINES, lines, 8), PV_LEFT }, { DRDATA (CCTP, cctptr, 8), PV_LEFT }, diff --git a/S3/s3_pkb.c b/S3/s3_pkb.c index 7f2fa686..881bf360 100644 --- a/S3/s3_pkb.c +++ b/S3/s3_pkb.c @@ -25,6 +25,7 @@ pkb 5471 printer/keyboard + 25-Apr-03 RMS Revised for extended file support 08-Oct-02 RMS Added impossible function catcher */ @@ -76,7 +77,7 @@ REG pkb_reg[] = { { HRDATA (RTNKEY, key_rtn, 8) }, { HRDATA (CANKEY, key_can, 8) }, { HRDATA (ENDKEY, key_end, 8) }, - { DRDATA (POS, pkb_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, pkb_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, pkb_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; diff --git a/S3/s3_sys.c b/S3/s3_sys.c index 0d2cc73e..c18e1506 100644 --- a/S3/s3_sys.c +++ b/S3/s3_sys.c @@ -1,6 +1,6 @@ -/* ibms3_sys.c: IBM System/3 system interface +/* s3_sys.c: IBM System/3 system interface - Copyright (c) 2001, Charles E. Owen + Copyright (c) 2001-2003, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/SDS/sds_cpu.c b/SDS/sds_cpu.c index 5c26359b..2489cd13 100644 --- a/SDS/sds_cpu.c +++ b/SDS/sds_cpu.c @@ -919,11 +919,10 @@ return SCPE_OK; /* Relocate addr for console access */ -t_addr RelocC (int32 va, int32 sw) +uint32 RelocC (int32 va, int32 sw) { uint32 nml = nml_mode, usr = usr_mode; -uint32 pgn, map; -t_addr pa; +uint32 pa, pgn, map; if (sw & SWMASK ('N')) nml = 1; /* -n: normal */ else if (sw & SWMASK ('X')) nml = usr = 0; /* -x: mon */ @@ -1161,7 +1160,7 @@ return SCPE_OK; t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) { -t_addr pa; +uint32 pa; pa = RelocC (addr, sw); if (pa > MAXMEMSIZE) return SCPE_REL; @@ -1174,7 +1173,7 @@ return SCPE_OK; t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) { -t_addr pa; +uint32 pa; pa = RelocC (addr, sw); if (pa > MAXMEMSIZE) return SCPE_REL; @@ -1188,7 +1187,7 @@ return SCPE_OK; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i; +uint32 i; if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 037777) != 0)) return SCPE_ARG; @@ -1209,7 +1208,7 @@ extern DEVICE drm_dev, mux_dev, muxl_dev; extern UNIT drm_unit, mux_unit; extern DIB mux_dib; -if ((cpu_unit.flags & UNIT_GENIE) == val) return SCPE_OK; +if ((cpu_unit.flags & UNIT_GENIE) == (uint32) val) return SCPE_OK; if ((drm_unit.flags & UNIT_ATT) || /* attached? */ (mux_unit.flags & UNIT_ATT)) return SCPE_NOFNC; /* can't do it */ if (val) { /* Genie? */ diff --git a/SDS/sds_defs.h b/SDS/sds_defs.h index 6b974d86..d6b6a549 100644 --- a/SDS/sds_defs.h +++ b/SDS/sds_defs.h @@ -1,6 +1,6 @@ /* sds_defs.h: SDS 940 simulator definitions - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,8 @@ Except as contained in this notice, the name of Robert M Supnik shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + + 25-Apr-03 RMS Revised for extended file support */ #include "sim_defs.h" /* simulator defns */ @@ -73,7 +75,7 @@ #define MAXMEMSIZE (1 << 16) /* max memory size */ #define PAMASK (MAXMEMSIZE - 1) /* physical addr mask */ #define MEMSIZE (cpu_unit.capac) /* actual memory size */ -#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE) +#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE) #define ReadP(x) M[x] #define WriteP(x,y) if (MEM_ADDR_OK (x)) M[x] = y diff --git a/SDS/sds_drm.c b/SDS/sds_drm.c index d49c9378..c41d5550 100644 --- a/SDS/sds_drm.c +++ b/SDS/sds_drm.c @@ -1,6 +1,6 @@ /* sds_drm.c: SDS 940 Project Genie drum simulator - Copyright (c) 2002, Robert M. Supnik + Copyright (c) 2002-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/SDS/sds_dsk.c b/SDS/sds_dsk.c index 24af8aa9..adedeefa 100644 --- a/SDS/sds_dsk.c +++ b/SDS/sds_dsk.c @@ -1,6 +1,6 @@ /* sds_dsk.c: SDS 940 moving head disk simulator - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/SDS/sds_io.c b/SDS/sds_io.c index f26b8f6e..702ea412 100644 --- a/SDS/sds_io.c +++ b/SDS/sds_io.c @@ -1,6 +1,6 @@ /* sds_io.c: SDS 940 I/O simulator - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/SDS/sds_lp.c b/SDS/sds_lp.c index cf33ba85..f3e4ffc5 100644 --- a/SDS/sds_lp.c +++ b/SDS/sds_lp.c @@ -1,6 +1,6 @@ /* sds_lp.c: SDS 940 line printer simulator - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,7 +23,9 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - lpt line printer + lpt line printer + + 25-Apr-03 RMS Revised for extended file support */ #include "sds_defs.h" @@ -84,7 +86,7 @@ REG lpt_reg[] = { { DRDATA (CCTP, lpt_ccp, 8), PV_LEFT }, { DRDATA (CCTL, lpt_ccl, 8), REG_RO + PV_LEFT }, { ORDATA (SPCINST, lpt_spc, 24) }, - { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (CTIME, lpt_ctime, 24), REG_NZ + PV_LEFT }, { DRDATA (PTIME, lpt_ptime, 24), REG_NZ + PV_LEFT }, { DRDATA (STIME, lpt_stime, 24), REG_NZ + PV_LEFT }, diff --git a/SDS/sds_mt.c b/SDS/sds_mt.c index 8d796189..7d62a81d 100644 --- a/SDS/sds_mt.c +++ b/SDS/sds_mt.c @@ -25,6 +25,8 @@ mt 7 track magnetic tape + 25-Apr-03 RMS Revised for extended file support + 28-Mar-03 RMS Added multiformat support 28-Feb-03 RMS Revised for magtape library Magnetic tapes are represented as a series of variable 8b records @@ -132,7 +134,7 @@ REG mt_reg[] = { { FLDATA (SKIP, mt_skip, 0) }, { DRDATA (CTIME, mt_ctime, 24), REG_NZ + PV_LEFT }, { DRDATA (GTIME, mt_gtime, 24), REG_NZ + PV_LEFT }, - { URDATA (POS, mt_unit[0].pos, 10, 32, 0, + { URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0, MT_NUMDR, PV_LEFT | REG_RO) }, { URDATA (BOT, mt_unit[0].botf, 10, 1, 0, MT_NUMDR, REG_RO) }, { URDATA (EOT, mt_unit[0].eotf, 10, 1, 0, MT_NUMDR, REG_RO) }, @@ -142,6 +144,8 @@ REG mt_reg[] = { MTAB mt_mod[] = { { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, { MTAB_XTD|MTAB_VDV, 0, "CHANNEL", "CHANNEL", &set_chan, &show_chan, NULL }, { 0 } }; diff --git a/SDS/sds_mux.c b/SDS/sds_mux.c index 32253a36..65192e08 100644 --- a/SDS/sds_mux.c +++ b/SDS/sds_mux.c @@ -1,6 +1,6 @@ /* sds_mux.c: SDS 940 terminal multiplexor simulator - Copyright (c) 2001-2002, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ mux terminal multiplexor + 09-May-03 RMS Added network device flag + This module implements up to 32 individual serial interfaces, representing either the project Genie terminal multiplexor or the SDS 940 CTE option. */ @@ -162,7 +164,7 @@ DEVICE mux_dev = { 1, 10, 31, 1, 8, 8, &tmxr_ex, &tmxr_dep, &mux_reset, NULL, &mux_attach, &mux_detach, - &mux_dib, DEV_DISABLE }; + &mux_dib, DEV_NET | DEV_DISABLE }; /* MUXL data structures diff --git a/SDS/sds_rad.c b/SDS/sds_rad.c index b1dc4125..d111ba4d 100644 --- a/SDS/sds_rad.c +++ b/SDS/sds_rad.c @@ -1,6 +1,6 @@ /* sds_rad.c: SDS 940 fixed head disk simulator - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -123,7 +123,7 @@ t_stat rad (uint32 fnc, uint32 inst, uint32 *dat) { int32 t, lun, new_ch; uint32 *wptr; -t_addr p; +uint32 p; switch (fnc) { /* case function */ case IO_CONN: /* connect */ @@ -238,7 +238,7 @@ return SCPE_OK; t_stat rad_fill (int32 sba) { -t_addr p = rad_da * RAD_NUMWD; +uint32 p = rad_da * RAD_NUMWD; int32 wa = (sba + 1) >> 1; /* whole words */ if (sba && (p < rad_unit.capac)) { /* fill needed? */ diff --git a/SDS/sds_stddev.c b/SDS/sds_stddev.c index 7c2eb5a2..02892571 100644 --- a/SDS/sds_stddev.c +++ b/SDS/sds_stddev.c @@ -1,6 +1,6 @@ /* sds_stddev.c: SDS 940 standard devices - Copyright (c) 2001-2002, Robert M. Supnik + Copyright (c) 2001-2003, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -27,6 +27,8 @@ ptp paper tape punch tti keyboard tto teleprinter + + 25-Apr-03 RMS Revised for extended file support */ #include "sds_defs.h" @@ -81,7 +83,7 @@ REG ptr_reg[] = { { ORDATA (BUF, ptr_unit.buf, 7) }, { FLDATA (XFR, xfr_req, XFR_V_PTR) }, { FLDATA (SOR, ptr_sor, 0) }, - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), REG_NZ + PV_LEFT }, { FLDATA (STOP_IOE, ptr_stopioe, 0) }, { NULL } }; @@ -114,7 +116,7 @@ REG ptp_reg[] = { { ORDATA (BUF, ptp_unit.buf, 7) }, { FLDATA (XFR, xfr_req, XFR_V_PTP) }, { FLDATA (LDR, ptp_ldr, 0) }, - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), REG_NZ + PV_LEFT }, { FLDATA (STOP_IOE, ptp_stopioe, 0) }, { NULL } }; @@ -145,7 +147,7 @@ UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT }; REG tti_reg[] = { { ORDATA (BUF, tti_unit.buf, 6) }, { FLDATA (XFR, xfr_req, XFR_V_TTI) }, - { DRDATA (POS, tti_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; @@ -175,7 +177,7 @@ UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT }; REG tto_reg[] = { { ORDATA (BUF, tto_unit.buf, 6) }, { FLDATA (XFR, xfr_req, XFR_V_TTO) }, - { DRDATA (POS, tto_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; diff --git a/SDS/sds_sys.c b/SDS/sds_sys.c index f711097e..8ff8d2af 100644 --- a/SDS/sds_sys.c +++ b/SDS/sds_sys.c @@ -1,6 +1,6 @@ /* sds_sys.c: SDS 940 simulator interface - Copyright (c) 2001-2002, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/VAX/vax_cpu.c b/VAX/vax_cpu.c index d8d1f6f3..6a851f48 100644 --- a/VAX/vax_cpu.c +++ b/VAX/vax_cpu.c @@ -25,6 +25,8 @@ cpu CVAX central processor + 17-May-03 RMS Fixed operand order in EMODx + 23-Apr-03 RMS Revised for 32b/64b t_addr 05-Jan-02 RMS Added memory size restore support 25-Dec-02 RMS Added instruction history (from Mark Pizzolato) 29-Sep-02 RMS Revised to build dib_tab dynamically @@ -307,12 +309,12 @@ extern void op_polyd (int32 *opnd, int32 acc); extern void op_polyg (int32 *opnd, int32 acc); extern int32 op_emulate (int32 *opnd, int32 cc, int32 opc, int32 acc); extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei); -extern int32 Read (t_addr va, int32 lnt, int32 acc); -extern void Write (t_addr va, int32 val, int32 lnt, int32 acc); -extern int32 ReadB (t_addr pa); -extern int32 WriteB (t_addr pa, int32 val); -extern int32 Test (t_addr va, int32 acc, int32 *status); -extern int32 ReadLP (t_addr pa); +extern int32 Read (uint32 va, int32 lnt, int32 acc); +extern void Write (uint32 va, int32 val, int32 lnt, int32 acc); +extern int32 ReadB (uint32 pa); +extern int32 WriteB (uint32 pa, int32 val); +extern int32 Test (uint32 va, int32 acc, int32 *status); +extern int32 ReadLP (uint32 pa); extern int32 eval_int (void); extern int32 get_vector (int32 lvl); extern void set_map_reg (void); @@ -322,8 +324,8 @@ extern t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat cpu_reset (DEVICE *dptr); t_stat cpu_boot (int32 unitno, DEVICE *dptr); -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_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); +t_stat cpu_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw); t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat cpu_show_virt (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc); @@ -512,7 +514,7 @@ for ( ;; ) { int32 spec, disp, rn, index, numspec; int32 vfldrp1, brdisp, flg, mstat; int32 i, j, r, rh, temp; -t_addr va, iad; +uint32 va, iad; int32 opnd[OPND_SIZE]; /* operand queue */ if (cpu_astop) { @@ -2120,8 +2122,8 @@ case ACBG: /* EMODF - op0 = extension - op1 = multiplier + op0 = multiplier + op1 = extension op2 = multiplicand op3:op4 = integer destination (int.wl) op5:op6 = floating destination (flt.wl) @@ -2139,8 +2141,8 @@ case EMODF: /* EMODD, EMODG - op0 = extension - op1:op2 = multiplier + op0:op1 = multiplier + op2 = extension op3:op4 = multiplicand op5:op6 = integer destination (int.wl) op7:op8 = floating destination (flt.wq) @@ -2315,7 +2317,7 @@ ASTLVL = 4; MSER = 0; CADR = 0; mapen = 0; -if (M == NULL) M = calloc (MEMSIZE >> 2, sizeof (int32)); +if (M == NULL) M = calloc (((uint32) MEMSIZE) >> 2, sizeof (int32)); if (M == NULL) return SCPE_MEM; pcq_r = find_reg ("PCQ", NULL, dptr); if (pcq_r) pcq_r->qptr = 0; @@ -2356,9 +2358,10 @@ return SCPE_OK; /* Memory examine */ -t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) +t_stat cpu_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) { int32 st; +uint32 addr = (uint32) exta; if (vptr == NULL) return SCPE_ARG; if (sw & SWMASK ('V')) addr = Test (addr, RD, &st); @@ -2372,9 +2375,10 @@ return SCPE_NXM; /* Memory deposit */ -t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) +t_stat cpu_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw) { int32 st; +uint32 addr = (uint32) exta; if (sw & SWMASK ('V')) addr = Test (addr, RD, &st); else addr = addr & PAMASK; @@ -2393,7 +2397,7 @@ return SCPE_NXM; t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 mc = 0; -t_addr i, clim; +uint32 i, clim; uint32 *nM = NULL; if ((val <= 0) || (val > MAXMEMSIZE)) return SCPE_ARG; @@ -2402,7 +2406,7 @@ if ((mc != 0) && !get_yn ("Really truncate memory [N]?", FALSE)) return SCPE_OK; nM = calloc (val >> 2, sizeof (uint32)); if (nM == NULL) return SCPE_MEM; -clim = (((t_addr) val) < MEMSIZE)? val: MEMSIZE; +clim = (uint32) ((((uint32) val) < MEMSIZE)? val: MEMSIZE); for (i = 0; i < clim; i = i + 4) nM[i >> 2] = M[i >> 2]; free (M); M = nM; @@ -2414,7 +2418,7 @@ return SCPE_OK; } t_stat cpu_show_virt (UNIT *uptr, int32 val, char *cptr, void *desc) { t_stat r; -t_addr va, pa; +uint32 va, pa; int32 st; static const char *mm_str[] = { "Access control violation", @@ -2426,7 +2430,7 @@ static const char *mm_str[] = { "Process PTE translation not valid" }; if (cptr == NULL) return SCPE_ARG; -va = (t_addr) get_uint (cptr, 16, 0xFFFFFFFF, &r); +va = (uint32) get_uint (cptr, 16, 0xFFFFFFFF, &r); if (r != SCPE_OK) return SCPE_ARG; pa = Test (va, RD, &st); if (st == PR_OK) printf ("Virtual %-X = physical %-X\n", va, pa); diff --git a/VAX/vax_cpu1.c b/VAX/vax_cpu1.c index 502b1135..ad1f6c23 100644 --- a/VAX/vax_cpu1.c +++ b/VAX/vax_cpu1.c @@ -1,6 +1,6 @@ /* vax_cpu1.c: VAX complex instructions - Copyright (c) 1998-2002, Robert M Supnik + Copyright (c) 1998-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -101,15 +101,15 @@ extern int32 ibcnt, ppc; extern int32 cpu_log; extern FILE *sim_log; -extern int32 Read (t_addr va, int32 lnt, int32 acc); -extern void Write (t_addr va, int32 val, int32 lnt, int32 acc); -extern int32 Test (t_addr va, int32 acc, int32 *status); -extern int32 ReadLP (t_addr pa); -extern void WriteLP (t_addr pa, int32 val); +extern int32 Read (uint32 va, int32 lnt, int32 acc); +extern void Write (uint32 va, int32 val, int32 lnt, int32 acc); +extern int32 Test (uint32 va, int32 acc, int32 *status); +extern int32 ReadLP (uint32 pa); +extern void WriteLP (uint32 pa, int32 val); extern void set_map_reg (void); extern void zap_tb (int stb); -extern void zap_tb_ent (t_addr va); -extern t_bool chk_tb_ent (t_addr va); +extern void zap_tb_ent (uint32 va); +extern t_bool chk_tb_ent (uint32 va); extern int32 ReadIPR (int32 rg); extern void WriteIPR (int32 rg, int32 val); extern jmp_buf save_env; diff --git a/VAX/vax_defs.h b/VAX/vax_defs.h index 6c28df71..6541c71f 100644 --- a/VAX/vax_defs.h +++ b/VAX/vax_defs.h @@ -1,6 +1,6 @@ /* vax_defs.h: VAX architecture definitions file - Copyright (c) 1998-2002, Robert M Supnik + Copyright (c) 1998-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,10 +26,18 @@ The author gratefully acknowledges the help of Stephen Shirron, Antonio Carlini, and Kevin Peterson in providing specifications for the Qbus VAX's + 19-May-03 RMS Revised for new conditional compilation scheme 14-Jul-02 RMS Added infinite loop message 30-Apr-02 RMS Added CLR_TRAPS macro */ +#ifndef _VAX_DEFS_H +#define _VAX_DEFS_H 0 + +#ifndef VM_VAX +#define VM_VAX 0 +#endif + #include "sim_defs.h" #include @@ -563,3 +571,5 @@ enum opcodes { /* Model dependent definitions */ #include "vaxmod_defs.h" + +#endif /* _VAX_DEFS_H */ diff --git a/VAX/vax_doc.txt b/VAX/vax_doc.txt index 807565d8..7afcc27e 100644 --- a/VAX/vax_doc.txt +++ b/VAX/vax_doc.txt @@ -1,14 +1,14 @@ To: Users From: Bob Supnik Subj: VAX Simulator Usage -Date: 15-Nov-2002 +Date: 15-Jun-2003 COPYRIGHT NOTICE The following copyright notice applies to both the SIMH source and binary: - Original code published in 1993-2002, written by Robert M Supnik - Copyright (c) 1993-2002, Robert M Supnik + Original code published in 1993-2003, written by Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -36,12 +36,10 @@ This memorandum documents the VAX simulator. 1. Simulator Files -To compile the VAX, you must define USE_INT64 as part of the compilation +To compile the VAX, you must define VM_VAX and USE_INT64 as part of the compilation command line. -sim/ dec_dz.h - dec_pt.h - sim_defs.h +sim/ sim_defs.h sim_ether.h sim_rev.h sim_sock.h @@ -65,6 +63,7 @@ sim/vax/ vax_defs.h sim/pdp11/ pdp11_mscp.h pdp11_uqssp.h pdp11_xq.h + pdp11_xq_bootrom.h pdp11_dz.c pdp11_lp.c pdp11_pt.c @@ -100,9 +99,10 @@ RQD fourth RQDX3 MSCP controller with four drives TS TSV11/TSV05 magnetic tape controller with one drive TQ TQK50 TMSCP magnetic tape controller with four drives XQ DELQA/DEQNA Ethernet controller +XQB second DELQA/DEQNA Ethernet controller -The PTR, PTP, LPT, DZ, RL, RQ, RQB, RQC, RQD, TS, TQ, and XQ devices can -be set DISABLED. RQB, RQC, and RQD are disabled by default. +The PTR, PTP, LPT, DZ, RL, RQ, RQB, RQC, RQD, TS, TQ, XQ, and XQB devices +can be set DISABLED. RQB, RQC, RQD, and XQB are disabled by default. The VAX simulator implements several unique stop conditions: @@ -227,6 +227,14 @@ using the LOAD -r command: LOAD -r KA655.BIN -- load boot ROM image KA655.BIN +ROM accesses a use a calibrated delay that slows ROM-based execution to +about 500K instructions per second. This delay is required to make the +power-up self-test routines run correctly on very fast hosts. The delay +is controlled with the commands: + + SET ROM NODELAY -- ROM runs like RAM + SET ROM DELAY -- ROM runs slowly + 2.1.4 Non-volatile Memory (NVR) The NVR consists of a single unit, representing 1KB of battery-backed up @@ -320,7 +328,7 @@ longer recognizes the explicitly configured device. A device can be reset to autoconfigure with the SET AUTOCONFIGURE command. The current I/O map can be displayed with the SHOW CPU IOSPACE command. -Address that have set by autoconfiguration are marked with an asterisk (*). +Addresses that have set by autoconfiguration are marked with an asterisk (*). All devices support the SHOW ADDRESS and SHOW VECTOR commands, which display the device address and vector, respectively. @@ -780,9 +788,10 @@ Error handling is as follows: OS I/O error report error and stop -2.8 DELQA/DEQNA Ethernet Controller (XQ) +2.8 DELQA/DEQNA Qbus Ethernet Controllers (XQ, XQB) -XQ simulates the DELQA/DEQNA 10Mbps Ethernet controller. Options allow +The simulator implements two DELQA/DEQNA Qbus Ethernet controllers (XQ, +XQB). Initially, XQ is enabled, and XQB is disabled. Options allow control of the MAC address, the controller mode, and the sanity timer. SET XQ MAC= ex. 08-00-2B-AA-BB-CC diff --git a/VAX/vax_fpa.c b/VAX/vax_fpa.c index fe0fefbe..483dd9df 100644 --- a/VAX/vax_fpa.c +++ b/VAX/vax_fpa.c @@ -1,6 +1,6 @@ /* vax_fpa.c - VAX floating point accelerator simulator - Copyright (c) 1998-2002, Robert M Supnik + Copyright (c) 1998-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,10 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 19-Jun-03 RMS Simplified add algorithm + 16-May-03 RMS Fixed bug in floating to integer convert overflow + Fixed multiple bugs in EMODx + Integrated 32b only code 05-Jul-02 RMS Changed internal routine names for C library conflict 17-Apr-02 RMS Fixed bug in EDIV zero quotient @@ -31,39 +35,49 @@ - 64 bit arithmetic (ASHQ, EMUL, EDIV) - single precision floating point - double precision floating point, D and G format - - To make life easier (for me), this module assumes that 64b - integer operations are available. Feel free to rewrite this - in 32b arithmetic... */ #include "vax_defs.h" #include #define M32 0xFFFFFFFF /* 32b */ -#define ONES 0xFFFFFFFFFFFFFFFF /* 64b */ +#define M16 0x0000FFFF + #define FD_V_EXP 7 /* f/d exponent */ #define FD_M_EXP 0xFF #define FD_BIAS 0x80 /* f/d bias */ #define FD_EXP (FD_M_EXP << FD_V_EXP) #define FD_HB (1 << FD_V_EXP) /* f/d hidden bit */ -#define FD_FRACW (0xFFFF & ~(FD_EXP | FPSIGN)) -#define FD_FRACL (FD_FRACW | 0xFFFF0000) /* f/d fraction */ +#define FD_GUARD (15 - FD_V_EXP) /* # guard bits */ +#define FD_GETEXP(x) (((x) >> FD_V_EXP) & FD_M_EXP) + #define G_V_EXP 4 /* g exponent */ #define G_M_EXP 0x7FF #define G_BIAS 0x400 /* g bias */ #define G_EXP (G_M_EXP << G_V_EXP) #define G_HB (1 << G_V_EXP) /* g hidden bit */ +#define G_GUARD (15 - G_V_EXP) /* # guard bits */ +#define G_GETEXP(x) (((x) >> G_V_EXP) & G_M_EXP) + +extern int32 R[16]; +extern int32 PSL; +extern int32 p1; +extern jmp_buf save_env; + +extern int32 Read (uint32 va, int32 size, int32 acc); + +#if defined (USE_INT64) + +#define M64 0xFFFFFFFFFFFFFFFF /* 64b */ +#define FD_FRACW (0xFFFF & ~(FD_EXP | FPSIGN)) +#define FD_FRACL (FD_FRACW | 0xFFFF0000) /* f/d fraction */ #define G_FRACW (0xFFFF & ~(G_EXP | FPSIGN)) #define G_FRACL (G_FRACW | 0xFFFF0000) /* g fraction */ -#define FD_GETEXP(x) (((x) >> FD_V_EXP) & FD_M_EXP) -#define G_GETEXP(x) (((x) >> G_V_EXP) & G_M_EXP) #define UNSCRAM(h,l) (((((t_uint64) (h)) << 48) & 0xFFFF000000000000) | \ ((((t_uint64) (h)) << 16) & 0x0000FFFF00000000) | \ ((((t_uint64) (l)) << 16) & 0x00000000FFFF0000) | \ ((((t_uint64) (l)) >> 16) & 0x000000000000FFFF)) -#define CONCAT(h,l) ((((t_uint64) (h)) << 32) | \ - ((uint32) (l))) +#define CONCAT(h,l) ((((t_uint64) (h)) << 32) | ((uint32) (l))) struct ufp { int32 sign; @@ -73,11 +87,8 @@ struct ufp { typedef struct ufp UFP; #define UF_NM 0x8000000000000000 /* normalized */ -#define UF_FMSK 0xFFFFFF0000000000 /* F fraction */ #define UF_FRND 0x0000008000000000 /* F round */ -#define UF_DMSK 0xFFFFFFFFFFFFFF00 /* D fraction */ #define UF_DRND 0x0000000000000080 /* D round */ -#define UF_GMSK 0xFFFFFFFFFFFFF800 /* G fraction */ #define UF_GRND 0x0000000000000400 /* G round */ #define UF_V_NM 63 #define UF_V_FDHI 40 @@ -93,12 +104,6 @@ typedef struct ufp UFP; #define UF_GETGLO(x) (int32) ((((x) >> (16 + UF_V_GLO)) & 0xFFFF) | \ (((x) << (16 - UF_V_GLO)) & ~0xFFFF)) -extern int32 R[16]; -extern int32 PSL; -extern int32 p1; -extern jmp_buf save_env; - -extern int32 Read (t_addr va, int32 size, int32 acc); void unpackf (int32 hi, UFP *a); void unpackd (int32 hi, int32 lo, UFP *a); void unpackg (int32 hi, int32 lo, UFP *a); @@ -179,40 +184,6 @@ if (opnd[2] & LSIGN) rem = -rem; /* sign of rem */ return quo; /* return quo */ } -/* Move/test/move negated floating - - Note that only the high 32b is processed. - If the high 32b is not zero, it is unchanged. -*/ - -int32 op_movfd (int32 val) -{ -if (val & FD_EXP) return val; -if (val & FPSIGN) RSVD_OPND_FAULT; -return 0; -} - -int32 op_mnegfd (int32 val) -{ -if (val & FD_EXP) return (val ^ FPSIGN); -if (val & FPSIGN) RSVD_OPND_FAULT; -return 0; -} - -int32 op_movg (int32 val) -{ -if (val & G_EXP) return val; -if (val & FPSIGN) RSVD_OPND_FAULT; -return 0; -} - -int32 op_mnegg (int32 val) -{ -if (val & G_EXP) return (val ^ FPSIGN); -if (val & FPSIGN) RSVD_OPND_FAULT; -return 0; -} - /* Compare floating */ int32 op_cmpfd (int32 h1, int32 l1, int32 h2, int32 l2) @@ -290,17 +261,919 @@ if (ubexp <= UF_V_NM) { a.frac = a.frac >> (UF_V_NM - ubexp); /* leave rnd bit */ if ((opc & 03) == 03) a.frac = a.frac + 1; /* if CVTR, round */ a.frac = a.frac >> 1; /* now justified */ - if (a.frac > (maxv[lnt] + (a.sign != 0))) *flg = CC_V; } -else { if (ubexp > (UF_V_NM + 32)) return 0; - a.frac = a.frac << (ubexp - UF_V_NM - 1); /* no rnd bit */ - *flg = CC_V; } + if (a.frac > (maxv[lnt] + (a.sign? 1: 0))) *flg = CC_V; } +else { *flg = CC_V; /* set overflow */ + if (ubexp > (UF_V_NM + 32)) return 0; + a.frac = a.frac << (ubexp - UF_V_NM - 1); } /* no rnd bit */ return ((int32) (a.sign? (a.frac ^ M32) + 1: a.frac)); } + +/* Extended modularize -/* Floating to floating convert - F to D is essentially done with MOVFD + One of three floating point instructions dropped from the architecture, + EMOD presents two sets of complications. First, it requires an extended + fraction multiply, with precise (and unusual) truncation conditions. + Second, it has two write operands, a dubious distinction it shares + with EDIV. */ +int32 op_emodf (int32 *opnd, int32 *intgr, int32 *flg) +{ +UFP a, b; + +unpackf (opnd[0], &a); /* unpack operands */ +unpackf (opnd[2], &b); +a.frac = a.frac | (((t_uint64) opnd[1]) << 32); /* extend src1 */ +vax_fmul (&a, &b, 32, FD_BIAS, M32); /* multiply */ +vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */ +return rpackfd (&a, NULL); /* return frac */ +} + +int32 op_emodd (int32 *opnd, int32 *flo, int32 *intgr, int32 *flg) +{ +UFP a, b; + +unpackd (opnd[0], opnd[1], &a); /* unpack operands */ +unpackd (opnd[3], opnd[4], &b); +a.frac = a.frac | opnd[2]; /* extend src1 */ +vax_fmul (&a, &b, 64, FD_BIAS, 0); /* multiply */ +vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */ +return rpackfd (&a, flo); /* return frac */ +} + +int32 op_emodg (int32 *opnd, int32 *flo, int32 *intgr, int32 *flg) +{ +UFP a, b; + +unpackg (opnd[0], opnd[1], &a); /* unpack operands */ +unpackg (opnd[3], opnd[4], &b); +a.frac = a.frac | (opnd[2] >> 5); /* extend src1 */ +vax_fmul (&a, &b, 64, G_BIAS, 0); /* multiply */ +vax_fmod (&a, G_BIAS, intgr, flg); /* sep int & frac */ +return rpackg (&a, flo); /* return frac */ +} + +/* Unpacked floating point routines */ + +void vax_fadd (UFP *a, UFP *b, t_int64 mask) +{ +int32 ediff; +UFP t; + +if (a->exp == 0) { /* s1 = 0? */ + *a = *b; + return; } +if (b->exp == 0) return; /* s2 = 0? */ +if ((a->exp < b->exp) || /* |s1| < |s2|? swap */ + ((a->exp == b->exp) && (a->frac < b->frac))) { + t = *a; + *a = *b; + *b = t; } +ediff = a->exp - b->exp; /* exp diff */ +if (a->sign ^ b->sign) { /* eff sub? */ + if (ediff) { /* exp diff? */ + if (ediff > 63) b->frac = M64; /* retain sticky */ + else b->frac = ((-((t_int64) b->frac) >> ediff) | /* denormalize */ + (M64 << (64 - ediff))); /* preserve sign */ + a->frac = a->frac + b->frac; } /* add frac */ + else a->frac = a->frac - b->frac; /* sub frac */ + a->frac = a->frac & ~mask; + norm (a); } /* normalize */ +else { if (ediff > 63) b->frac = 0; /* add */ + else if (ediff) b->frac = b->frac >> ediff; /* denormalize */ + a->frac = a->frac + b->frac; /* add frac */ + if (a->frac < b->frac) { /* chk for carry */ + a->frac = UF_NM | (a->frac >> 1); /* shift in carry */ + a->exp = a->exp + 1; } /* skip norm */ + a->frac = a->frac & ~mask; } +return; +} + +/* Floating multiply - 64b * 64b with cross products */ + +void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, t_int64 mask) +{ +t_uint64 ah, bh, al, bl, rhi, rlo, rmid1, rmid2; + +if ((a->exp == 0) || (b->exp == 0)) { /* zero argument? */ + a->frac = a->sign = a->exp = 0; /* result is zero */ + return; } +a->sign = a->sign ^ b->sign; /* sign of result */ +a->exp = a->exp + b->exp - bias; /* add exponents */ +ah = (a->frac >> 32) & M32; /* split operands */ +bh = (b->frac >> 32) & M32; /* into 32b chunks */ +rhi = ah * bh; /* high result */ +if (prec > 32) { /* 64b needed? */ + al = a->frac & M32; + bl = b->frac & M32; + rmid1 = ah * bl; + rmid2 = al * bh; + rlo = al * bl; + rhi = rhi + ((rmid1 >> 32) & M32) + ((rmid2 >> 32) & M32); + rmid1 = rlo + (rmid1 << 32); /* add mid1 to lo */ + if (rmid1 < rlo) rhi = rhi + 1; /* carry? incr hi */ + rmid2 = rmid1 + (rmid2 << 32); /* add mid2 to to */ + if (rmid2 < rmid1) rhi = rhi + 1; } /* carry? incr hi */ +a->frac = rhi & ~mask; /* mask out */ +norm (a); /* normalize */ +return; +} + +/* Floating modulus - there are three cases + + exp <= bias - integer is 0, fraction is input, + no overflow + bias < exp <= bias+64 - separate integer and fraction, + integer overflow may occur + bias+64 < exp - result is integer, fraction is 0 + integer overflow +*/ + +void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg) +{ +if (a->exp <= bias) *intgr = *flg = 0; /* 0 or <1? int = 0 */ +else if (a->exp <= (bias + 64)) { /* in range? */ + *intgr = (int32) (a->frac >> (64 - (a->exp - bias))); + if ((a->exp > (bias + 32)) || /* test ovflo */ + ((a->exp == (bias + 32)) && + (((uint32) *intgr) > (a->sign? 0x80000000: 0x7FFFFFFF)))) + *flg = CC_V; + else *flg = 0; + if (a->sign) *intgr = -*intgr; /* -? comp int */ + a->frac = a->frac << (a->exp - bias); + a->exp = bias; } +else { *intgr = 0; /* out of range */ + a->frac = a->sign = a->exp = 0; /* result 0 */ + *flg = CC_V; } /* overflow */ +norm (a); /* normalize */ +return; +} + +/* Floating divide + Needs to develop at least one rounding bit. Since the first + divide step can fail, caller should specify 2 more bits than + the precision of the fraction. +*/ + +void vax_fdiv (UFP *a, UFP *b, int32 prec, int32 bias) +{ +int32 i; +t_uint64 quo = 0; + +if (a->exp == 0) FLT_DZRO_FAULT; /* divr = 0? */ +if (b->exp == 0) return; /* divd = 0? */ +b->sign = b->sign ^ a->sign; /* result sign */ +b->exp = b->exp - a->exp + bias + 1; /* unbiased exp */ +a->frac = a->frac >> 1; /* allow 1 bit left */ +b->frac = b->frac >> 1; +for (i = 0; (i < prec) && b->frac; i++) { /* divide loop */ + quo = quo << 1; /* shift quo */ + if (b->frac >= a->frac) { /* div step ok? */ + b->frac = b->frac - a->frac; /* subtract */ + quo = quo + 1; } /* quo bit = 1 */ + b->frac = b->frac << 1; } /* shift divd */ +b->frac = quo << (UF_V_NM - i + 1); /* shift quo */ +norm (b); /* normalize */ +return; +} + +/* Support routines */ + +void unpackf (int32 hi, UFP *r) +{ +r->sign = hi & FPSIGN; /* get sign */ +r->exp = FD_GETEXP (hi); /* get exponent */ +if (r->exp == 0) { /* exp = 0? */ + if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ + r->frac = 0; /* else 0 */ + return; } +hi = (((hi & FD_FRACW) | FD_HB) << 16) | ((hi >> 16) & 0xFFFF); +r->frac = ((t_uint64) hi) << (32 + UF_V_FDLO); +return; +} + +void unpackd (int32 hi, int32 lo, UFP *r) +{ +r->sign = hi & FPSIGN; /* get sign */ +r->exp = FD_GETEXP (hi); /* get exponent */ +if (r->exp == 0) { /* exp = 0? */ + if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ + r->frac = 0; /* else 0 */ + return; } +hi = (hi & FD_FRACL) | FD_HB; /* canonical form */ +r->frac = UNSCRAM (hi, lo) << UF_V_FDLO; /* guard bits */ +return; +} + +void unpackg (int32 hi, int32 lo, UFP *r) +{ +r->sign = hi & FPSIGN; /* get sign */ +r->exp = G_GETEXP (hi); /* get exponent */ +if (r->exp == 0) { /* exp = 0? */ + if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ + r->frac = 0; /* else 0 */ + return; } +hi = (hi & G_FRACL) | G_HB; /* canonical form */ +r->frac = UNSCRAM (hi, lo) << UF_V_GLO; /* guard bits */ +return; +} + +void norm (UFP *r) +{ +int32 i; +static t_uint64 normmask[5] = { + 0xc000000000000000, 0xf000000000000000, 0xff00000000000000, + 0xffff000000000000, 0xffffffff00000000 }; +static int32 normtab[6] = { 1, 2, 4, 8, 16, 32}; + +if (r->frac == 0) { /* if fraction = 0 */ + r->sign = r->exp = 0; /* result is 0 */ + return; } +while ((r->frac & UF_NM) == 0) { /* normalized? */ + for (i = 0; i < 5; i++) { /* find first 1 */ + if (r->frac & normmask[i]) break; } + r->frac = r->frac << normtab[i]; /* shift frac */ + r->exp = r->exp - normtab[i]; } /* decr exp */ +return; +} + +int32 rpackfd (UFP *r, int32 *rh) +{ +if (rh) *rh = 0; /* assume 0 */ +if (r->frac == 0) return 0; /* result 0? */ +r->frac = r->frac + (rh? UF_DRND: UF_FRND); /* round */ +if ((r->frac & UF_NM) == 0) { /* carry out? */ + r->frac = r->frac >> 1; /* renormalize */ + r->exp = r->exp + 1; } +if (r->exp > (int32) FD_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */ +if (r->exp <= 0) { /* underflow? */ + if (PSL & PSW_FU) FLT_UNFL_FAULT; /* fault if fu */ + return 0; } /* else 0 */ +if (rh) *rh = UF_GETFDLO (r->frac); /* get low */ +return r->sign | (r->exp << FD_V_EXP) | UF_GETFDHI (r->frac); +} + +int32 rpackg (UFP *r, int32 *rh) +{ +*rh = 0; /* assume 0 */ +if (r->frac == 0) return 0; /* result 0? */ +r->frac = r->frac + UF_GRND; /* round */ +if ((r->frac & UF_NM) == 0) { /* carry out? */ + r->frac = r->frac >> 1; /* renormalize */ + r->exp = r->exp + 1; } +if (r->exp > (int32) G_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */ +if (r->exp <= 0) { /* underflow? */ + if (PSL & PSW_FU) FLT_UNFL_FAULT; /* fault if fu */ + return 0; } /* else 0 */ +if (rh) *rh = UF_GETGLO (r->frac); /* get low */ +return r->sign | (r->exp << G_V_EXP) | UF_GETGHI (r->frac); +} + +#else /* 32b code */ + +#define WORDSWAP(x) ((((x) & 0xFFFF) << 16) | (((x) >> 16) & 0xFFFF)) +#define INC32(x) (((x) + 1) & M32) +#define NEG32(x) (((~(x)) + 1) & M32) + +struct udp { + uint32 lo; + uint32 hi; +}; + +typedef struct udp UDP; + +struct ufp { + int32 sign; + int32 exp; + struct udp frac; }; + +typedef struct ufp UFP; + +#define UF_NM_H 0x80000000 /* normalized */ +#define UF_FRND_H 0x00000080 /* F round */ +#define UF_FRND_L 0x00000000 +#define UF_DRND_H 0x00000000 /* D round */ +#define UF_DRND_L 0x00000080 +#define UF_GRND_H 0x00000000 /* G round */ +#define UF_GRND_L 0x00000400 +#define UF_V_NM 63 + +void unpackf (uint32 hi, UFP *a); +void unpackd (uint32 hi, uint32 lo, UFP *a); +void unpackg (uint32 hi, uint32 lo, UFP *a); +void norm (UFP *a); +int32 rpackfd (UFP *a, int32 *rh); +int32 rpackg (UFP *a, int32 *rh); +void vax_fadd (UFP *a, UFP *b, uint32 mask); +void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, uint32 mask); +void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg); +void vax_fdiv (UFP *b, UFP *a, int32 prec, int32 bias); +int32 vax_fcmp (UFP *a, UFP *b); +void dp_add (UDP *a, UDP *b); +void dp_inc (UDP *a); +void dp_sub (UDP *a, UDP *b); +void dp_imul (uint32 a, uint32 b, UDP *r); +void dp_lsh (UDP *a, uint32 sc); +void dp_rsh (UDP *a, uint32 sc); +void dp_rsh_s (UDP *a, uint32 sc, uint32 neg); +void dp_neg (UDP *a); +int32 dp_cmp (UDP *a, UDP *b); + +/* Quadword arithmetic shift + + opnd[0] = shift count (cnt.rb) + opnd[1:2] = source (src.rq) + opnd[3:4] = destination (dst.wq) +*/ + +int32 op_ashq (int32 *opnd, int32 *rh, int32 *flg) +{ +UDP r, sr; +uint32 sc = opnd[0]; + +r.lo = opnd[1]; /* get source */ +r.hi = opnd[2]; +*flg = 0; /* assume no ovflo */ +if (sc & BSIGN) /* right shift? */ + dp_rsh_s (&r, 0x100 - sc, r.hi & LSIGN); /* signed right */ +else { dp_lsh (&r, sc); /* left shift */ + sr = r; /* copy result */ + dp_rsh_s (&sr, sc, sr.hi & LSIGN); /* signed right */ + if ((sr.hi != ((uint32) opnd[2])) || /* reshift != orig? */ + (sr.lo != ((uint32) opnd[1]))) *flg = 1; } /* overflow */ +*rh = r.hi; /* hi result */ +return r.lo; /* lo result */ +} + +/* Extended multiply subroutine */ + +int32 op_emul (int32 mpy, int32 mpc, int32 *rh) +{ +UDP r; +int32 sign = mpy ^ mpc; /* sign of result */ + +if (mpy & LSIGN) mpy = -mpy; /* abs value */ +if (mpc & LSIGN) mpc = -mpc; +dp_imul (mpy & M32, mpc & M32, &r); /* 32b * 32b -> 64b */ +if (sign & LSIGN) dp_neg (&r); /* negative result? */ +*rh = r.hi; +return r.lo; +} + +/* Extended divide + + opnd[0] = divisor (non-zero) + opnd[1:2] = dividend +*/ + +int32 op_ediv (int32 *opnd, int32 *rh, int32 *flg) +{ +UDP dvd; +uint32 i, dvr, quo; + +dvr = opnd[0]; /* get divisor */ +dvd.lo = opnd[1]; /* get dividend */ +dvd.hi = opnd[2]; +*flg = CC_V; /* assume error */ +*rh = 0; +if (dvd.hi & LSIGN) dp_neg (&dvd); /* |dividend| */ +if (dvr & LSIGN) dvr = NEG32 (dvr); /* |divisor| */ +if (dvd.hi >= dvr) return opnd[1]; /* divide work? */ +for (i = quo = 0; i < 32; i++) { /* 32 iterations */ + quo = quo << 1; /* shift quotient */ + dp_lsh (&dvd, 1); /* shift dividend */ + if (dvd.hi >= dvr) { /* step work? */ + dvd.hi = (dvd.hi - dvr) & M32; /* subtract dvr */ + quo = quo + 1; } } +if ((opnd[0] ^ opnd[2]) & LSIGN) { /* result -? */ + quo = NEG32 (quo); /* negate */ + if (quo && ((quo & LSIGN) == 0)) return opnd[1]; } /* right sign? */ +else if (quo & LSIGN) return opnd[1]; +if (opnd[2] & LSIGN) *rh = NEG32 (dvd.hi); /* sign of rem */ +else *rh = dvd.hi; +*flg = 0; /* no overflow */ +return quo; /* return quo */ +} + +/* Compare floating */ + +int32 op_cmpfd (int32 h1, int32 l1, int32 h2, int32 l2) +{ +UFP a, b; +int32 r; + +unpackd (h1, l1, &a); +unpackd (h2, l2, &b); +if (a.sign != b.sign) return (a.sign? CC_N: 0); +r = a.exp - b.exp; +if (r == 0) r = dp_cmp (&a.frac, &b.frac); +if (r < 0) return (a.sign? 0: CC_N); +if (r > 0) return (a.sign? CC_N: 0); +return CC_Z; +} + +int32 op_cmpg (int32 h1, int32 l1, int32 h2, int32 l2) +{ +UFP a, b; +int32 r; + +unpackg (h1, l1, &a); +unpackg (h2, l2, &b); +if (a.sign != b.sign) return (a.sign? CC_N: 0); +r = a.exp - b.exp; +if (r == 0) r = dp_cmp (&a.frac, &b.frac); +if (r < 0) return (a.sign? 0: CC_N); +if (r > 0) return (a.sign? CC_N: 0); +return CC_Z; +} + +/* Integer to floating convert */ + +int32 op_cvtifdg (int32 val, int32 *rh, int32 opc) +{ +UFP a; + +if (val == 0) { /* zero? */ + if (rh) *rh = 0; /* return true 0 */ + return 0; } +if (val < 0) { /* negative? */ + a.sign = FPSIGN; /* sign = - */ + val = -val; } +else a.sign = 0; /* else sign = + */ +a.exp = 32 + ((opc & 0x100)? G_BIAS: FD_BIAS); /* initial exp */ +a.frac.hi = val & M32; /* fraction */ +a.frac.lo = 0; +norm (&a); /* normalize */ +if (opc & 0x100) return rpackg (&a, rh); /* pack and return */ +return rpackfd (&a, rh); +} + +/* Floating to integer convert */ + +int32 op_cvtfdgi (int32 *opnd, int32 *flg, int32 opc) +{ +UFP a; +int32 lnt = opc & 03; +int32 ubexp; +static uint32 maxv[4] = { 0x7F, 0x7FFF, 0x7FFFFFFF, 0x7FFFFFFF }; + +*flg = 0; +if (opc & 0x100) { /* G? */ + unpackg (opnd[0], opnd[1], &a); /* unpack */ + ubexp = a.exp - G_BIAS; } /* unbiased exp */ +else { if (opc & 0x20) unpackd (opnd[0], opnd[1], &a); /* F or D */ + else unpackf (opnd[0], &a); /* unpack */ + ubexp = a.exp - FD_BIAS; } /* unbiased exp */ +if ((a.exp == 0) || (ubexp < 0)) return 0; /* true zero or frac? */ +if (ubexp <= UF_V_NM) { /* exp in range? */ + dp_rsh (&a.frac, UF_V_NM - ubexp); /* leave rnd bit */ + if (lnt == 03) dp_inc (&a.frac); /* if CVTR, round */ + dp_rsh (&a.frac, 1); /* now justified */ + if ((a.frac.hi != 0) || + (a.frac.lo > (maxv[lnt] + (a.sign? 1: 0)))) *flg = CC_V; } +else { *flg = CC_V; /* always ovflo */ + if (ubexp > (UF_V_NM + 32)) return 0; /* in ext range? */ + dp_lsh (&a.frac, ubexp - UF_V_NM - 1); } /* no rnd bit */ +return (a.sign? NEG32 (a.frac.lo): a.frac.lo); /* return lo frac */ +} + +/* Extended modularize + + One of three floating point instructions dropped from the architecture, + EMOD presents two sets of complications. First, it requires an extended + fraction multiply, with precise (and unusual) truncation conditions. + Second, it has two write operands, a dubious distinction it shares + with EDIV. +*/ + +int32 op_emodf (int32 *opnd, int32 *intgr, int32 *flg) +{ +UFP a, b; + +unpackf (opnd[0], &a); /* unpack operands */ +unpackf (opnd[2], &b); +a.frac.hi = a.frac.hi | opnd[1]; /* extend src1 */ +vax_fmul (&a, &b, 32, FD_BIAS, M32); /* multiply */ +vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */ +return rpackfd (&a, NULL); /* return frac */ +} + +int32 op_emodd (int32 *opnd, int32 *flo, int32 *intgr, int32 *flg) +{ +UFP a, b; + +unpackd (opnd[0], opnd[1], &a); /* unpack operands */ +unpackd (opnd[3], opnd[4], &b); +a.frac.lo = a.frac.lo | opnd[2]; /* extend src1 */ +vax_fmul (&a, &b, 64, FD_BIAS, 0); /* multiply */ +vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */ +return rpackfd (&a, flo); /* return frac */ +} + +int32 op_emodg (int32 *opnd, int32 *flo, int32 *intgr, int32 *flg) +{ +UFP a, b; + +unpackg (opnd[0], opnd[1], &a); /* unpack operands */ +unpackg (opnd[3], opnd[4], &b); +a.frac.lo = a.frac.lo | (opnd[2] >> 5); /* extend src1 */ +vax_fmul (&a, &b, 64, G_BIAS, 0); /* multiply */ +vax_fmod (&a, G_BIAS, intgr, flg); /* sep int & frac */ +return rpackg (&a, flo); /* return frac */ +} + +/* Unpacked floating point routines */ + +/* Floating add */ + +void vax_fadd (UFP *a, UFP *b, uint32 mask) +{ +int32 ediff; +UFP t; + +if (a->exp == 0) { /* s1 = 0? */ + *a = *b; + return; } +if (b->exp == 0) return; /* s2 = 0? */ +if ((a->exp < b->exp) || /* |s1| < |s2|? swap */ + ((a->exp == b->exp) && (dp_cmp (&a->frac, &b->frac) < 0))) { + t = *a; + *a = *b; + *b = t; } +ediff = a->exp - b->exp; /* exp diff */ +if (a->sign ^ b->sign) { /* eff sub? */ + if (ediff) { /* exp diff? */ + dp_neg (&b->frac); /* negate fraction */ + dp_rsh_s (&b->frac, ediff, 1); /* signed right */ + dp_add (&a->frac, &b->frac); } /* "add" frac */ + else dp_sub (&a->frac, &b->frac); /* a >= b */ + a->frac.lo = a->frac.lo & ~mask; /* trim low result */ + norm (a); } /* normalize */ +else { if (ediff) dp_rsh (&b->frac, ediff); /* add, denormalize */ + dp_add (&a->frac, &b->frac); /* add frac */ + if (dp_cmp (&a->frac, &b->frac) < 0) { /* chk for carry */ + dp_rsh (&a->frac, 1); /* renormalize */ + a->frac.hi = a->frac.hi | UF_NM_H; /* add norm bit */ + a->exp = a->exp + 1; } /* skip norm */ + a->frac.lo = a->frac.lo & ~mask; } /* trim low result */ +return; +} + +/* Floating compare */ + +int32 vax_fcmp (UFP *a, UFP *b) +{ +int32 r; + +if (a->sign != b->sign) return ((a->sign)? CC_N: 0); +r = a->exp - b->exp; +if (r == 0) r = dp_cmp (&a->frac, &b->frac); +if (r == 0) return CC_Z; +if (r < 0) return (a->sign? 0: CC_N); +else return (a->sign? CC_N: 0); +} + +/* Floating multiply - 64b * 64b with cross products */ + +void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, uint32 mask) +{ +UDP rhi, rlo, rmid1, rmid2; + +if ((a->exp == 0) || (b->exp == 0)) { /* zero argument? */ + a->frac.hi = a->frac.lo = 0; /* result is zero */ + a->sign = a->exp = 0; + return; } +a->sign = a->sign ^ b->sign; /* sign of result */ +a->exp = a->exp + b->exp - bias; /* add exponents */ +dp_imul (a->frac.hi, b->frac.hi, &rhi); /* high result */ +if (prec > 32) { /* 64b needed? */ + dp_imul (a->frac.hi, b->frac.lo, &rmid1); /* cross products */ + dp_imul (a->frac.lo, b->frac.hi, &rmid2); + dp_imul (a->frac.lo, b->frac.lo, &rlo); /* low result */ + rhi.lo = (rhi.lo + rmid1.hi) & M32; /* add hi cross */ + if (rhi.lo < rmid1.hi) rhi.hi = INC32 (rhi.hi); /* to low high res */ + rhi.lo = (rhi.lo + rmid2.hi) & M32; + if (rhi.lo < rmid2.hi) rhi.hi = INC32 (rhi.hi); + rlo.hi = (rlo.hi + rmid1.lo) & M32; /* add mid1 to low res */ + if (rlo.hi < rmid1.lo) dp_inc (&rhi); /* carry? incr high res */ + rlo.hi = (rlo.hi + rmid2.lo) & M32; /* add mid2 to low res */ + if (rlo.hi < rmid1.hi) dp_inc (&rhi); } /* carry? incr high res */ +a->frac.hi = rhi.hi; /* mask low fraction */ +a->frac.lo = rhi.lo & ~mask; +norm (a); /* normalize */ +return; +} + +/* Floating modulus - there are three cases + + exp <= bias - integer is 0, fraction is input, + no overflow + bias < exp <= bias+64 - separate integer and fraction, + integer overflow may occur + bias+64 < exp - result is integer, fraction is 0 + integer overflow +*/ + +void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg) +{ +UDP ifr; + +if (a->exp <= bias) *intgr = *flg = 0; /* 0 or <1? int = 0 */ +else if (a->exp <= (bias + 64)) { /* in range? */ + ifr = a->frac; + dp_rsh (&ifr, 64 - (a->exp - bias)); /* separate integer */ + if ((a->exp > (bias + 32)) || /* test ovflo */ + ((a->exp == (bias + 32)) && + (ifr.lo > (a->sign? 0x80000000: 0x7FFFFFFF)))) + *flg = CC_V; + else *flg = 0; + *intgr = ifr.lo; + if (a->sign) *intgr = -*intgr; /* -? comp int */ + dp_lsh (&a->frac, a->exp - bias); /* excise integer */ + a->exp = bias; } +else { *intgr = 0; /* out of range */ + a->frac.hi = a->frac.lo = a->sign = a->exp = 0; /* result 0 */ + *flg = CC_V; } /* overflow */ +norm (a); /* normalize */ +return; +} + +/* Floating divide + Needs to develop at least one rounding bit. Since the first + divide step can fail, caller should specify 2 more bits than + the precision of the fraction. +*/ + +void vax_fdiv (UFP *a, UFP *b, int32 prec, int32 bias) +{ +int32 i; +UDP quo = { 0, 0 }; + +if (a->exp == 0) FLT_DZRO_FAULT; /* divr = 0? */ +if (b->exp == 0) return; /* divd = 0? */ +b->sign = b->sign ^ a->sign; /* result sign */ +b->exp = b->exp - a->exp + bias + 1; /* unbiased exp */ +dp_rsh (&a->frac, 1); /* allow 1 bit left */ +dp_rsh (&b->frac, 1); +for (i = 0; i < prec; i++) { /* divide loop */ + dp_lsh (&quo, 1); /* shift quo */ + if (dp_cmp (&b->frac, &a->frac) >= 0) { /* div step ok? */ + dp_sub (&b->frac, &a->frac); /* subtract */ + quo.lo = quo.lo + 1; } /* quo bit = 1 */ + dp_lsh (&b->frac, 1); } /* shift divd */ +dp_lsh (&quo, UF_V_NM - prec + 1); /* put in position */ +b->frac = quo; +norm (b); /* normalize */ +return; +} + +/* Double precision integer routines */ + +int32 dp_cmp (UDP *a, UDP *b) +{ +if (a->hi < b->hi) return -1; /* compare hi */ +if (a->hi > b->hi) return +1; +if (a->lo < b->lo) return -1; /* hi =, compare lo */ +if (a->lo > b->lo) return +1; +return 0; /* hi, lo equal */ +} + +void dp_add (UDP *a, UDP *b) +{ +a->lo = (a->lo + b->lo) & M32; /* add lo */ +if (a->lo < b->lo) a->hi = a->hi + 1; /* carry? */ +a->hi = (a->hi + b->hi) & M32; /* add hi */ +return; +} + +void dp_inc (UDP *a) +{ +a->lo = (a->lo + 1) & M32; /* inc lo */ +if (a->lo == 0) a->hi = (a->hi + 1) & M32; /* carry? inc hi */ +return; +} + +void dp_sub (UDP *a, UDP *b) +{ +if (a->lo < b->lo) a->hi = a->hi - 1; /* borrow? decr hi */ +a->lo = (a->lo - b->lo) & M32; /* sub lo */ +a->hi = (a->hi - b->hi) & M32; /* sub hi */ +return; +} + +void dp_lsh (UDP *r, uint32 sc) +{ +if (sc > 63) r->hi = r->lo = 0; /* > 63? result 0 */ +else if (sc > 31) { /* [32,63]? */ + r->hi = (r->lo << (sc - 32)) & M32; + r->lo = 0; } +else if (sc != 0) { + r->hi = ((r->hi << sc) | (r->lo >> (32 - sc))) & M32; + r->lo = (r->lo << sc) & M32; } +return; +} + +void dp_rsh (UDP *r, uint32 sc) +{ +if (sc > 63) r->hi = r->lo = 0; /* > 63? result 0 */ +else if (sc > 31) { /* [32,63]? */ + r->lo = (r->hi >> (sc - 32)) & M32; + r->hi = 0; } +else if (sc != 0) { + r->lo = ((r->lo >> sc) | (r->hi << (32 - sc))) & M32; + r->hi = (r->hi >> sc) & M32; } +return; +} + +void dp_rsh_s (UDP *r, uint32 sc, uint32 neg) +{ +dp_rsh (r, sc); /* do unsigned right */ +if (neg && sc) { /* negative? */ + if (sc > 63) r->hi = r->lo = M32; /* > 63? result -1 */ + else { + UDP ones = { M32, M32 }; + dp_lsh (&ones, 64 - sc); /* shift ones */ + r->hi = r->hi | ones.hi; /* or into result */ + r->lo = r->lo | ones.lo; } } +return; +} + +void dp_imul (uint32 a, uint32 b, UDP *r) +{ +uint32 ah, bh, al, bl, rhi, rlo, rmid1, rmid2; + +if ((a == 0) || (b == 0)) { /* zero argument? */ + r->hi = r->lo = 0; /* result is zero */ + return; } +ah = (a >> 16) & M16; /* split operands */ +bh = (b >> 16) & M16; /* into 16b chunks */ +al = a & M16; +bl = b & M16; +rhi = ah * bh; /* high result */ +rmid1 = ah * bl; +rmid2 = al * bh; +rlo = al * bl; +rhi = rhi + ((rmid1 >> 16) & M16) + ((rmid2 >> 16) & M16); +rmid1 = (rlo + (rmid1 << 16)) & M32; /* add mid1 to lo */ +if (rmid1 < rlo) rhi = rhi + 1; /* carry? incr hi */ +rmid2 = (rmid1 + (rmid2 << 16)) & M32; /* add mid2 to to */ +if (rmid2 < rmid1) rhi = rhi + 1; /* carry? incr hi */ +r->hi = rhi & M32; /* mask result */ +r->lo = rmid2; +return; +} + +void dp_neg (UDP *r) +{ +r->lo = NEG32 (r->lo); +r->hi = (~r->hi + (r->lo == 0)) & M32; +return; +} + +/* Support routines */ + +void unpackf (uint32 hi, UFP *r) +{ +r->sign = hi & FPSIGN; /* get sign */ +r->exp = FD_GETEXP (hi); /* get exponent */ +if (r->exp == 0) { /* exp = 0? */ + if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ + r->frac.hi = r->frac.lo = 0; /* else 0 */ + return; } +r->frac.hi = WORDSWAP ((hi & ~(FPSIGN | FD_EXP)) | FD_HB); +r->frac.lo = 0; +dp_lsh (&r->frac, FD_GUARD); +return; +} + +void unpackd (uint32 hi, uint32 lo, UFP *r) +{ +r->sign = hi & FPSIGN; /* get sign */ +r->exp = FD_GETEXP (hi); /* get exponent */ +if (r->exp == 0) { /* exp = 0? */ + if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ + r->frac.hi = r->frac.lo = 0; /* else 0 */ + return; } +r->frac.hi = WORDSWAP ((hi & ~(FPSIGN | FD_EXP)) | FD_HB); +r->frac.lo = WORDSWAP (lo); +dp_lsh (&r->frac, FD_GUARD); +return; +} + +void unpackg (uint32 hi, uint32 lo, UFP *r) +{ +r->sign = hi & FPSIGN; /* get sign */ +r->exp = G_GETEXP (hi); /* get exponent */ +if (r->exp == 0) { /* exp = 0? */ + if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ + r->frac.hi = r->frac.lo = 0; /* else 0 */ + return; } +r->frac.hi = WORDSWAP ((hi & ~(FPSIGN | G_EXP)) | G_HB); +r->frac.lo = WORDSWAP (lo); +dp_lsh (&r->frac, G_GUARD); +return; +} + +void norm (UFP *r) +{ +int32 i; +static uint32 normmask[5] = { + 0xc0000000, 0xf0000000, 0xff000000, 0xffff0000, 0xffffffff }; +static int32 normtab[6] = { 1, 2, 4, 8, 16, 32}; + +if ((r->frac.hi == 0) && (r->frac.lo == 0)) { /* if fraction = 0 */ + r->sign = r->exp = 0; /* result is 0 */ + return; } +while ((r->frac.hi & UF_NM_H) == 0) { /* normalized? */ + for (i = 0; i < 5; i++) { /* find first 1 */ + if (r->frac.hi & normmask[i]) break; } + dp_lsh (&r->frac, normtab[i]); /* shift frac */ + r->exp = r->exp - normtab[i]; } /* decr exp */ +return; +} + +int32 rpackfd (UFP *r, int32 *rh) +{ +static UDP f_round = { UF_FRND_L, UF_FRND_H }; +static UDP d_round = { UF_DRND_L, UF_DRND_H }; + +if (rh) *rh = 0; /* assume 0 */ +if ((r->frac.hi == 0) && (r->frac.lo == 0)) return 0; /* result 0? */ +if (rh) dp_add (&r->frac, &d_round); /* round */ +else dp_add (&r->frac, &f_round); +if ((r->frac.hi & UF_NM_H) == 0) { /* carry out? */ + dp_rsh (&r->frac, 1); /* renormalize */ + r->exp = r->exp + 1; } +if (r->exp > (int32) FD_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */ +if (r->exp <= 0) { /* underflow? */ + if (PSL & PSW_FU) FLT_UNFL_FAULT; /* fault if fu */ + return 0; } /* else 0 */ +dp_rsh (&r->frac, FD_GUARD); /* remove guard */ +if (rh) *rh = WORDSWAP (r->frac.lo); /* get low */ +return r->sign | (r->exp << FD_V_EXP) | + (WORDSWAP (r->frac.hi) & ~(FD_HB | FPSIGN | FD_EXP)); +} + +int32 rpackg (UFP *r, int32 *rh) +{ +static UDP g_round = { UF_GRND_L, UF_GRND_H }; + +*rh = 0; /* assume 0 */ +if ((r->frac.hi == 0) && (r->frac.lo == 0)) return 0; /* result 0? */ +dp_add (&r->frac, &g_round); /* round */ +if ((r->frac.hi & UF_NM_H) == 0) { /* carry out? */ + dp_rsh (&r->frac, 1); /* renormalize */ + r->exp = r->exp + 1; } +if (r->exp > (int32) G_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */ +if (r->exp <= 0) { /* underflow? */ + if (PSL & PSW_FU) FLT_UNFL_FAULT; /* fault if fu */ + return 0; } /* else 0 */ +dp_rsh (&r->frac, G_GUARD); /* remove guard */ +*rh = WORDSWAP (r->frac.lo); /* get low */ +return r->sign | (r->exp << G_V_EXP) | + (WORDSWAP (r->frac.hi) & ~(G_HB | FPSIGN | G_EXP)); +} + +#endif + +/* Floating point instructions */ + +/* Move/test/move negated floating + + Note that only the high 32b is processed. + If the high 32b is not zero, it is unchanged. +*/ + +int32 op_movfd (int32 val) +{ +if (val & FD_EXP) return val; +if (val & FPSIGN) RSVD_OPND_FAULT; +return 0; +} + +int32 op_mnegfd (int32 val) +{ +if (val & FD_EXP) return (val ^ FPSIGN); +if (val & FPSIGN) RSVD_OPND_FAULT; +return 0; +} + +int32 op_movg (int32 val) +{ +if (val & G_EXP) return val; +if (val & FPSIGN) RSVD_OPND_FAULT; +return 0; +} + +int32 op_mnegg (int32 val) +{ +if (val & G_EXP) return (val ^ FPSIGN); +if (val & FPSIGN) RSVD_OPND_FAULT; +return 0; +} + +/* Floating to floating convert - F to D is essentially done with MOVFD */ + int32 op_cvtdf (int32 *opnd) { UFP a; @@ -361,49 +1234,8 @@ if (sub) a.sign = a.sign ^ FPSIGN; /* sub? -s1 */ vax_fadd (&a, &b, 0); /* add fractions */ return rpackg (&a, rh); /* round and pack */ } - -void vax_fadd (UFP *a, UFP *b, t_int64 mask) -{ -int32 ediff; -UFP t; - -if (a->exp == 0) { /* s1 = 0? */ - *a = *b; - return; } -if (b->exp == 0) return; /* s2 = 0? */ -if (a->exp < b->exp) { /* s1 < s2? swap */ - t = *a; - *a = *b; - *b = t; } -ediff = a->exp - b->exp; /* exp diff */ -if (a->sign ^ b->sign) { /* eff sub? */ - if (ediff) { /* exp diff? */ - b->frac = (ediff > 63)? ONES: /* shift b */ - ((-((t_int64) b->frac) >> ediff) | - (ONES << (64 - ediff))); /* preserve sign */ - a->frac = a->frac + b->frac; } /* add frac */ - else { - if (a->frac < b->frac) { /* same, check magn */ - a->frac = b->frac - a->frac; /* b > a */ - a->sign = b->sign; } - else a->frac = a->frac - b->frac; } /* a >= b */ - a->frac = a->frac & ~mask; - norm (a); } /* normalize */ -else { if (ediff >= 64) b->frac = 0; - else b->frac = b->frac >> ediff; /* add, denorm */ - a->frac = a->frac + b->frac; /* add frac */ - if (a->frac < b->frac) { /* chk for carry */ - a->frac = UF_NM | (a->frac >> 1); /* shift in carry */ - a->exp = a->exp + 1; } /* skip norm */ - a->frac = a->frac & ~mask; } -return; -} -/* Floating multiply - - Note that when the fractions are multiplied, the fraction position - must be adjusted to maintain the right precision. -*/ +/* Floating multiply */ int32 op_mulf (int32 *opnd) { @@ -434,38 +1266,6 @@ unpackg (opnd[2], opnd[3], &b); vax_fmul (&a, &b, 53, G_BIAS, 0); /* do multiply */ return rpackg (&a, rh); /* round and pack */ } - -/* Floating multiply - 64b * 64b with cross products - Where is Alpha's UMULH when you need it? -*/ - -void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, t_int64 mask) -{ -t_uint64 ah, bh, al, bl, rhi, rlo, rmid1, rmid2; - -if ((a->exp == 0) || (b->exp == 0)) { /* zero argument? */ - a->frac = a->sign = a->exp = 0; /* result is zero */ - return; } -a->sign = a->sign ^ b->sign; /* sign of result */ -a->exp = a->exp + b->exp - bias; /* add exponents */ -ah = (a->frac >> 32) & M32; /* split operands */ -bh = (b->frac >> 32) & M32; /* into 32b chunks */ -rhi = ah * bh; /* high result */ -if (prec > 32) { /* 64b needed? */ - al = a->frac & M32; - bl = b->frac & M32; - rmid1 = ah * bl; - rmid2 = al * bh; - rlo = al * bl; - rhi = rhi + ((rmid1 >> 32) & M32) + ((rmid2 >> 32) & M32); - rmid1 = rlo + (rmid1 << 32); /* add mid1 to lo */ - if (rmid1 < rlo) rhi = rhi + 1; /* carry? incr hi */ - rmid2 = rmid1 + (rmid2 << 32); /* add mid2 to to */ - if (rmid2 < rmid1) rhi = rhi + 1; } /* carry? incr hi */ -a->frac = rhi & ~mask; /* mask out */ -norm (a); /* normalize */ -return; -} /* Floating divide */ @@ -498,94 +1298,6 @@ unpackg (opnd[2], opnd[3], &b); vax_fdiv (&a, &b, 55, G_BIAS); /* do divide */ return rpackg (&b, rh); /* round and pack */ } - -/* Floating divide - Needs to develop at least one rounding bit. Since the first - divide step can fail, caller should specify 2 more bits than - the precision of the fraction. -*/ - -void vax_fdiv (UFP *a, UFP *b, int32 prec, int32 bias) -{ -int32 i; -t_uint64 quo = 0; - -if (a->exp == 0) FLT_DZRO_FAULT; /* divr = 0? */ -if (b->exp == 0) return; /* divd = 0? */ -b->sign = b->sign ^ a->sign; /* result sign */ -b->exp = b->exp - a->exp + bias + 1; /* unbiased exp */ -a->frac = a->frac >> 1; /* allow 1 bit left */ -b->frac = b->frac >> 1; -for (i = 0; (i < prec) && b->frac; i++) { /* divide loop */ - quo = quo << 1; /* shift quo */ - if (b->frac >= a->frac) { /* div step ok? */ - b->frac = b->frac - a->frac; /* subtract */ - quo = quo + 1; } /* quo bit = 1 */ - b->frac = b->frac << 1; } /* shift divd */ -b->frac = quo << (UF_V_NM - i + 1); /* shift quo */ -norm (b); /* normalize */ -return; -} - -/* Extended modularize - - One of three floating point instructions dropped from the architecture, - EMOD presents two sets of complications. First, it requires an extended - fraction multiply, with precise (and unusual) truncation conditions. - Second, it has two write operands, a dubious distinction it shares - with EDIV. -*/ - -int32 op_emodf (int32 *opnd, int32 *intgr, int32 *flg) -{ -UFP a, b; - -unpackf (opnd[1], &a); /* unpack operands */ -unpackf (opnd[2], &b); -a.frac = a.frac | (((t_uint64) opnd[0]) << 32); /* extend src1 */ -vax_fmul (&a, &b, 32, FD_BIAS, M32); /* multiply */ -vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */ -return rpackfd (&a, NULL); /* return frac */ -} - -int32 op_emodd (int32 *opnd, int32 *flo, int32 *intgr, int32 *flg) -{ -UFP a, b; - -unpackd (opnd[1], opnd[2], &a); /* unpack operands */ -unpackd (opnd[3], opnd[4], &b); -a.frac = a.frac | opnd[0]; /* extend src1 */ -vax_fmul (&a, &b, 64, FD_BIAS, 0); /* multiply */ -vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */ -return rpackfd (&a, flo); /* return frac */ -} - -int32 op_emodg (int32 *opnd, int32 *flo, int32 *intgr, int32 *flg) -{ -UFP a, b; - -unpackg (opnd[1], opnd[2], &a); /* unpack operands */ -unpackg (opnd[3], opnd[4], &b); -a.frac = a.frac | (opnd[0] >> 5); -vax_fmul (&a, &b, 64, G_BIAS, 0); /* multiply */ -vax_fmod (&a, G_BIAS, intgr, flg); /* sep int & frac */ -return rpackg (&a, flo); /* return frac */ -} - -void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg) -{ -if (a->exp <= bias) *intgr = 0; /* 0 or <1? int = 0 */ -else if (a->exp <= (bias + 64)) { /* in range? */ - *intgr = (int32) (a->frac >> (64 - (a->exp - bias))); - a->frac = a->frac << (a->exp - bias); } -else *intgr = 0; /* out of range */ -if (a->sign) *intgr = -*intgr; /* -? comp int */ -if ((a->exp >= (bias + 32)) || (((a->sign) != 0) && (*intgr < 0))) - *flg = CC_V; /* test ovflo */ -else *flg = 0; -norm (a); /* normalize */ -return; -} /* Polynomial evaluation The most mis-implemented instruction in the VAX (probably here too). @@ -681,95 +1393,3 @@ R[2] = 0; R[3] = opnd[3] + 4 + (opnd[2] << 2); return; } - -/* Support routines */ - -void unpackf (int32 hi, UFP *r) -{ -r->sign = hi & FPSIGN; /* get sign */ -r->exp = FD_GETEXP (hi); /* get exponent */ -if (r->exp == 0) { /* exp = 0? */ - if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ - r->frac = 0; /* else 0 */ - return; } -hi = (((hi & FD_FRACW) | FD_HB) << 16) | ((hi >> 16) & 0xFFFF); -r->frac = ((t_uint64) hi) << (32 + UF_V_FDLO); -return; -} - -void unpackd (int32 hi, int32 lo, UFP *r) -{ -r->sign = hi & FPSIGN; /* get sign */ -r->exp = FD_GETEXP (hi); /* get exponent */ -if (r->exp == 0) { /* exp = 0? */ - if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ - r->frac = 0; /* else 0 */ - return; } -hi = (hi & FD_FRACL) | FD_HB; /* canonical form */ -r->frac = UNSCRAM (hi, lo) << UF_V_FDLO; /* guard bits */ -return; -} - -void unpackg (int32 hi, int32 lo, UFP *r) -{ -r->sign = hi & FPSIGN; /* get sign */ -r->exp = G_GETEXP (hi); /* get exponent */ -if (r->exp == 0) { /* exp = 0? */ - if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */ - r->frac = 0; /* else 0 */ - return; } -hi = (hi & G_FRACL) | G_HB; /* canonical form */ -r->frac = UNSCRAM (hi, lo) << UF_V_GLO; /* guard bits */ -return; -} - -void norm (UFP *r) -{ -int32 i; -static t_uint64 normmask[5] = { - 0xc000000000000000, 0xf000000000000000, 0xff00000000000000, - 0xffff000000000000, 0xffffffff00000000 }; -static int32 normtab[6] = { 1, 2, 4, 8, 16, 32}; - -if (r->frac == 0) { /* if fraction = 0 */ - r->sign = r->exp = 0; /* result is 0 */ - return; } -while ((r->frac & UF_NM) == 0) { /* normalized? */ - for (i = 0; i < 5; i++) { /* find first 1 */ - if (r->frac & normmask[i]) break; } - r->frac = r->frac << normtab[i]; /* shift frac */ - r->exp = r->exp - normtab[i]; } /* decr exp */ -return; -} - -int32 rpackfd (UFP *r, int32 *rh) -{ -if (rh) *rh = 0; /* assume 0 */ -if (r->frac == 0) return 0; /* result 0? */ -r->frac = r->frac + (rh? UF_DRND: UF_FRND); /* round */ -if ((r->frac & UF_NM) == 0) { /* carry out? */ - r->frac = r->frac >> 1; /* renormalize */ - r->exp = r->exp + 1; } -if (r->exp > (int32) FD_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */ -if (r->exp <= 0) { /* underflow? */ - if (PSL & PSW_FU) FLT_UNFL_FAULT; /* fault if fu */ - return 0; } /* else 0 */ -if (rh) *rh = UF_GETFDLO (r->frac); /* get low */ -return r->sign | (r->exp << FD_V_EXP) | UF_GETFDHI (r->frac); -} - -int32 rpackg (UFP *r, int32 *rh) -{ -*rh = 0; /* assume 0 */ -if (r->frac == 0) return 0; /* result 0? */ -r->frac = r->frac + UF_GRND; /* round */ -if ((r->frac & UF_NM) == 0) { /* carry out? */ - r->frac = r->frac >> 1; /* renormalize */ - r->exp = r->exp + 1; } -if (r->exp > (int32) G_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */ -if (r->exp <= 0) { /* underflow? */ - if (PSL & PSW_FU) FLT_UNFL_FAULT; /* fault if fu */ - return 0; } /* else 0 */ -if (rh) *rh = UF_GETGLO (r->frac); /* get low */ -return r->sign | (r->exp << G_V_EXP) | UF_GETGHI (r->frac); -} diff --git a/VAX/vax_io.c b/VAX/vax_io.c index ab3d2a11..5074b68e 100644 --- a/VAX/vax_io.c +++ b/VAX/vax_io.c @@ -1,6 +1,6 @@ /* vax_io.c: VAX Qbus IO simulator - Copyright (c) 1998-2002, Robert M Supnik + Copyright (c) 1998-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,7 +25,9 @@ qba Qbus adapter - 22-Dec-02 RMS Addec console halt support + 19-Apr-03 RMS Added optimized byte and word DMA routines + 12-Mar-03 RMS Added logical name support + 22-Dec-02 RMS Added console halt support 12-Oct-02 RMS Added autoconfigure support Added SHOW IO space routine 29-Sep-02 RMS Added dynamic table support @@ -101,12 +103,12 @@ extern int32 ssc_bto; extern jmp_buf save_env; extern DEVICE *sim_devices[]; -extern int32 ReadB (t_addr pa); -extern int32 ReadW (t_addr pa); -extern int32 ReadL (t_addr pa); -extern int32 WriteB (t_addr pa, int32 val); -extern int32 WriteW (t_addr pa, int32 val); -extern int32 WriteL (t_addr pa, int32 val); +extern int32 ReadB (uint32 pa); +extern int32 ReadW (uint32 pa); +extern int32 ReadL (uint32 pa); +extern int32 WriteB (uint32 pa, int32 val); +extern int32 WriteW (uint32 pa, int32 val); +extern int32 WriteL (uint32 pa, int32 val); extern FILE *sim_log; t_stat dbl_rd (int32 *data, int32 addr, int32 access); @@ -409,7 +411,7 @@ return; int32 cqmem_rd (int32 pa) { int32 qa = pa & CQMAMASK; /* Qbus addr */ -t_addr ma; +uint32 ma; if (map_addr (qa, &ma)) return M[ma >> 2]; /* map addr */ MACH_CHECK (MCHK_READ); /* err? mcheck */ @@ -419,7 +421,7 @@ return 0; void cqmem_wr (int32 pa, int32 val, int32 lnt) { int32 qa = pa & CQMAMASK; /* Qbus addr */ -t_addr ma; +uint32 ma; if (map_addr (qa, &ma)) { /* map addr */ if (lnt < L_LONG) { @@ -434,7 +436,7 @@ return; /* Map an address via the translation map */ -t_bool map_addr (t_addr qa, t_addr *ma) +t_bool map_addr (uint32 qa, uint32 *ma) { int32 qblk = (qa >> VA_V_VPN); /* Qbus blk */ int32 qmma = ((qblk << 2) & CQMAPAMASK) + cq_mbr; /* map entry */ @@ -511,40 +513,64 @@ return qba_reset (&qba_dev); map_WriteL - store longword buffer into memory */ -int32 map_readB (t_addr ba, int32 bc, uint8 *buf) +int32 map_readB (uint32 ba, int32 bc, uint8 *buf) { int32 i; -t_addr ma; +uint32 ma, dat; -for (i = ma = 0; i < bc; i++, buf++) { /* by bytes */ - if ((ma & VA_M_OFF) == 0) { /* need map? */ - if (!map_addr (ba + i, &ma) || /* inv or NXM? */ - !ADDR_IS_MEM (ma)) return (bc - i); } - *buf = ReadB (ma); - ma = ma + 1; } +if ((ba | bc) & 03) { /* check alignment */ + for (i = ma = 0; i < bc; i++, buf++) { /* by bytes */ + if ((ma & VA_M_OFF) == 0) { /* need map? */ + if (!map_addr (ba + i, &ma) || /* inv or NXM? */ + !ADDR_IS_MEM (ma)) return (bc - i); } + *buf = ReadB (ma); + ma = ma + 1; } + } +else { for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by longwords */ + if ((ma & VA_M_OFF) == 0) { /* need map? */ + if (!map_addr (ba + i, &ma) || /* inv or NXM? */ + !ADDR_IS_MEM (ma)) return (bc - i); } + dat = ReadL (ma); /* get lw */ + *buf++ = dat & BMASK; /* low 8b */ + *buf++ = (dat >> 8) & BMASK; /* next 8b */ + *buf++ = (dat >> 16) & BMASK; /* next 8b */ + *buf = (dat >> 24) & BMASK; + ma = ma + 4; } + } return 0; } -int32 map_readW (t_addr ba, int32 bc, uint16 *buf) +int32 map_readW (uint32 ba, int32 bc, uint16 *buf) { int32 i; -t_addr ma; +uint32 ma,dat; ba = ba & ~01; bc = bc & ~01; -for (i = ma = 0; i < bc; i = i + 2, buf++) { /* by words */ - if ((ma & VA_M_OFF) == 0) { /* need map? */ - if (!map_addr (ba + i, &ma) || /* inv or NXM? */ - !ADDR_IS_MEM (ma)) return (bc - i); } - *buf = ReadW (ma); - ma = ma + 2; } +if ((ba | bc) & 03) { /* check alignment */ + for (i = ma = 0; i < bc; i = i + 2, buf++) { /* by words */ + if ((ma & VA_M_OFF) == 0) { /* need map? */ + if (!map_addr (ba + i, &ma) || /* inv or NXM? */ + !ADDR_IS_MEM (ma)) return (bc - i); } + *buf = ReadW (ma); + ma = ma + 2; } + } +else { for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by longwords */ + if ((ma & VA_M_OFF) == 0) { /* need map? */ + if (!map_addr (ba + i, &ma) || /* inv or NXM? */ + !ADDR_IS_MEM (ma)) return (bc - i); } + dat = ReadL (ma); /* get lw */ + *buf++ = dat & WMASK; /* low 16b */ + *buf = (dat >> 16) & WMASK; /* high 16b */ + ma = ma + 4; } + } return 0; } -int32 map_readL (t_addr ba, int32 bc, uint32 *buf) +int32 map_readL (uint32 ba, int32 bc, uint32 *buf) { int32 i; -t_addr ma; +uint32 ma; ba = ba & ~03; bc = bc & ~03; @@ -557,40 +583,64 @@ for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by lw */ return 0; } -int32 map_writeB (t_addr ba, int32 bc, uint8 *buf) +int32 map_writeB (uint32 ba, int32 bc, uint8 *buf) { int32 i; -t_addr ma; +uint32 ma, dat; -for (i = ma = 0; i < bc; i++, buf++) { /* by bytes */ - if ((ma & VA_M_OFF) == 0) { /* need map? */ - if (!map_addr (ba + i, &ma) || /* inv or NXM? */ - !ADDR_IS_MEM (ma)) return (bc - i); } - WriteB (ma, *buf); - ma = ma + 1; } +if ((ba | bc) & 03) { /* check alignment */ + for (i = ma = 0; i < bc; i++, buf++) { /* by bytes */ + if ((ma & VA_M_OFF) == 0) { /* need map? */ + if (!map_addr (ba + i, &ma) || /* inv or NXM? */ + !ADDR_IS_MEM (ma)) return (bc - i); } + WriteB (ma, *buf); + ma = ma + 1; } + } +else { for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by longwords */ + if ((ma & VA_M_OFF) == 0) { /* need map? */ + if (!map_addr (ba + i, &ma) || /* inv or NXM? */ + !ADDR_IS_MEM (ma)) return (bc - i); } + dat = (uint32) *buf++; /* get low 8b */ + dat = dat | (((uint32) *buf++) << 8); /* merge next 8b */ + dat = dat | (((uint32) *buf++) << 16); /* merge next 8b */ + dat = dat | (((uint32) *buf) << 24); /* merge hi 8b */ + WriteL (ma, dat); /* store lw */ + ma = ma + 4; } + } return 0; } -int32 map_writeW (t_addr ba, int32 bc, uint16 *buf) +int32 map_writeW (uint32 ba, int32 bc, uint16 *buf) { int32 i; -t_addr ma; +uint32 ma, dat; ba = ba & ~01; bc = bc & ~01; -for (i = ma = 0; i < bc; i = i + 2, buf++) { /* by words */ - if ((ma & VA_M_OFF) == 0) { /* need map? */ - if (!map_addr (ba + i, &ma) || /* inv or NXM? */ - !ADDR_IS_MEM (ma)) return (bc - i); } - WriteW (ma, *buf); - ma = ma + 2; } +if ((ba | bc) & 03) { /* check alignment */ + for (i = ma = 0; i < bc; i = i + 2, buf++) { /* by words */ + if ((ma & VA_M_OFF) == 0) { /* need map? */ + if (!map_addr (ba + i, &ma) || /* inv or NXM? */ + !ADDR_IS_MEM (ma)) return (bc - i); } + WriteW (ma, *buf); + ma = ma + 2; } + } +else { for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by longwords */ + if ((ma & VA_M_OFF) == 0) { /* need map? */ + if (!map_addr (ba + i, &ma) || /* inv or NXM? */ + !ADDR_IS_MEM (ma)) return (bc - i); } + dat = (uint32) *buf++; /* get low 16b */ + dat = dat | (((uint32) *buf) << 16); /* merge hi 16b */ + WriteL (ma, dat); /* store lw */ + ma = ma + 4; } + } return 0; } -int32 map_writeL (t_addr ba, int32 bc, uint32 *buf) +int32 map_writeL (uint32 ba, int32 bc, uint32 *buf) { int32 i; -t_addr ma; +uint32 ma; ba = ba & ~03; bc = bc & ~03; @@ -722,9 +772,11 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */ (curr->ba < (dibp->ba + dibp->lnt))) || ((end >= dibp->ba) && /* overlap end? */ (end < (dibp->ba + dibp->lnt)))) { - printf ("Device %s address conflict at %08X\n", dptr->name, dibp->ba); + printf ("Device %s address conflict at %08X\n", + sim_dname (dptr), dibp->ba); if (sim_log) fprintf (sim_log, - "Device %s address conflict at %08X\n", dptr->name, dibp->ba); + "Device %s address conflict at %08X\n", + sim_dname (dptr), dibp->ba); return TRUE; } } return FALSE; } @@ -797,7 +849,7 @@ for (i = 0; dib_tab[i] != NULL; i++) { /* print table */ fprintf (st, "%08X - %08X%c\t%s\n", dib_tab[i]->ba, dib_tab[i]->ba + dib_tab[i]->lnt - 1, (dptr && (dptr->flags & DEV_FLTA))? '*': ' ', - dptr? dptr->name: "CPU"); + dptr? sim_dname (dptr): "CPU"); } return SCPE_OK; } diff --git a/VAX/vax_mmu.c b/VAX/vax_mmu.c index 87c81acb..1f131b23 100644 --- a/VAX/vax_mmu.c +++ b/VAX/vax_mmu.c @@ -1,6 +1,6 @@ /* vax_mm.c - VAX memory management simulator - Copyright (c) 1998-2002, Robert M Supnik + Copyright (c) 1998-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,8 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 01-Jun-03 RMS Fixed compilation problem with USE_ADDR64 + This module contains the instruction simulators for Read - read virtual @@ -95,19 +97,19 @@ t_stat tlb_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); t_stat tlb_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); t_stat tlb_reset (DEVICE *dptr); -TLBENT fill (t_addr va, int32 lnt, int32 acc, int32 *stat); -int32 ReadB (t_addr pa); -void WriteB (t_addr pa, int32 val); -int32 ReadW (t_addr pa); -void WriteW (t_addr pa, int32 val); -int32 ReadL (t_addr pa); -void WriteL (t_addr pa, int32 val); -int32 ReadLP (t_addr pa); -void WriteLP (t_addr pa, int32 val); -extern int32 ReadIO (t_addr pa, int32 lnt); -extern void WriteIO (t_addr pa, int32 val, int32 lnt); -extern int32 ReadReg (t_addr pa, int32 lnt); -extern void WriteReg (t_addr pa, int32 val, int32 lnt); +TLBENT fill (uint32 va, int32 lnt, int32 acc, int32 *stat); +int32 ReadB (uint32 pa); +void WriteB (uint32 pa, int32 val); +int32 ReadW (uint32 pa); +void WriteW (uint32 pa, int32 val); +int32 ReadL (uint32 pa); +void WriteL (uint32 pa, int32 val); +int32 ReadLP (uint32 pa); +void WriteLP (uint32 pa, int32 val); +extern int32 ReadIO (uint32 pa, int32 lnt); +extern void WriteIO (uint32 pa, int32 val, int32 lnt); +extern int32 ReadReg (uint32 pa, int32 lnt); +extern void WriteReg (uint32 pa, int32 val, int32 lnt); /* TLB data structures @@ -156,7 +158,7 @@ DEVICE tlb_dev = { returned data, right justified in 32b longword */ -int32 Read (t_addr va, int32 lnt, int32 acc) +int32 Read (uint32 va, int32 lnt, int32 acc) { int32 vpn, off, tbi, pa; int32 pa1, bo, sc, wl, wh; @@ -209,7 +211,7 @@ else { wl = ReadL (pa); /* word cross lw */ none */ -void Write (t_addr va, int32 val, int32 lnt, int32 acc) +void Write (uint32 va, int32 val, int32 lnt, int32 acc) { int32 vpn, off, tbi, pa; int32 pa1, bo, sc, wl, wh; @@ -289,7 +291,7 @@ return va & PAMASK; /* ret phys addr */ returned data, right justified in 32b longword */ -int32 ReadB (t_addr pa) +int32 ReadB (uint32 pa) { int32 dat; @@ -300,7 +302,7 @@ else { mchk_ref = REF_V; return ((dat >> ((pa & 3) << 3)) & BMASK); } -int32 ReadW (t_addr pa) +int32 ReadW (uint32 pa) { int32 dat; @@ -311,7 +313,7 @@ else { mchk_ref = REF_V; return ((dat >> ((pa & 2)? 16: 0)) & WMASK); } -int32 ReadL (t_addr pa) +int32 ReadL (uint32 pa) { if (ADDR_IS_MEM (pa)) return M[pa >> 2]; mchk_ref = REF_V; @@ -319,7 +321,7 @@ if (ADDR_IS_IO (pa)) return ReadIO (pa, L_LONG); return ReadReg (pa, L_LONG); } -int32 ReadLP (t_addr pa) +int32 ReadLP (uint32 pa) { if (ADDR_IS_MEM (pa)) return M[pa >> 2]; mchk_va = pa; @@ -337,7 +339,7 @@ return ReadReg (pa, L_LONG); none */ -void WriteB (t_addr pa, int32 val) +void WriteB (uint32 pa, int32 val) { if (ADDR_IS_MEM (pa)) { int32 id = pa >> 2; @@ -350,7 +352,7 @@ else { mchk_ref = REF_V; return; } -void WriteW (t_addr pa, int32 val) +void WriteW (uint32 pa, int32 val) { if (ADDR_IS_MEM (pa)) { int32 id = pa >> 2; @@ -362,7 +364,7 @@ else { mchk_ref = REF_V; return; } -void WriteL (t_addr pa, int32 val) +void WriteL (uint32 pa, int32 val) { if (ADDR_IS_MEM (pa)) M[pa >> 2] = val; else { mchk_ref = REF_V; @@ -371,7 +373,7 @@ else { mchk_ref = REF_V; return; } -void WriteLP (t_addr pa, int32 val) +void WriteLP (uint32 pa, int32 val) { if (ADDR_IS_MEM (pa)) M[pa >> 2] = val; else { mchk_va = pa; @@ -398,7 +400,7 @@ return; p2 = va; \ ABORT ((param & PR_TNV)? ABORT_TNV: ABORT_ACV); } -TLBENT fill (t_addr va, int32 lnt, int32 acc, int32 *stat) +TLBENT fill (uint32 va, int32 lnt, int32 acc, int32 *stat) { int32 ptidx = (((uint32) va) >> 7) & ~03; int32 tlbpte, ptead, pte, tbi, vpn; @@ -500,7 +502,7 @@ return FALSE; t_stat tlb_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) { int32 tlbn = uptr - tlb_unit; -int32 idx = addr >> 1; +int32 idx = (uint32) addr >> 1; if (idx >= VA_TBSIZE) return SCPE_NXM; if (addr & 1) *vptr = ((uint32) (tlbn? stlb[idx].pte: ptlb[idx].pte)); @@ -513,7 +515,7 @@ return SCPE_OK; t_stat tlb_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) { int32 tlbn = uptr - tlb_unit; -int32 idx = addr >> 1; +int32 idx = (uint32) addr >> 1; if (idx >= VA_TBSIZE) return SCPE_NXM; if (addr & 1) { diff --git a/VAX/vax_stddev.c b/VAX/vax_stddev.c index 1c184c3f..e33a2b40 100644 --- a/VAX/vax_stddev.c +++ b/VAX/vax_stddev.c @@ -27,6 +27,7 @@ tto terminal output clk 100Hz and TODR clock + 25-Apr-03 RMS Revised for extended file support 02-Mar-02 RMS Added SET TTI CTRL-C 22-Dec-02 RMS Added console halt capability 01-Nov-02 RMS Added 7B/8B capability to terminal @@ -93,7 +94,7 @@ REG tti_reg[] = { { FLDATA (INT, int_req[IPL_TTI], INT_V_TTI) }, { FLDATA (DONE, tti_csr, CSR_V_DONE) }, { FLDATA (IE, tti_csr, CSR_V_IE) }, - { DRDATA (POS, tti_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT }, { NULL } }; @@ -130,7 +131,7 @@ REG tto_reg[] = { { FLDATA (INT, int_req[IPL_TTO], INT_V_TTO) }, { FLDATA (DONE, tto_csr, CSR_V_DONE) }, { FLDATA (IE, tto_csr, CSR_V_IE) }, - { DRDATA (POS, tto_unit.pos, 32), PV_LEFT }, + { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT }, { NULL } }; diff --git a/VAX/vax_sys.c b/VAX/vax_sys.c index e05c4526..2933fd2e 100644 --- a/VAX/vax_sys.c +++ b/VAX/vax_sys.c @@ -1,6 +1,6 @@ /* vax_sys.c: VAX simulator interface - Copyright (c) 1998-2002, Robert M Supnik + Copyright (c) 1998-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 06-May-03 RMS Added support for second DELQA 12-Oct-02 RMS Added multiple RQ controller support 10-Oct-02 RMS Added DELQA support 21-Sep-02 RMS Extended symbolic ex/mod to all byte devices @@ -33,17 +34,23 @@ #include "vax_defs.h" #include -extern DEVICE cpu_dev, tlb_dev; -extern DEVICE rom_dev, nvr_dev; -extern DEVICE sysd_dev, qba_dev; +extern DEVICE cpu_dev; +extern DEVICE tlb_dev; +extern DEVICE rom_dev; +extern DEVICE nvr_dev; +extern DEVICE sysd_dev; +extern DEVICE qba_dev; extern DEVICE ptr_dev, ptp_dev; extern DEVICE tti_dev, tto_dev; extern DEVICE csi_dev, cso_dev; -extern DEVICE lpt_dev, clk_dev; +extern DEVICE lpt_dev; +extern DEVICE clk_dev; extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev; extern DEVICE rl_dev; -extern DEVICE ts_dev, tq_dev; -extern DEVICE dz_dev, xq_dev; +extern DEVICE ts_dev; +extern DEVICE tq_dev; +extern DEVICE dz_dev; +extern DEVICE xq_dev, xqb_dev; extern UNIT cpu_unit; extern REG cpu_reg[]; extern uint32 *M; @@ -52,12 +59,12 @@ extern int32 sim_switches; extern void WriteB (int32 pa, int32 val); extern void rom_wr (int32 pa, int32 val, int32 lnt); -t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val); +t_stat fprint_sym_m (FILE *of, uint32 addr, t_value *val); int32 fprint_sym_qoimm (FILE *of, t_value *val, int32 vp, int32 lnt); -t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val); -int32 parse_brdisp (char *cptr, t_addr addr, t_value *val, +t_stat parse_sym_m (char *cptr, uint32 addr, t_value *val); +int32 parse_brdisp (char *cptr, uint32 addr, t_value *val, int32 vp, int32 lnt, t_stat *r); -int32 parse_spec (char *cptr, t_addr addr, t_value *val, +int32 parse_spec (char *cptr, uint32 addr, t_value *val, int32 vp, int32 disp, t_stat *r); char *parse_rnum (char *cptr, int32 *rn); int32 parse_sym_qoimm (int32 *lit, t_value *val, int32 vp, @@ -103,6 +110,7 @@ DEVICE *sim_devices[] = { &ts_dev, &tq_dev, &xq_dev, + &xqb_dev, NULL }; const char *sim_stop_messages[] = { @@ -135,7 +143,7 @@ t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) { t_stat r; int32 i; -t_addr origin, limit; +uint32 origin, limit; extern int32 ssc_cnf; #define SSCCNF_BLO 0x80000000 @@ -148,7 +156,7 @@ else if (sim_switches & SWMASK ('N')) { /* NVR? */ limit = NVRBASE + NVRSIZE; ssc_cnf = ssc_cnf & ~SSCCNF_BLO; } else { origin = 0; /* memory */ - limit = cpu_unit.capac; + limit = (uint32) cpu_unit.capac; if (sim_switches & SWMASK ('O')) { /* origin? */ origin = (int32) get_uint (cptr, 16, 0xFFFFFFFF, &r); if (r != SCPE_OK) return SCPE_ARG; } } @@ -189,7 +197,7 @@ int32 *buf; if ((sec < 2) || (wds < 16)) return SCPE_ARG; if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; if (!get_yn ("Overwrite last track? [N]", FALSE)) return SCPE_OK; -da = (uptr->capac - (sec * wds)) * sizeof (int16); +da = (int32) (uptr->capac - (sec * wds)) * sizeof (int16); if (fseek (uptr->fileref, da, SEEK_SET)) return SCPE_IOERR; if ((buf = malloc (wds * sizeof (int32))) == NULL) return SCPE_MEM; buf[0] = 0x12345678; @@ -821,9 +829,10 @@ const char* regname[] = { if < 0, number of extra bytes retired */ -t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, +t_stat fprint_sym (FILE *of, t_addr exta, t_value *val, UNIT *uptr, int32 sw) { +uint32 addr = (uint32) exta; int32 c, k, num, vp, lnt, rdx; t_stat r; DEVICE *dptr; @@ -869,7 +878,7 @@ return -(vp - 1); if < 0, number of extra bytes retired */ -t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val) +t_stat fprint_sym_m (FILE *of, uint32 addr, t_value *val) { int32 i, k, vp, inst, numspec; int32 num, spec, rn, disp, index; @@ -999,8 +1008,9 @@ return vp; <= 0 -number of extra words */ -t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) +t_stat parse_sym (char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw) { +uint32 addr = (uint32) exta; int32 k, rdx, lnt, num, vp; t_stat r; DEVICE *dptr; @@ -1047,7 +1057,7 @@ return -(lnt - 1); <= 0 -number of extra words */ -t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val) +t_stat parse_sym_m (char *cptr, uint32 addr, t_value *val) { int32 i, numspec, disp, opc, vp; t_stat r; @@ -1090,7 +1100,7 @@ return -(vp - 1); vp = updated output pointer */ -int32 parse_brdisp (char *cptr, t_addr addr, t_value *val, int32 vp, +int32 parse_brdisp (char *cptr, uint32 addr, t_value *val, int32 vp, int32 lnt, t_stat *r) { int32 k, dest, num; @@ -1133,7 +1143,7 @@ return vp; #define PARSE_LOSE { *r = SCPE_ARG; return vp; } #define SEL_LIM(p,m,u) ((fl & SP_PLUS)? (p): ((fl & SP_MINUS)? (m): (u))) -int32 parse_spec (char *cptr, t_addr addr, t_value *val, int32 vp, int32 disp, t_stat *r) +int32 parse_spec (char *cptr, uint32 addr, t_value *val, int32 vp, int32 disp, t_stat *r) { int32 i, k, litsize, rn, index; int32 num, dispsize, mode; diff --git a/VAX/vax_sysdev.c b/VAX/vax_sysdev.c index 943c96fb..77214ad1 100644 --- a/VAX/vax_sysdev.c +++ b/VAX/vax_sysdev.c @@ -1,6 +1,6 @@ /* vax_sysreg.c: VAX system registers simulator - Copyright (c) 1998-2002, Robert M Supnik + Copyright (c) 1998-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -33,6 +33,10 @@ cso console storage output sysd system devices (SSC miscellany) + 7-Jun-03 MP Added calibrated delay to ROM reads (from Mark Pizzolato) + Fixed calibration problems interval timer (from Mark Pizzolato) + 12-May-03 RMS Fixed compilation warnings from VC.Net + 23-Apr-03 RMS Revised for 32b/64b t_addr 19-Aug-02 RMS Removed unused variables (found by David Hittner) Allowed NVR to be attached to file 30-May-02 RMS Widened POS to 32b @@ -41,6 +45,9 @@ #include "vax_defs.h" +#define UNIT_V_NODELAY (UNIT_V_UF + 0) /* ROM access equal to RAM access */ +#define UNIT_NODELAY (1u << UNIT_V_NODELAY) + /* Console storage control/status */ #define CSICSR_IMP (CSR_DONE + CSR_IE) /* console input */ @@ -156,6 +163,7 @@ extern int32 int_req[IPL_HLVL]; extern UNIT cpu_unit; +extern UNIT clk_unit; extern jmp_buf save_env; extern int32 p1; extern int32 sim_switches; @@ -182,12 +190,13 @@ uint32 tmr_sav[2] = { 0 }; /* saved inst cnt */ int32 ssc_adsm[2] = { 0 }; /* addr strobes */ int32 ssc_adsk[2] = { 0 }; int32 cdg_dat[CDASIZE >> 2]; /* cache data */ +static uint32 rom_delay = 0; -t_stat rom_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); -t_stat rom_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); +t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); +t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw); t_stat rom_reset (DEVICE *dptr); -t_stat nvr_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); -t_stat nvr_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); +t_stat nvr_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); +t_stat nvr_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw); t_stat nvr_reset (DEVICE *dptr); t_stat nvr_attach (UNIT *uptr, char *cptr); t_stat nvr_detach (UNIT *uptr); @@ -241,6 +250,7 @@ extern void rxcs_wr (int32 dat); extern void txcs_wr (int32 dat); extern void txdb_wr (int32 dat); extern void ioreset_wr (int32 dat); +extern uint32 sim_os_msec(); /* ROM data structures @@ -254,8 +264,13 @@ UNIT rom_unit = { UDATA (NULL, UNIT_FIX+UNIT_BINK, ROMSIZE) }; REG rom_reg[] = { { NULL } }; +MTAB rom_mod[] = { + { UNIT_NODELAY, UNIT_NODELAY, "fast access", "NODELAY", NULL }, + { UNIT_NODELAY, 0, "1usec calibrated access", "DELAY", NULL }, + { 0 } }; + DEVICE rom_dev = { - "ROM", &rom_unit, rom_reg, NULL, + "ROM", &rom_unit, rom_reg, rom_mod, 1, 16, ROMAWIDTH, 4, 16, 32, &rom_ex, &rom_dep, &rom_reset, NULL, NULL, NULL, @@ -395,13 +410,70 @@ DEVICE sysd_dev = { /* ROM: read only memory - stored in a buffered file Register space access routines see ROM twice + + ROM access has been 'regulated' to about 1Mhz to avoid issues + with testing the interval timers in self-test. Specifically, + the VAX boot ROM (ka655.bin) contains code which presumes that + the VAX runs at a particular slower speed when code is running + from ROM (which is not cached). These assumptions are built + into instruction based timing loops. As the host platform gets + much faster than the original VAX, the assumptions embedded in + these code loops are no longer valid. + + Code has been added to the ROM implementation to limit CPU speed + to about 500K instructions per second. This heads off any future + issues with the embedded timing loops. */ +int32 rom_swapb(int32 val) +{ +return ((val << 24) & 0xff000000) | (( val << 8) & 0xff0000) | + ((val >> 8) & 0xff00) | ((val >> 24) & 0xff); +} + +int32 rom_read_delay (int32 val) +{ +uint32 i, l = rom_delay; +int32 loopval = 0; + +if (rom_unit.flags & UNIT_NODELAY) return val; + +/* Calibrate the loop delay factor when first used. + Do this 4 times to and use the largest value computed. */ + +if (rom_delay == 0) { + uint32 ts, te, c = 10000, samples = 0; + while (1) { + c = c * 2; + te = sim_os_msec(); + while (te == (ts = sim_os_msec ())); /* align on ms tick */ + +/* This is merely a busy wait with some "work" that won't get optimized + away by a good compiler. loopval always is zero. To avoid smart compilers, + the loopval variable is referenced in the function arguments so that the + function expression is not loop invariant. It also must be referenced + by subsequent code or to avoid the whole computation being eliminated. */ + + for (i = 0; i < c; i++) + loopval |= (loopval + ts) ^ rom_swapb (rom_swapb (loopval + ts)); + te = sim_os_msec (); + if ((te - ts) < 50) continue; /* sample big enough? */ + if (rom_delay < (loopval + (c / (te - ts) / 1000) + 1)) + rom_delay = loopval + (c / (te - ts) / 1000) + 1; + if (++samples >= 4) break; + c = c / 2; } + if (rom_delay < 5) rom_delay = 5; } + +for (i = 0; i < l; i++) + loopval |= (loopval + val) ^ rom_swapb (rom_swapb (loopval + val)); +return val + loopval; +} + int32 rom_rd (int32 pa) { int32 rg = ((pa - ROMBASE) & ROMAMASK) >> 2; -return rom[rg]; +return rom_read_delay (rom[rg]); } void rom_wr (int32 pa, int32 val, int32 lnt) @@ -418,8 +490,10 @@ return; /* ROM examine */ -t_stat rom_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) +t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) { +uint32 addr = (uint32) exta; + if ((vptr == NULL) || (addr & 03)) return SCPE_ARG; if (addr >= ROMSIZE) return SCPE_NXM; *vptr = rom[addr >> 2]; @@ -428,8 +502,10 @@ return SCPE_OK; /* ROM deposit */ -t_stat rom_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) +t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw) { +uint32 addr = (uint32) exta; + if (addr & 03) return SCPE_ARG; if (addr >= ROMSIZE) return SCPE_NXM; rom[addr >> 2] = (uint32) val; @@ -468,8 +544,10 @@ return; /* NVR examine */ -t_stat nvr_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) +t_stat nvr_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) { +uint32 addr = (uint32) exta; + if ((vptr == NULL) || (addr & 03)) return SCPE_ARG; if (addr >= NVRSIZE) return SCPE_NXM; *vptr = nvr[addr >> 2]; @@ -478,8 +556,10 @@ return SCPE_OK; /* NVR deposit */ -t_stat nvr_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) +t_stat nvr_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw) { +uint32 addr = (uint32) exta; + if (addr & 03) return SCPE_ARG; if (addr >= NVRSIZE) return SCPE_NXM; nvr[addr >> 2] = (uint32) val; @@ -711,8 +791,8 @@ return; struct reglink { /* register linkage */ int32 low; /* low addr */ int32 high; /* high addr */ - t_stat (*read)(); /* read routine */ - void (*write)(); }; /* write routine */ + t_stat (*read)(int32 pa); /* read routine */ + void (*write)(int32 pa, int32 val, int32 lnt); }; /* write routine */ struct reglink regtable[] = { { CQMAPBASE, CQMAPBASE+CQMAPSIZE, &cqmap_rd, &cqmap_wr }, @@ -1031,13 +1111,31 @@ return; clock events per second. Instead, a gross hack is used. When a timer is started, the clock interval is inspected. - if (int < 0 and small) then testing timer, count instructions + if (int < 0 and small) then testing timer, count instructions. + Small is determined by when the requested interval is less + than the size of a 100hz system clock tick. if (int >= 0 or large) then counting a real interval, schedule clock events at 100Hz using calibrated line clock delay + and when the remaining time value gets small enough, behave + like the small case above. If the interval register is read, then its value between events is interpolated using the current instruction count versus the - count when the most recent event started. + count when the most recent event started, the result is scaled + to the calibrated system clock, unless the interval being timed + is less than a calibrated system clock tick (or the calibrated + clock is running very slowly) at which time the result will be + the elapsed instruction count. + + The powerup TOY Test sometimes fails its tolerance test. This was + due to varying system load causing varying calibration values to be + used at different times while referencing the TIR. While timing long + intervals, we now synchronize the stepping (and calibration) of the + system tick with the opportunity to reference the value. This gives + precise tolerance measurement values (when interval timers are used + to measure the system clock), regardless of other load issues on the + host system which might cause varying values of the system clock's + calibration factor. */ int32 tmr_tir_rd (int32 tmr, t_bool interp) @@ -1046,6 +1144,9 @@ uint32 delta; if (interp || (tmr_csr[tmr] & TMR_CSR_RUN)) { /* interp, running? */ delta = sim_grtime () - tmr_sav[tmr]; /* delta inst */ + if ((tmr_inc[tmr] == TMR_INC) && /* scale large int */ + (tmr_poll > TMR_INC)) + delta = (uint32) ((((double) delta) * TMR_INC) / tmr_poll); if (delta >= tmr_inc[tmr]) delta = tmr_inc[tmr] - 1; return tmr_tir[tmr] + delta; } return tmr_tir[tmr]; @@ -1117,12 +1218,27 @@ return; void tmr_sched (int32 tmr) { +int32 clk_time = sim_is_active (&clk_unit) - 1; +int32 tmr_time; + tmr_sav[tmr] = sim_grtime (); /* save intvl base */ if (tmr_tir[tmr] > (0xFFFFFFFFu - TMR_INC)) { /* short interval? */ tmr_inc[tmr] = (~tmr_tir[tmr] + 1); /* inc = interval */ - sim_activate (&sysd_unit[tmr], tmr_inc[tmr]); } + tmr_time = tmr_inc[tmr]; } else { tmr_inc[tmr] = TMR_INC; /* usec/interval */ - sim_activate (&sysd_unit[tmr], tmr_poll); } /* use calib clock */ + tmr_time = tmr_poll; } +if (tmr_time == 0) tmr_time = 1; +if ((tmr_inc[tmr] = TMR_INC) && (tmr_time > clk_time)) { + +/* Align scheduled event to be identical to the event for the next clock + tick. This lets us always see a consistent calibrated value, both for + this scheduling, AND for any query of the current timer register that + may happen in tmr_tir_rd (). This presumes that sim_activate will + queue the interval timer behind the event for the clock tick. */ + + tmr_inc[tmr] = (uint32) (((double) clk_time * TMR_INC) / tmr_poll); + tmr_time = clk_time; } +sim_activate (&sysd_unit[tmr], tmr_time); return; } diff --git a/VAX/vaxmod_defs.h b/VAX/vaxmod_defs.h index 8dc75397..66a72894 100644 --- a/VAX/vaxmod_defs.h +++ b/VAX/vaxmod_defs.h @@ -85,7 +85,7 @@ #define MAXMEMMASK (MAXMEMSIZE - 1) /* max mem addr mask */ #define INITMEMSIZE (1 << 24) /* initial memory size */ #define MEMSIZE (cpu_unit.capac) -#define ADDR_IS_MEM(x) (((t_addr) (x)) < MEMSIZE) +#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE) /* Cache diagnostic space */ @@ -101,8 +101,8 @@ #define CDG_GETTAG(x) (((x) >> CDAAWIDTH) & CTGMASK) #define CTG_V (1u << (CTGAWIDTH + 0)) /* tag valid */ #define CTG_WP (1u << (CTGAWIDTH + 1)) /* wrong parity */ -#define ADDR_IS_CDG(x) ((((t_addr) (x)) >= CDGBASE) && \ - (((t_addr) (x)) < (CDGBASE + CDGSIZE))) +#define ADDR_IS_CDG(x) ((((uint32) (x)) >= CDGBASE) && \ + (((uint32) (x)) < (CDGBASE + CDGSIZE))) /* Qbus I/O registers */ @@ -110,8 +110,8 @@ #define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */ #define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */ #define IOPAGEBASE 0x20000000 /* IO page base */ -#define ADDR_IS_IO(x) ((((t_addr) (x)) >= IOPAGEBASE) && \ - (((t_addr) (x)) < (IOPAGEBASE + IOPAGESIZE))) +#define ADDR_IS_IO(x) ((((uint32) (x)) >= IOPAGEBASE) && \ + (((uint32) (x)) < (IOPAGEBASE + IOPAGESIZE))) /* Read only memory - appears twice */ @@ -119,8 +119,8 @@ #define ROMSIZE (1u << ROMAWIDTH) /* ROM length */ #define ROMAMASK (ROMSIZE - 1) /* ROM addr mask */ #define ROMBASE 0x20040000 /* ROM base */ -#define ADDR_IS_ROM(x) ((((t_addr) (x)) >= ROMBASE) && \ - (((t_addr) (x)) < (ROMBASE + ROMSIZE + ROMSIZE))) +#define ADDR_IS_ROM(x) ((((uint32) (x)) >= ROMBASE) && \ + (((uint32) (x)) < (ROMBASE + ROMSIZE + ROMSIZE))) /* Local register space */ @@ -161,8 +161,8 @@ #define NVRSIZE (1u << NVRAWIDTH) /* NVR length */ #define NVRAMASK (NVRSIZE - 1) /* NVR addr mask */ #define NVRBASE 0x20140400 /* NVR base */ -#define ADDR_IS_NVR(x) ((((t_addr) (x)) >= NVRBASE) && \ - (((t_addr) (x)) < (NVRBASE + NVRSIZE))) +#define ADDR_IS_NVR(x) ((((uint32) (x)) >= NVRBASE) && \ + (((uint32) (x)) < (NVRBASE + NVRSIZE))) /* CQBIC Qbus memory space (seen from CVAX) */ @@ -211,6 +211,8 @@ #define UNIBUS FALSE /* 22b only */ +#define DEV_RDX 16 /* default device radix */ + /* Device information block */ #define VEC_DEVMAX 4 /* max device vec */ @@ -223,7 +225,7 @@ struct pdp_dib { int32 vnum; /* vectors: number */ int32 vloc; /* locator */ int32 vec; /* value */ - int32 (*ack[VEC_DEVMAX])(void); /* ack routines */ + int32 (*ack[VEC_DEVMAX])(void); /* ack routine */ }; typedef struct pdp_dib DIB; @@ -386,13 +388,13 @@ typedef struct pdp_dib DIB; /* Function prototypes for I/O */ -t_bool map_addr (t_addr qa, t_addr *ma); -int32 map_readB (t_addr ba, int32 bc, uint8 *buf); -int32 map_readW (t_addr ba, int32 bc, uint16 *buf); -int32 map_readL (t_addr ba, int32 bc, uint32 *buf); -int32 map_writeB (t_addr ba, int32 bc, uint8 *buf); -int32 map_writeW (t_addr ba, int32 bc, uint16 *buf); -int32 map_writeL (t_addr ba, int32 bc, uint32 *buf); +t_bool map_addr (uint32 qa, uint32 *ma); +int32 map_readB (uint32 ba, int32 bc, uint8 *buf); +int32 map_readW (uint32 ba, int32 bc, uint16 *buf); +int32 map_readL (uint32 ba, int32 bc, uint32 *buf); +int32 map_writeB (uint32 ba, int32 bc, uint8 *buf); +int32 map_writeW (uint32 ba, int32 bc, uint16 *buf); +int32 map_writeL (uint32 ba, int32 bc, uint32 *buf); #define Map_Addr(a,b) map_addr (a, b) #define Map_ReadB(a,b,c,d) map_readB (a, b, c) diff --git a/dec_dz.h b/dec_dz.h deleted file mode 100644 index fd9318c0..00000000 --- a/dec_dz.h +++ /dev/null @@ -1,627 +0,0 @@ -/* dec_dz.c: DZ11 terminal multiplexor simulator - - Copyright (c) 2001-2002, Robert M Supnik - - 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 - ROBERT M SUPNIK 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. - - Except as contained in this notice, the name of Robert M Supnik shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - Based on the original DZ11 simulator by Thord Nilson, as updated by - Arthur Krewat. - - dz DZ11 terminal multiplexor - - 22-Dec-02 RMS Added break (framing error) support - 31-Oct-02 RMS Added 8b support - 12-Oct-02 RMS Added autoconfigure support - 29-Sep-02 RMS Fixed bug in set number of lines routine - Added variable vector support - New data structures - 22-Apr-02 RMS Updated for changes in sim_tmxr - 28-Apr-02 RMS Fixed interrupt acknowledge, fixed SHOW DZ ADDRESS - 14-Jan-02 RMS Added multiboard support - 30-Dec-01 RMS Added show statistics, set disconnect - Removed statistics registers - 03-Dec-01 RMS Modified for extended SET/SHOW - 09-Nov-01 RMS Added VAX support - 20-Oct-01 RMS Moved getchar from sim_tmxr, changed interrupt - logic to use tmxr_rqln - 06-Oct-01 RMS Fixed bug in carrier detect logic - 03-Oct-01 RMS Added support for BSD-style "ringless" modems - 27-Sep-01 RMS Fixed bug in xmte initialization - 17-Sep-01 RMS Added separate autodisconnect switch - 16-Sep-01 RMS Fixed modem control bit offsets - - This file is intended to be included in a shell routine that invokes - a simulator definition file: - - pdp11_dz.c = pdp11_defs.h + dec_dz.h - pdp10_dz.c = pdp10_defs.h + dec_dz.h - vax_dz.c = vax_defs.h + dec_dz.h -*/ - -#include "sim_sock.h" -#include "sim_tmxr.h" - -#if !defined (DZ_RDX) -#define DZ_RDX 8 -#endif -#if !defined (DZ_MUXES) -#define DZ_MUXES 1 -#endif -#if !defined (DZ_LINES) -#define DZ_LINES 8 -#endif -#if !defined (DZ_8B_DFLT) -#define DZ_8B_DFLT 0 -#endif - -#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */ -#define UNIT_8B (1 << UNIT_V_8B) - -#define DZ_MNOMASK (DZ_MUXES - 1) /* mask for mux no */ -#define DZ_LNOMASK (DZ_LINES - 1) /* mask for lineno */ -#define DZ_LMASK ((1 << DZ_LINES) - 1) /* mask of lines */ -#define DZ_SILO_ALM 16 /* silo alarm level */ - -/* DZCSR - 160100 - control/status register */ - -#define CSR_MAINT 0000010 /* maint - NI */ -#define CSR_CLR 0000020 /* clear */ -#define CSR_MSE 0000040 /* master scan enb */ -#define CSR_RIE 0000100 /* rcv int enb */ -#define CSR_RDONE 0000200 /* rcv done - RO */ -#define CSR_V_TLINE 8 /* xmit line - RO */ -#define CSR_TLINE (DZ_LNOMASK << CSR_V_TLINE) -#define CSR_SAE 0010000 /* silo alm enb */ -#define CSR_SA 0020000 /* silo alm - RO */ -#define CSR_TIE 0040000 /* xmit int enb */ -#define CSR_TRDY 0100000 /* xmit rdy - RO */ -#define CSR_RW (CSR_MSE | CSR_RIE | CSR_SAE | CSR_TIE) -#define CSR_MBZ (0004003 | CSR_CLR | CSR_MAINT) - -#define CSR_GETTL(x) (((x) >> CSR_V_TLINE) & DZ_LNOMASK) -#define CSR_PUTTL(x,y) x = ((x) & ~CSR_TLINE) | (((y) & DZ_LNOMASK) << CSR_V_TLINE) - -/* DZRBUF - 160102 - receive buffer, read only */ - -#define RBUF_CHAR 0000377 /* rcv char */ -#define RBUF_V_RLINE 8 /* rcv line */ -#define RBUF_PARE 0010000 /* parity err - NI */ -#define RBUF_FRME 0020000 /* frame err */ -#define RBUF_OVRE 0040000 /* overrun err - NI */ -#define RBUF_VALID 0100000 /* rcv valid */ -#define RBUF_MBZ 0004000 - -/* DZLPR - 160102 - line parameter register, write only, word access only */ - -#define LPR_V_LINE 0 /* line */ -#define LPR_LPAR 0007770 /* line pars - NI */ -#define LPR_RCVE 0010000 /* receive enb */ -#define LPR_GETLN(x) (((x) >> LPR_V_LINE) & DZ_LNOMASK) - -/* DZTCR - 160104 - transmission control register */ - -#define TCR_V_XMTE 0 /* xmit enables */ -#define TCR_V_DTR 8 /* DTRs */ - -/* DZMSR - 160106 - modem status register, read only */ - -#define MSR_V_RI 0 /* ring indicators */ -#define MSR_V_CD 8 /* carrier detect */ - -/* DZTDR - 160106 - transmit data, write only */ - -#define TDR_CHAR 0000377 /* xmit char */ -#define TDR_V_TBR 8 /* xmit break - NI */ - -extern int32 IREQ (HLVL); -extern int32 sim_switches; -extern FILE *sim_log; -extern int32 tmxr_poll; /* calibrated delay */ - -uint16 dz_csr[DZ_MUXES] = { 0 }; /* csr */ -uint16 dz_rbuf[DZ_MUXES] = { 0 }; /* rcv buffer */ -uint16 dz_lpr[DZ_MUXES] = { 0 }; /* line param */ -uint16 dz_tcr[DZ_MUXES] = { 0 }; /* xmit control */ -uint16 dz_msr[DZ_MUXES] = { 0 }; /* modem status */ -uint16 dz_tdr[DZ_MUXES] = { 0 }; /* xmit data */ -uint8 dz_sae[DZ_MUXES] = { 0 }; /* silo alarm enabled */ -uint32 dz_rxi = 0; /* rcv interrupts */ -uint32 dz_txi = 0; /* xmt interrupts */ -int32 dz_mctl = 0; /* modem ctrl enabled */ -int32 dz_auto = 0; /* autodiscon enabled */ -TMLN dz_ldsc[DZ_MUXES * DZ_LINES] = { 0 }; /* line descriptors */ -TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, NULL }; /* mux descriptor */ - -DEVICE dz_dev; -t_stat dz_rd (int32 *data, int32 PA, int32 access); -t_stat dz_wr (int32 data, int32 PA, int32 access); -int32 dz_rxinta (void); -int32 dz_txinta (void); -t_stat dz_svc (UNIT *uptr); -t_stat dz_reset (DEVICE *dptr); -t_stat dz_attach (UNIT *uptr, char *cptr); -t_stat dz_detach (UNIT *uptr); -t_stat dz_clear (int32 dz, t_bool flag); -int32 dz_getc (int32 dz); -void dz_update_rcvi (void); -void dz_update_xmti (void); -void dz_clr_rxint (int32 dz); -void dz_set_rxint (int32 dz); -void dz_clr_txint (int32 dz); -void dz_set_txint (int32 dz); -t_stat dz_summ (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat dz_show (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat dz_show_vec (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat dz_setnl (UNIT *uptr, int32 val, char *cptr, void *desc); - -/* DZ data structures - - dz_dev DZ device descriptor - dz_unit DZ unit list - dz_reg DZ register list -*/ - -DIB dz_dib = { IOBA_DZ, IOLN_DZ * DZ_MUXES, &dz_rd, &dz_wr, - 2, IVCL (DZRX), VEC_DZRX, { &dz_rxinta, &dz_txinta } }; - -UNIT dz_unit = { UDATA (&dz_svc, UNIT_ATTABLE + DZ_8B_DFLT, 0) }; - -REG dz_nlreg = { DRDATA (NLINES, dz_desc.lines, 6), PV_LEFT }; - -REG dz_reg[] = { - { BRDATA (CSR, dz_csr, DZ_RDX, 16, DZ_MUXES) }, - { BRDATA (RBUF, dz_rbuf, DZ_RDX, 16, DZ_MUXES) }, - { BRDATA (LPR, dz_lpr, DZ_RDX, 16, DZ_MUXES) }, - { BRDATA (TCR, dz_tcr, DZ_RDX, 16, DZ_MUXES) }, - { BRDATA (MSR, dz_msr, DZ_RDX, 16, DZ_MUXES) }, - { BRDATA (TDR, dz_tdr, DZ_RDX, 16, DZ_MUXES) }, - { BRDATA (SAENB, dz_sae, DZ_RDX, 1, DZ_MUXES) }, - { GRDATA (RXINT, dz_rxi, DZ_RDX, DZ_MUXES, 0) }, - { GRDATA (TXINT, dz_txi, DZ_RDX, DZ_MUXES, 0) }, - { FLDATA (MDMCTL, dz_mctl, 0) }, - { FLDATA (AUTODS, dz_auto, 0) }, - { GRDATA (DEVADDR, dz_dib.ba, DZ_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, dz_dib.vec, DZ_RDX, 16, 0), REG_HRO }, - { NULL } }; - -MTAB dz_mod[] = { - { UNIT_8B, 0, "7b", "7B", NULL }, - { UNIT_8B, UNIT_8B, "8b", "8B", NULL }, - { MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT", - &tmxr_dscln, NULL, &dz_desc }, - { UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &dz_summ }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL, - NULL, &dz_show, NULL }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL, - NULL, &dz_show, NULL }, - { MTAB_XTD|MTAB_VDV, 010, "ADDRESS", "ADDRESS", - &set_addr, &show_addr, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", - &set_vec, &dz_show_vec, NULL }, -#if !defined (VM_PDP10) - { MTAB_XTD | MTAB_VDV, 0, NULL, "AUTOCONFIGURE", - &set_addr_flt, NULL, NULL }, -#endif - { MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES", - &dz_setnl, NULL, &dz_nlreg }, - { 0 } }; - -DEVICE dz_dev = { - "DZ", &dz_unit, dz_reg, dz_mod, - 1, DZ_RDX, 8, 1, DZ_RDX, 8, - &tmxr_ex, &tmxr_dep, &dz_reset, - NULL, &dz_attach, &dz_detach, - &dz_dib, DEV_FLTA | DEV_DISABLE | DEV_UBUS | DEV_QBUS }; - -/* IO dispatch routines, I/O addresses 177601x0 - 177601x7 */ - -t_stat dz_rd (int32 *data, int32 PA, int32 access) -{ -int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */ - -switch ((PA >> 1) & 03) { /* case on PA<2:1> */ -case 00: /* CSR */ - *data = dz_csr[dz] = dz_csr[dz] & ~CSR_MBZ; - break; -case 01: /* RBUF */ - dz_csr[dz] = dz_csr[dz] & ~CSR_SA; /* clr silo alarm */ - if (dz_csr[dz] & CSR_MSE) { /* scanner on? */ - dz_rbuf[dz] = dz_getc (dz); /* get top of silo */ - if (!dz_rbuf[dz]) dz_sae[dz] = 1; /* empty? re-enable */ - tmxr_poll_rx (&dz_desc); /* poll input */ - dz_update_rcvi (); } /* update rx intr */ - else { - dz_rbuf[dz] = 0; /* no data */ - dz_update_rcvi (); } /* no rx intr */ - *data = dz_rbuf[dz]; - break; -case 02: /* TCR */ - *data = dz_tcr[dz]; - break; -case 03: /* MSR */ - *data = dz_msr[dz]; - break; } -return SCPE_OK; -} - -t_stat dz_wr (int32 data, int32 PA, int32 access) -{ -int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */ -int32 i, line; -TMLN *lp; - -switch ((PA >> 1) & 03) { /* case on PA<2:1> */ -case 00: /* CSR */ - if (access == WRITEB) data = (PA & 1)? /* byte? merge */ - (dz_csr[dz] & 0377) | (data << 8): - (dz_csr[dz] & ~0377) | data; - if (data & CSR_CLR) dz_clear (dz, FALSE); /* clr? reset */ - if (data & CSR_MSE) sim_activate (&dz_unit, tmxr_poll); - else dz_csr[dz] &= ~(CSR_SA | CSR_RDONE | CSR_TRDY); - if ((data & CSR_RIE) == 0) dz_clr_rxint (dz); /* RIE = 0? */ - else if (((dz_csr[dz] & CSR_IE) == 0) && /* RIE 0->1? */ - ((dz_csr[dz] & CSR_SAE)? - (dz_csr[dz] & CSR_SA): (dz_csr[dz] & CSR_RDONE))) - dz_set_rxint (dz); - if ((data & CSR_TIE) == 0) dz_clr_txint (dz); /* TIE = 0? */ - else if (((dz_csr[dz] & CSR_TIE) == 0) && (dz_csr[dz] & CSR_TRDY)) - dz_set_txint (dz); - dz_csr[dz] = (dz_csr[dz] & ~CSR_RW) | (data & CSR_RW); - break; -case 01: /* LPR */ - dz_lpr[dz] = data; - line = (dz * DZ_LINES) + LPR_GETLN (data); /* get line num */ - lp = &dz_ldsc[line]; /* get line desc */ - if (dz_lpr[dz] & LPR_RCVE) lp->rcve = 1; /* rcv enb? on */ - else lp->rcve = 0; /* else line off */ - tmxr_poll_rx (&dz_desc); /* poll input */ - dz_update_rcvi (); /* update rx intr */ - break; -case 02: /* TCR */ - if (access == WRITEB) data = (PA & 1)? /* byte? merge */ - (dz_tcr[dz] & 0377) | (data << 8): - (dz_tcr[dz] & ~0377) | data; - if (dz_mctl) { /* modem ctl? */ - dz_msr[dz] |= ((data & 0177400) & /* dcd |= dtr & ring */ - ((dz_msr[dz] & DZ_LMASK) << MSR_V_CD)); - dz_msr[dz] &= ~(data >> TCR_V_DTR); /* ring &= ~dtr */ - if (dz_auto) { /* auto disconnect? */ - int32 drop; - drop = (dz_tcr[dz] & ~data) >> TCR_V_DTR; /* drop = dtr & ~data */ - for (i = 0; i < DZ_LINES; i++) { /* drop hangups */ - line = (dz * DZ_LINES) + i; /* get line num */ - lp = &dz_ldsc[line]; /* get line desc */ - if (lp->conn && (drop & (1 << i))) { - tmxr_msg (lp->conn, "\r\nLine hangup\r\n"); - tmxr_reset_ln (lp); /* reset line, cdet */ - dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); - } /* end if drop */ - } /* end for */ - } /* end if auto */ - } /* end if modem */ - dz_tcr[dz] = data; - tmxr_poll_tx (&dz_desc); /* poll output */ - dz_update_xmti (); /* update int */ - break; -case 03: /* TDR */ - if (PA & 1) { /* odd byte? */ - dz_tdr[dz] = (dz_tdr[dz] & 0377) | (data << 8); /* just save */ - break; } - dz_tdr[dz] = data; - if (dz_csr[dz] & CSR_MSE) { /* enabled? */ - line = (dz * DZ_LINES) + CSR_GETTL (dz_csr[dz]); - lp = &dz_ldsc[line]; /* get line desc */ - tmxr_putc_ln (lp, dz_tdr[dz] & /* store char */ - ((dz_unit.flags & UNIT_8B)? 0377: 0177)); - tmxr_poll_tx (&dz_desc); /* poll output */ - dz_update_xmti (); } /* update int */ - break; } -return SCPE_OK; -} - -/* Unit service routine - - The DZ11 polls to see if asynchronous activity has occurred and now - needs to be processed. The polling interval is controlled by the clock - simulator, so for most environments, it is calibrated to real time. - Typical polling intervals are 50-60 times per second. - - The simulator assumes that software enables all of the multiplexors, - or none of them. -*/ - -t_stat dz_svc (UNIT *uptr) -{ -int32 dz, t, newln; - -for (dz = t = 0; dz < DZ_MUXES; dz++) /* check enabled */ - t = t | (dz_csr[dz] & CSR_MSE); -if (t) { /* any enabled? */ - newln = tmxr_poll_conn (&dz_desc); /* poll connect */ - if ((newln >= 0) && dz_mctl) { /* got a live one? */ - dz = newln / DZ_LINES; /* get mux num */ - if (dz_tcr[dz] & (1 << (newln + TCR_V_DTR))) /* DTR set? */ - dz_msr[dz] |= (1 << (newln + MSR_V_CD)); /* set cdet */ - else dz_msr[dz] |= (1 << newln); } /* set ring */ - tmxr_poll_rx (&dz_desc); /* poll input */ - dz_update_rcvi (); /* upd rcv intr */ - tmxr_poll_tx (&dz_desc); /* poll output */ - dz_update_xmti (); /* upd xmt intr */ - sim_activate (uptr, tmxr_poll); } /* reactivate */ -return SCPE_OK; -} - -/* Get first available character for mux, if any */ - -int32 dz_getc (int32 dz) -{ -uint32 i, line, c; - -for (i = c = 0; (i < DZ_LINES) && (c == 0); i++) { /* loop thru lines */ - line = (dz * DZ_LINES) + i; /* get line num */ - c = tmxr_getc_ln (&dz_ldsc[line]); /* test for input */ - if (c & SCPE_BREAK) c = RBUF_VALID | RBUF_FRME; /* break? frame err */ - if (c) c = c | (i << RBUF_V_RLINE); /* or in line # */ - } /* end for */ -return c; -} - -/* Update receive interrupts */ - -void dz_update_rcvi (void) -{ -int32 i, dz, line, scnt[DZ_MUXES]; -TMLN *lp; - -for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */ - scnt[dz] = 0; /* clr input count */ - for (i = 0; i < DZ_LINES; i++) { /* poll lines */ - line = (dz * DZ_LINES) + i; /* get line num */ - lp = &dz_ldsc[line]; /* get line desc */ - scnt[dz] = scnt[dz] + tmxr_rqln (lp); /* sum buffers */ - if (dz_mctl && !lp->conn) /* if disconn */ - dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); /* reset car det */ - } - } -for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */ - if (scnt[dz] && (dz_csr[dz] & CSR_MSE)) { /* input & enabled? */ - dz_csr[dz] |= CSR_RDONE; /* set done */ - if (dz_sae[dz] && (scnt[dz] >= DZ_SILO_ALM)) { /* alm enb & cnt hi? */ - dz_csr[dz] |= CSR_SA; /* set status */ - dz_sae[dz] = 0; } } /* disable alarm */ - else dz_csr[dz] &= ~CSR_RDONE; /* no, clear done */ - if ((dz_csr[dz] & CSR_RIE) && /* int enable */ - ((dz_csr[dz] & CSR_SAE)? - (dz_csr[dz] & CSR_SA): (dz_csr[dz] & CSR_RDONE))) - dz_set_rxint (dz); /* and alm/done? */ - else dz_clr_rxint (dz); /* no, clear int */ - } -return; -} - -/* Update transmit interrupts */ - -void dz_update_xmti (void) -{ -int32 dz, linemask, i, j, line; - -for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */ - linemask = dz_tcr[dz] & DZ_LMASK; /* enabled lines */ - dz_csr[dz] &= ~CSR_TRDY; /* assume not rdy */ - j = CSR_GETTL (dz_csr[dz]); /* start at current */ - for (i = 0; i < DZ_LINES; i++) { /* loop thru lines */ - j = (j + 1) & DZ_LNOMASK; /* next line */ - line = (dz * DZ_LINES) + j; /* get line num */ - if ((linemask & (1 << j)) && dz_ldsc[line].xmte) { - CSR_PUTTL (dz_csr[dz], j); /* put ln in csr */ - dz_csr[dz] |= CSR_TRDY; /* set xmt rdy */ - break; } } - if ((dz_csr[dz] & CSR_TIE) && (dz_csr[dz] & CSR_TRDY)) /* ready plus int? */ - dz_set_txint (dz); - else dz_clr_txint (dz); /* no int req */ - } -return; -} - -/* Interrupt routines */ - -void dz_clr_rxint (int32 dz) -{ -dz_rxi = dz_rxi & ~(1 << dz); /* clr mux rcv int */ -if (dz_rxi == 0) CLR_INT (DZRX); /* all clr? */ -else SET_INT (DZRX); /* no, set intr */ -return; -} - -void dz_set_rxint (int32 dz) -{ -dz_rxi = dz_rxi | (1 << dz); /* set mux rcv int */ -SET_INT (DZRX); /* set master intr */ -return; -} - -int32 dz_rxinta (void) -{ -int32 dz; - -for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */ - if (dz_rxi & (1 << dz)) { - dz_clr_rxint (dz); /* clear intr */ - return (dz_dib.vec + (dz * 010)); } } /* return vector */ -return 0; -} - -void dz_clr_txint (int32 dz) -{ -dz_txi = dz_txi & ~(1 << dz); /* clr mux xmt int */ -if (dz_txi == 0) CLR_INT (DZTX); /* all clr? */ -else SET_INT (DZTX); /* no, set intr */ -return; -} - -void dz_set_txint (int32 dz) -{ -dz_txi = dz_txi | (1 << dz); /* set mux xmt int */ -SET_INT (DZTX); /* set master intr */ -return; -} - -int32 dz_txinta (void) -{ -int32 dz; - -for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */ - if (dz_txi & (1 << dz)) { - dz_clr_txint (dz); /* clear intr */ - return (dz_dib.vec + 4 + (dz * 010)); } } /* return vector */ -return 0; -} - -/* Device reset */ - -t_stat dz_clear (int32 dz, t_bool flag) -{ -int32 i, line; - -dz_csr[dz] = 0; /* clear CSR */ -dz_rbuf[dz] = 0; /* silo empty */ -dz_lpr[dz] = 0; /* no params */ -if (flag) dz_tcr[dz] = 0; /* INIT? clr all */ -else dz_tcr[dz] &= ~0377; /* else save dtr */ -dz_tdr[dz] = 0; -dz_sae[dz] = 1; /* alarm on */ -dz_clr_rxint (dz); /* clear int */ -dz_clr_txint (dz); -for (i = 0; i < DZ_LINES; i++) { /* loop thru lines */ - line = (dz * DZ_LINES) + i; - if (!dz_ldsc[line].conn) dz_ldsc[line].xmte = 1;/* set xmt enb */ - dz_ldsc[line].rcve = 0; } /* clr rcv enb */ -return SCPE_OK; -} - -t_stat dz_reset (DEVICE *dptr) -{ -int32 i, ndev; - -for (i = 0; i < (DZ_MUXES * DZ_LINES); i++) /* init mux desc */ - dz_desc.ldsc[i] = &dz_ldsc[i]; -for (i = 0; i < DZ_MUXES; i++) dz_clear (i, TRUE); /* init muxes */ -dz_rxi = dz_txi = 0; /* clr master int */ -CLR_INT (DZRX); -CLR_INT (DZTX); -sim_cancel (&dz_unit); /* stop poll */ -ndev = ((dptr->flags & DEV_DIS)? 0: (dz_desc.lines / DZ_LINES)); -return auto_config (RANK_DZ, ndev); /* auto config */ -} - -/* Attach */ - -t_stat dz_attach (UNIT *uptr, char *cptr) -{ -t_stat r; -extern int32 sim_switches; - -dz_mctl = dz_auto = 0; /* modem ctl off */ -r = tmxr_attach (&dz_desc, uptr, cptr); /* attach mux */ -if (r != SCPE_OK) return r; /* error? */ -if (sim_switches & SWMASK ('M')) { /* modem control? */ - dz_mctl = 1; - printf ("Modem control activated\n"); - if (sim_log) fprintf (sim_log, "Modem control activated\n"); - if (sim_switches & SWMASK ('A')) { /* autodisconnect? */ - dz_auto = 1; - printf ("Auto disconnect activated\n"); - if (sim_log) fprintf (sim_log, "Auto disconnect activated\n"); - } - } -return SCPE_OK; -} - -/* Detach */ - -t_stat dz_detach (UNIT *uptr) -{ -return tmxr_detach (&dz_desc, uptr); -} - -/* Show summary processor */ - -t_stat dz_summ (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -int32 i, t; - -for (i = t = 0; i < dz_desc.lines; i++) { /* get num conn */ - if (dz_ldsc[i].conn) t = t + 1; } -if (t == 1) fprintf (st, "1 connection"); -else fprintf (st, "%d connections", t); -return SCPE_OK; -} - -/* SHOW CONN/STAT processor */ - -t_stat dz_show (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -int32 i, t; - -for (i = t = 0; i < dz_desc.lines; i++) { /* loop thru conn */ - if (dz_ldsc[i].conn) { - t = 1; - if (val) tmxr_fconns (st, &dz_ldsc[i], i); - else tmxr_fstats (st, &dz_ldsc[i], i); } } -if (t == 0) fprintf (st, "all disconnected\n"); -return SCPE_OK; -} - -/* SET LINES processor */ - -t_stat dz_setnl (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -int32 newln, i, t, ndev; -t_stat r; - -if (cptr == NULL) return SCPE_ARG; -newln = (int32) get_uint (cptr, 10, (DZ_MUXES * DZ_LINES), &r); -if ((r != SCPE_OK) || (newln == dz_desc.lines)) return r; -if ((newln == 0) || (newln % DZ_LINES)) return SCPE_ARG; -if (newln < dz_desc.lines) { - for (i = newln, t = 0; i < dz_desc.lines; i++) t = t | dz_ldsc[i].conn; - if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE)) - return SCPE_OK; - for (i = newln; i < dz_desc.lines; i++) { - if (dz_ldsc[i].conn) { - tmxr_msg (dz_ldsc[i].conn, "\r\nOperator disconnected line\r\n"); - tmxr_reset_ln (&dz_ldsc[i]); } /* reset line */ - if ((i % DZ_LINES) == (DZ_LINES - 1)) - dz_clear (i / DZ_LINES, TRUE); } /* reset mux */ - } -dz_dib.lnt = (newln / DZ_LINES) * IOLN_DZ; /* set length */ -dz_desc.lines = newln; -ndev = ((dz_dev.flags & DEV_DIS)? 0: (dz_desc.lines / DZ_LINES)); -return auto_config (RANK_DZ, ndev); /* auto config */ -} - -/* SHOW VECTOR processor */ - -t_stat dz_show_vec (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -return show_vec (st, uptr, ((dz_desc.lines * 2) / DZ_LINES), desc); -} diff --git a/dec_pt.h b/dec_pt.h deleted file mode 100644 index 3900f5ab..00000000 --- a/dec_pt.h +++ /dev/null @@ -1,303 +0,0 @@ -/* dec_pt.h: PC11 paper tape reader/punch simulator - - Copyright (c) 1993-2002, Robert M Supnik - - 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 - ROBERT M SUPNIK 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. - - Except as contained in this notice, the name of Robert M Supnik shall not - be used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - ptr paper tape reader - ptp paper tape punch - - 29-Sep-02 RMS Split off from pdp11_stddev.c -*/ - -#define PTRCSR_IMP (CSR_ERR+CSR_BUSY+CSR_DONE+CSR_IE) /* paper tape reader */ -#define PTRCSR_RW (CSR_IE) -#define PTPCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* paper tape punch */ -#define PTPCSR_RW (CSR_IE) - -int32 ptr_csr = 0; /* control/status */ -int32 ptr_stopioe = 0; /* stop on error */ -int32 ptp_csr = 0; /* control/status */ -int32 ptp_stopioe = 0; /* stop on error */ - -DEVICE ptr_dev, ptp_dev; -t_stat ptr_rd (int32 *data, int32 PA, int32 access); -t_stat ptr_wr (int32 data, int32 PA, int32 access); -t_stat ptr_svc (UNIT *uptr); -t_stat ptr_reset (DEVICE *dptr); -t_stat ptr_attach (UNIT *uptr, char *ptr); -t_stat ptr_detach (UNIT *uptr); -t_stat ptp_rd (int32 *data, int32 PA, int32 access); -t_stat ptp_wr (int32 data, int32 PA, int32 access); -t_stat ptp_svc (UNIT *uptr); -t_stat ptp_reset (DEVICE *dptr); -t_stat ptp_attach (UNIT *uptr, char *ptr); -t_stat ptp_detach (UNIT *uptr); - -/* PTR data structures - - ptr_dev PTR device descriptor - ptr_unit PTR unit descriptor - ptr_reg PTR register list -*/ - -DIB ptr_dib = { IOBA_PTR, IOLN_PTR, &ptr_rd, &ptr_wr, - 1, IVCL (PTR), VEC_PTR, { NULL } }; - -UNIT ptr_unit = { - UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), - SERIAL_IN_WAIT }; - -REG ptr_reg[] = { - { GRDATA (BUF, ptr_unit.buf, PT_RDX, 8, 0) }, - { GRDATA (CSR, ptr_csr, PT_RDX, 16, 0) }, - { FLDATA (INT, int_req, INT_V_PTR) }, - { FLDATA (ERR, ptr_csr, CSR_V_ERR) }, - { FLDATA (BUSY, ptr_csr, CSR_V_BUSY) }, - { FLDATA (DONE, ptr_csr, CSR_V_DONE) }, - { FLDATA (IE, ptr_csr, CSR_V_IE) }, - { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT }, - { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, - { FLDATA (STOP_IOE, ptr_stopioe, 0) }, - { FLDATA (DEVDIS, ptr_dev.flags, DEV_V_DIS), REG_HRO }, - { NULL } }; - -MTAB ptr_mod[] = { - { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL, - NULL, &show_addr, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, - NULL, &show_vec, NULL }, - { 0 } }; - -DEVICE ptr_dev = { - "PTR", &ptr_unit, ptr_reg, ptr_mod, - 1, 10, 31, 1, PT_RDX, 8, - NULL, NULL, &ptr_reset, - NULL, &ptr_attach, &ptr_detach, - &ptr_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS }; - -/* PTP data structures - - ptp_dev PTP device descriptor - ptp_unit PTP unit descriptor - ptp_reg PTP register list -*/ - -DIB ptp_dib = { IOBA_PTP, IOLN_PTP, &ptp_rd, &ptp_wr, - 1, IVCL (PTP), VEC_PTP, { NULL } }; - -UNIT ptp_unit = { - UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; - -REG ptp_reg[] = { - { GRDATA (BUF, ptp_unit.buf, PT_RDX, 8, 0) }, - { GRDATA (CSR, ptp_csr, PT_RDX, 16, 0) }, - { FLDATA (INT, int_req, INT_V_PTP) }, - { FLDATA (ERR, ptp_csr, CSR_V_ERR) }, - { FLDATA (DONE, ptp_csr, CSR_V_DONE) }, - { FLDATA (IE, ptp_csr, CSR_V_IE) }, - { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT }, - { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, - { FLDATA (STOP_IOE, ptp_stopioe, 0) }, - { NULL } }; - -MTAB ptp_mod[] = { - { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL, - NULL, &show_addr, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, - NULL, &show_vec, NULL }, - { 0 } }; - -DEVICE ptp_dev = { - "PTP", &ptp_unit, ptp_reg, ptp_mod, - 1, 10, 31, 1, 8, 8, - NULL, NULL, &ptp_reset, - NULL, &ptp_attach, &ptp_detach, - &ptp_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS }; - -/* Paper tape reader I/O address routines */ - -t_stat ptr_rd (int32 *data, int32 PA, int32 access) -{ -switch ((PA >> 1) & 01) { /* decode PA<1> */ -case 0: /* ptr csr */ - *data = ptr_csr & PTRCSR_IMP; - return SCPE_OK; -case 1: /* ptr buf */ - ptr_csr = ptr_csr & ~CSR_DONE; - CLR_INT (PTR); - *data = ptr_unit.buf & 0377; - return SCPE_OK; } -return SCPE_NXM; /* can't get here */ -} - -t_stat ptr_wr (int32 data, int32 PA, int32 access) -{ -switch ((PA >> 1) & 01) { /* decode PA<1> */ -case 0: /* ptr csr */ - if (PA & 1) return SCPE_OK; - if ((data & CSR_IE) == 0) CLR_INT (PTR); - else if (((ptr_csr & CSR_IE) == 0) && (ptr_csr & (CSR_ERR | CSR_DONE))) - SET_INT (PTR); - if (data & CSR_GO) { - ptr_csr = (ptr_csr & ~CSR_DONE) | CSR_BUSY; - CLR_INT (PTR); - if (ptr_unit.flags & UNIT_ATT) /* data to read? */ - sim_activate (&ptr_unit, ptr_unit.wait); - else sim_activate (&ptr_unit, 0); } /* error if not */ - ptr_csr = (ptr_csr & ~PTRCSR_RW) | (data & PTRCSR_RW); - return SCPE_OK; -case 1: /* ptr buf */ - return SCPE_OK; } /* end switch PA */ -return SCPE_NXM; /* can't get here */ -} - -/* Paper tape reader service */ - -t_stat ptr_svc (UNIT *uptr) -{ -int32 temp; - -ptr_csr = (ptr_csr | CSR_ERR) & ~CSR_BUSY; -if (ptr_csr & CSR_IE) SET_INT (PTR); -if ((ptr_unit.flags & UNIT_ATT) == 0) - return IORETURN (ptr_stopioe, SCPE_UNATT); -if ((temp = getc (ptr_unit.fileref)) == EOF) { - if (feof (ptr_unit.fileref)) { - if (ptr_stopioe) printf ("PTR end of file\n"); - else return SCPE_OK; } - else perror ("PTR I/O error"); - clearerr (ptr_unit.fileref); - return SCPE_IOERR; } -ptr_csr = (ptr_csr | CSR_DONE) & ~CSR_ERR; -ptr_unit.buf = temp & 0377; -ptr_unit.pos = ptr_unit.pos + 1; -return SCPE_OK; -} - -/* Paper tape reader support routines */ - -t_stat ptr_reset (DEVICE *dptr) -{ -ptr_unit.buf = 0; -ptr_csr = 0; -if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR; -CLR_INT (PTR); -sim_cancel (&ptr_unit); -return SCPE_OK; -} - -t_stat ptr_attach (UNIT *uptr, char *cptr) -{ -t_stat reason; - -reason = attach_unit (uptr, cptr); -if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR; -else ptr_csr = ptr_csr & ~CSR_ERR; -return reason; -} - -t_stat ptr_detach (UNIT *uptr) -{ -ptr_csr = ptr_csr | CSR_ERR; -return detach_unit (uptr); -} - -/* Paper tape punch I/O address routines */ - -t_stat ptp_rd (int32 *data, int32 PA, int32 access) -{ -switch ((PA >> 1) & 01) { /* decode PA<1> */ -case 0: /* ptp csr */ - *data = ptp_csr & PTPCSR_IMP; - return SCPE_OK; -case 1: /* ptp buf */ - *data = ptp_unit.buf; - return SCPE_OK; } -return SCPE_NXM; /* can't get here */ -} - -t_stat ptp_wr (int32 data, int32 PA, int32 access) -{ -switch ((PA >> 1) & 01) { /* decode PA<1> */ -case 0: /* ptp csr */ - if (PA & 1) return SCPE_OK; - if ((data & CSR_IE) == 0) CLR_INT (PTP); - else if (((ptp_csr & CSR_IE) == 0) && (ptp_csr & (CSR_ERR | CSR_DONE))) - SET_INT (PTP); - ptp_csr = (ptp_csr & ~PTPCSR_RW) | (data & PTPCSR_RW); - return SCPE_OK; -case 1: /* ptp buf */ - if ((PA & 1) == 0) ptp_unit.buf = data & 0377; - ptp_csr = ptp_csr & ~CSR_DONE; - CLR_INT (PTP); - if (ptp_unit.flags & UNIT_ATT) /* file to write? */ - sim_activate (&ptp_unit, ptp_unit.wait); - else sim_activate (&ptp_unit, 0); /* error if not */ - return SCPE_OK; } /* end switch PA */ -return SCPE_NXM; /* can't get here */ -} - -/* Paper tape punch service */ - -t_stat ptp_svc (UNIT *uptr) -{ -ptp_csr = ptp_csr | CSR_ERR | CSR_DONE; -if (ptp_csr & CSR_IE) SET_INT (PTP); -if ((ptp_unit.flags & UNIT_ATT) == 0) - return IORETURN (ptp_stopioe, SCPE_UNATT); -if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) { - perror ("PTP I/O error"); - clearerr (ptp_unit.fileref); - return SCPE_IOERR; } -ptp_csr = ptp_csr & ~CSR_ERR; -ptp_unit.pos = ptp_unit.pos + 1; -return SCPE_OK; -} - -/* Paper tape punch support routines */ - -t_stat ptp_reset (DEVICE *dptr) -{ -ptp_unit.buf = 0; -ptp_csr = CSR_DONE; -if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR; -CLR_INT (PTP); -sim_cancel (&ptp_unit); /* deactivate unit */ -return SCPE_OK; -} - -t_stat ptp_attach (UNIT *uptr, char *cptr) -{ -t_stat reason; - -reason = attach_unit (uptr, cptr); -if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR; -else ptp_csr = ptp_csr & ~CSR_ERR; -return reason; -} - -t_stat ptp_detach (UNIT *uptr) -{ -ptp_csr = ptp_csr | CSR_ERR; -return detach_unit (uptr); -} diff --git a/descrip.mms b/descrip.mms index edf097ca..bdad29cd 100644 --- a/descrip.mms +++ b/descrip.mms @@ -1,1008 +1,1021 @@ -# -# DESCRIP.MMS -# Written By: Robert Alan Byer -# byer@mail.ourservers.net -# -# This MMS/MMK build script is used to compile the various simulators in -# the SIMH package for OpenVMS using DEC C v6.0-001. -# -# Notes: On VAX, the PDP-10 and VAX simulator will not be built due to the -# fact that INT64 is required for those simulators. -# -# When using DEC's MMS on an Alpha you must use -# /MACRO=("__ALPHA__=1") to compile properly. -# -# This build script will accept the following build options. -# -# ALL Just Build "Everything". -# ALTAIR Just Build The MITS Altair. -# ALTAIRZ80 Just Build The MITS Altair Z80. -# ECLIPSE Just Build The Data General Eclipse. -# GRI Just Build The GRI Corporation GRI-909. -# H316 Just Build The Honewell 316/516. -# HP2100 Just Build The Hewlett-Packard HP-2100. -# I1401 Just Build The IBM 1401. -# IBM1130 Just Build The IBM 1130. -# ID16 Just Build The Interdata 16-bit CPU. -# ID32 Just Build The Interdata 32-bit CPU. -# NOVA Just Build The Data General Nova. -# PDP1 Just Build The DEC PDP-1. -# PDP4 Just Build The DEC PDP-4. -# PDP7 Just Build The DEC PDP-7. -# PDP8 Just Build The DEC PDP-8. -# PDP9 Just Build The DEC PDP-9. -# PDP10 Just Build The DEC PDP-10. -# PDP11 Just Build The DEC PDP-11. -# PDP15 Just Build The DEC PDP-15. -# S3 Just Build The IBM System 3. -# SDS Just Build The SDS 940. -# VAX Just Build The DEC VAX. -# -# To build with debugging enabled (which will also enable traceback -# information) use.. -# -# MMK/FORCE/MACRO=(DEBUG=1) -# - -# -# Define The BIN Directory Where The Executables Will Go. -# -BIN_DIR = SYS$DISK:[.BIN] - -# -# Define Our Library Directory. -# -LIB_DIR = SYS$DISK:[.LIB] - -# -# Let's See If We Are Going To Build With DEBUG Enabled. -# -.IFDEF DEBUG -CC_DEBUG = /DEBUG -LINK_DEBUG = /DEBUG/TRACEBACK -CC_OPTIMIZE = /NOOPTIMIZE -.ELSE -CC_DEBUG = /NODEBUG -LINK_DEBUG = /NODEBUG/NOTRACEBACK -.IFDEF __ALPHA__ -CC_OPTIMIZE = /OPTIMIZE=(LEVEL=5,TUNE=HOST)/ARCH=HOST -CC_FLAGS = /PREFIX=ALL -ARCH = AXP -.ELSE -CC_OPTIMIZE = /OPTIMIZE -ARCH = VAX -.ENDIF -.ENDIF - -# -# Define Our Compiler Flags. -# -CC_FLAGS = $(CC_FLAGS)$(CC_OPTIMIZE)/NEST=PRIMARY/NAME=(AS_IS,SHORTENED) - -# -# Define The Compile Command. -# -CC = CC $(CC_FLAGS) - -# -# First, Let's Check To Make Sure We Have A SYS$DISK:[.BIN] And -# SYS$DISK:[.LIB] Directory. -# -.FIRST - @ IF (F$SEARCH("SYS$DISK:[]BIN.DIR").EQS."") THEN CREATE/DIRECTORY $(BIN_DIR) - @ IF (F$SEARCH("SYS$DISK:[]LIB.DIR").EQS."") THEN CREATE/DIRECTORY $(LIB_DIR) - -# -# Core SIMH File Definitions. -# -SIMH_DIR = SYS$DISK:[] -SIMH_LIB = $(LIB_DIR)SIMH-$(ARCH).OLB -SIMH_SOURCE = $(SIMH_DIR)SCP_TTY.C,$(SIMH_DIR)SIM_SOCK.C,\ - $(SIMH_DIR)SIM_TMXR.C,$(SIMH_DIR)SIM_ETHER.C,$(SIMH_DIR)SIM_TAPE.C -SIMH_OBJS = $(SIMH_DIR)SCP_TTY.OBJ,$(SIMH_DIR)SIM_SOCK.OBJ,\ - $(SIMH_DIR)SIM_TMXR.OBJ,$(SIMH_DIR)SIM_ETHER.OBJ,$(SIMH_DIR)SIM_TAPE.OBJ - -# -# MITS Altair Simulator Definitions. -# -ALTAIR_DIR = SYS$DISK:[.ALTAIR] -ALTAIR_LIB = $(LIB_DIR)ALTAIR-$(ARCH).OLB -ALTAIR_SOURCE = $(ALTAIR_DIR)ALTAIR_SIO.C,$(ALTAIR_DIR)ALTAIR_CPU.C,\ - $(ALTAIR_DIR)ALTAIR_DSK.C,$(ALTAIR_DIR)ALTAIR_SYS.C -ALTAIR_OBJS = $(ALTAIR_DIR)ALTAIR_SIO.OBJ,$(ALTAIR_DIR)ALTAIR_CPU.OBJ,\ - $(ALTAIR_DIR)ALTAIR_DSK.OBJ,$(ALTAIR_DIR)ALTAIR_SYS.OBJ -ALTAIR_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ALTAIR_DIR)) - -# -# MITS Altair Z80 Simulator Definitions. -# -ALTAIRZ80_DIR = SYS$DISK:[.ALTAIRZ80] -ALTAIRZ80_LIB = $(LIB_DIR)ALTAIRZ80-$(ARCH).OLB -ALTAIRZ80_SOURCE = $(ALTAIRZ80_DIR)ALTAIRZ80_CPU.C,\ - $(ALTAIRZ80_DIR)ALTAIRZ80_DSK.C,\ - $(ALTAIRZ80_DIR)ALTAIRZ80_SIO.C,\ - $(ALTAIRZ80_DIR)ALTAIRZ80_SYS.C,\ - $(ALTAIRZ80_DIR)ALTAIRZ80_HDSK.C -ALTAIRZ80_OBJS = $(ALTAIRZ80_DIR)ALTAIRZ80_CPU.OBJ,\ - $(ALTAIRZ80_DIR)ALTAIRZ80_DSK.OBJ,\ - $(ALTAIRZ80_DIR)ALTAIRZ80_SIO.OBJ,\ - $(ALTAIRZ80_DIR)ALTAIRZ80_SYS.OBJ,\ - $(ALTAIRZ80_DIR)ALTAIRZ80_HDSK.OBJ -ALTAIRZ80_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ALTAIRZ80_DIR)) - -# -# Data General Nova Simulator Definitions. -# -NOVA_DIR = SYS$DISK:[.NOVA] -NOVA_LIB = $(LIB_DIR)NOVA-$(ARCH).OLB -NOVA_SOURCE = $(NOVA_DIR)NOVA_SYS.C,$(NOVA_DIR)NOVA_CPU.C,\ - $(NOVA_DIR)NOVA_DKP.C,$(NOVA_DIR)NOVA_DSK.C,\ - $(NOVA_DIR)NOVA_LP.C,$(NOVA_DIR)NOVA_MTA.C,\ - $(NOVA_DIR)NOVA_PLT.C,$(NOVA_DIR)NOVA_PT.C,\ - $(NOVA_DIR)NOVA_CLK.C,$(NOVA_DIR)NOVA_TT.C,\ - $(NOVA_DIR)NOVA_TT1.C -NOVA_OBJS = $(NOVA_DIR)NOVA_SYS.OBJ,$(NOVA_DIR)NOVA_CPU.OBJ,\ - $(NOVA_DIR)NOVA_DKP.OBJ,$(NOVA_DIR)NOVA_DSK.OBJ,\ - $(NOVA_DIR)NOVA_LP.OBJ,$(NOVA_DIR)NOVA_MTA.OBJ,\ - $(NOVA_DIR)NOVA_PLT.OBJ,$(NOVA_DIR)NOVA_PT.OBJ,\ - $(NOVA_DIR)NOVA_CLK.OBJ,$(NOVA_DIR)NOVA_TT.OBJ,\ - $(NOVA_DIR)NOVA_TT1.OBJ -NOVA_OPTIONS = /INCLUDE=($(SIMH_DIR),$(NOVA_DIR)) - -# -# Data General Eclipse Simulator Definitions. -# -ECLIPSE_LIB = $(LIB_DIR)ECLIPSE-$(ARCH).OLB -ECLIPSE_SOURCE = $(NOVA_DIR)ECLIPSE_CPU.C,$(NOVA_DIR)ECLIPSE_TT.C,\ - $(NOVA_DIR)NOVA_SYS.C,$(NOVA_DIR)NOVA_DKP.C,\ - $(NOVA_DIR)NOVA_DSK.C,$(NOVA_DIR)NOVA_LP.C,\ - $(NOVA_DIR)NOVA_MTA.C,$(NOVA_DIR)NOVA_PLT.C,\ - $(NOVA_DIR)NOVA_PT.C,$(NOVA_DIR)NOVA_CLK.C,\ - $(NOVA_DIR)NOVA_TT1.C -ECLIPSE_OBJS = $(NOVA_DIR)ECLIPSE_CPU.OBJ,$(NOVA_DIR)ECLIPSE_TT.OBJ,\ - $(NOVA_DIR)NOVA_SYS.OBJ,$(NOVA_DIR)NOVA_DKP.OBJ,\ - $(NOVA_DIR)NOVA_DSK.OBJ,$(NOVA_DIR)NOVA_LP.OBJ,\ - $(NOVA_DIR)NOVA_MTA.OBJ,$(NOVA_DIR)NOVA_PLT.OBJ,\ - $(NOVA_DIR)NOVA_PT.OBJ,$(NOVA_DIR)NOVA_CLK.OBJ,\ - $(NOVA_DIR)NOVA_TT1.OBJ -ECLIPSE_OPTIONS = /INCLUDE=($(SIMH_DIR),$(NOVA_DIR))/DEFINE=("ECLIPSE=1") - -# -# GRI Corporation GRI-909 Simulator Definitions. -# -GRI_DIR = SYS$DISK:[.GRI] -GRI_LIB = $(LIB_DIR)GRI-$(ARCH).OLB -GRI_SOURCE = $(GRI_DIR)GRI_CPU.C,$(GRI_DIR)GRI_STDDEV.C,$(GRI_DIR)GRI_SYS.C -GRI_OBJS = $(GRI_DIR)GRI_CPU.OBJ,$(GRI_DIR)GRI_STDDEV.OBJ,\ - $(GRI_DIR)GRI_SYS.OBJ -GRI_OPTIONS = /INCLUDE=($(SIMH_DIR),$(GRI_DIR)) - -# -# Honeywell 316/516 Simulator Definitions. -# -H316_DIR = SYS$DISK:[.H316] -H316_LIB = $(LIB_DIR)H316-$(ARCH).OLB -H316_SOURCE = $(H316_DIR)H316_STDDEV.C,$(H316_DIR)H316_LP.C,\ - $(H316_DIR)H316_CPU.C,$(H316_DIR)H316_SYS.C -H316_OBJS = $(H316_DIR)H316_STDDEV.OBJ,$(H316_DIR)H316_LP.OBJ,\ - $(H316_DIR)H316_CPU.OBJ,$(H316_DIR)H316_SYS.OBJ -H316_OPTIONS = /INCLUDE=($(SIMH_DIR),$(H316_DIR)) - -# -# Hewlett-Packard HP-2100 Simulator Definitions. -# -HP2100_DIR = SYS$DISK:[.HP2100] -HP2100_LIB = $(LIB_DIR)HP2100-$(ARCH).OLB -HP2100_SOURCE = $(HP2100_DIR)HP2100_STDDEV.C,$(HP2100_DIR)HP2100_DP.C,\ - $(HP2100_DIR)HP2100_DQ.C,$(HP2100_DIR)HP2100_DR.C,\ - $(HP2100_DIR)HP2100_LPS.C,$(HP2100_DIR)HP2100_MS.C,\ - $(HP2100_DIR)HP2100_MT.C,$(HP2100_DIR)HP2100_MUX.C,\ - $(HP2100_DIR)HP2100_CPU.C,$(HP2100_DIR)HP2100_FP.C,\ - $(HP2100_DIR)HP2100_SYS.C,$(HP2100_DIR)HP2100_LPT.C,\ - $(HP2100_DIR)HP2100_IPL.C -HP2100_OBJS = $(HP2100_DIR)HP2100_STDDEV.OBJ,$(HP2100_DIR)HP2100_DP.OBJ,\ - $(HP2100_DIR)HP2100_DQ.OBJ,$(HP2100_DIR)HP2100_DR.OBJ,\ - $(HP2100_DIR)HP2100_LPS.OBJ,$(HP2100_DIR)HP2100_MS.OBJ,\ - $(HP2100_DIR)HP2100_MT.OBJ,$(HP2100_DIR)HP2100_MUX.OBJ,\ - $(HP2100_DIR)HP2100_CPU.OBJ,$(HP2100_DIR)HP2100_FP.OBJ,\ - $(HP2100_DIR)HP2100_SYS.OBJ,$(HP2100_DIR)HP2100_LPT.OBJ,\ - $(HP2100_DIR)HP2100_IPL.OBJ -HP2100_OPTIONS = /INCLUDE=($(SIMH_DIR),$(HP2100_DIR)) - -# -# Interdata 16-bit CPU. -# -ID16_DIR = SYS$DISK:[.INTERDATA] -ID16_LIB = $(LIB_DIR)ID16-$(ARCH).OLB -ID16_SOURCE = $(ID16_DIR)ID16_CPU.C,$(ID16_DIR)ID16_SYS.C,$(ID16_DIR)ID_DP.C,\ - $(ID16_DIR)ID_FD.C,$(ID16_DIR)ID_FP.C,$(ID16_DIR)ID_IDC.C,\ - $(ID16_DIR)ID_IO.C,$(ID16_DIR)ID_LP.C,$(ID16_DIR)ID_MT.C,\ - $(ID16_DIR)ID_PAS.C,$(ID16_DIR)ID_PT.C,$(ID16_DIR)ID_TT.C,\ - $(ID16_DIR)ID_UVC.C,$(ID16_DIR)ID16_DBOOT.C,$(ID16_DIR)ID_TTP.C -ID16_OBJS = $(ID16_DIR)ID16_CPU.OBJ,$(ID16_DIR)ID16_SYS.OBJ,$(ID16_DIR)ID_DP.OBJ,\ - $(ID16_DIR)ID_FD.OBJ,$(ID16_DIR)ID_FP.OBJ,$(ID16_DIR)ID_IDC.OBJ,\ - $(ID16_DIR)ID_IO.OBJ,$(ID16_DIR)ID_LP.OBJ,$(ID16_DIR)ID_MT.OBJ,\ - $(ID16_DIR)ID_PAS.OBJ,$(ID16_DIR)ID_PT.OBJ,$(ID16_DIR)ID_TT.OBJ,\ - $(ID16_DIR)ID_UVC.OBJ,$(ID16_DIR)ID16_DBOOT.OBJ,$(ID16)DIR)ID_TTP.OBJ -ID16_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ID16_DIR)) - -# -# Interdata 32-bit CPU. -# -ID32_DIR = SYS$DISK:[.INTERDATA] -ID32_LIB = $(LIB_DIR)ID32-$(ARCH).OLB -ID32_SOURCE = $(ID32_DIR)ID32_CPU.C,$(ID32_DIR)ID32_SYS.C,$(ID32_DIR)ID_DP.C,\ - $(ID32_DIR)ID_FD.C,$(ID32_DIR)ID_FP.C,$(ID32_DIR)ID_IDC.C,\ - $(ID32_DIR)ID_IO.C,$(ID32_DIR)ID_LP.C,$(ID32_DIR)ID_MT.C,\ - $(ID32_DIR)ID_PAS.C,$(ID32_DIR)ID_PT.C,$(ID32_DIR)ID_TT.C,\ - $(ID32_DIR)ID_UVC.C,$(ID32_DIR)ID32_DBOOT.C,$(ID32_DIR)ID_TTP.C -ID32_OBJS = $(ID32_DIR)ID32_CPU.OBJ,$(ID32_DIR)ID32_SYS.OBJ,\ - $(ID32_DIR)ID_DP.OBJ,$(ID32_DIR)ID_FD.OBJ,\ - $(ID32_DIR)ID_FP.OBJ,$(ID32_DIR)ID_IDC.OBJ,\ - $(ID32_DIR)ID_IO.OBJ,$(ID32_DIR)ID_LP.OBJ,$(ID32_DIR)ID_MT.OBJ,\ - $(ID32_DIR)ID_PAS.OBJ,$(ID32_DIR)ID_PT.OBJ,$(ID32_DIR)ID_TT.OBJ,\ - $(ID32_DIR)ID_UVC.OBJ,$(ID32_DIR)ID32_DBOOT.C,$(ID32_DIR)ID_TTP.OBJ -ID32_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ID32_DIR)) - -# -# IBM 1130 Simulator Definitions. -# -IBM1130_DIR = SYS$DISK:[.IBM1130] -IBM1130_LIB = $(LIB_DIR)IBM1130-$(ARCH).OLB -IBM1130_SOURCE = $(IBM1130_DIR)IBM1130_CPU.C,$(IBM1130_DIR)IBM1130_CR.C,\ - $(IBM1130_DIR)IBM1130_DISK.C,$(IBM1130_DIR)IBM1130_STDDEV.C,\ - $(IBM1130_DIR)IBM1130_SYS.C,$(IBM1130_DIR)IBM1130_GDU.C,\ - $(IBM1130_DIR)IBM1130_GUI.C,$(IBM1130_DIR)IBM1130_PRT.C -IBM1130_OBJS = $(IBM1130_DIR)IBM1130_CPU.OBJ,$(IBM1130_DIR)IBM1130_CR.OBJ,\ - $(IBM1130_DIR)IBM1130_DISK.OBJ,$(IBM1130_DIR)IBM1130_STDDEV.OBJ,\ - $(IBM1130_DIR)IBM1130_SYS.OBJ,$(IBM1130_DIR)IBM1130_GDU.OBJ,\ - $(IBM1130_DIR)IBM1130_GUI.OBJ,$(IBM1130_DIR)IBM1130_PRT.OBJ -IBM1130_OPTIONS = /INCLUDE=($(SIMH_DIR),$(IBM1130_DIR)) - -# -# IBM 1401 Simulator Definitions. -# -I1401_DIR = SYS$DISK:[.I1401] -I1401_LIB = $(LIB_DIR)I1401-$(ARCH).OLB -I1401_SOURCE = $(I1401_DIR)I1401_LP.C,$(I1401_DIR)I1401_CPU.C,\ - $(I1401_DIR)I1401_IQ.C,$(I1401_DIR)I1401_CD.C,\ - $(I1401_DIR)I1401_MT.C,$(I1401_DIR)I1401_DP.C,\ - $(I1401_DIR)I1401_SYS.C -I1401_OBJS = $(I1401_DIR)I1401_LP.OBJ,$(I1401_DIR)I1401_CPU.OBJ,\ - $(I1401_DIR)I1401_IQ.OBJ,$(I1401_DIR)I1401_CD.OBJ,\ - $(I1401_DIR)I1401_MT.OBJ,$(I1401_DIR)I1401_DP.OBJ,\ - $(I1401_DIR)I1401_SYS.OBJ -I1401_OPTIONS = /INCLUDE=($(SIMH_DIR),$(I1401_DIR)) - - -# -# IBM 1620 Simulators Definitions. -# -I1620_DIR = SYS$DISK:[.I1620] -I1620_LIB = $(LIB_DIR)I1620-$(ARCH).OLB -I1620_SOURCE = $(I1620_DIR)I1620_CD.C,$(I1620_DIR)I1620_DP.C,\ - $(I1620_DIR)I1620_PT.C,$(I1620_DIR)I1620_TTY.C,\ - $(I1620_DIR)I1620_CPU.C,$(I1620_DIR)I1620_LP.C,\ - $(I1620_DIR)I1620_FP.C,$(I1620_DIR)I1620_SYS.C -I1620_OBJS = $(I1620_DIR)I1620_CD.OBJ,$(I1620_DIR)I1620_DP.OBJ,\ - $(I1620_DIR)I1620_PT.OBJ,$(I1620_DIR)I1620_TTY.OBJ,\ - $(I1620_DIR)I1620_CPU.OBJ,$(I1620_DIR)I1620_LP.OBJ,\ - $(I1620_DIR)I1620_FP.OBJ,$(I1620_DIR)I1620_SYS.OBJ -I1620_OPTIONS = /INCLUDE=($(SIMH_DIR),$(I1620_DIR)) - -# -# PDP-1 Simulator Definitions. -# -PDP1_DIR = SYS$DISK:[.PDP1] -PDP1_LIB = $(LIB_DIR)PDP1-$(ARCH).OLB -PDP1_SOURCE = $(PDP1_DIR)PDP1_LP.C,$(PDP1_DIR)PDP1_CPU.C,\ - $(PDP1_DIR)PDP1_STDDEV.C,$(PDP1_DIR)PDP1_SYS.C,\ - $(PDP1_DIR)PDP1_DT.C,${PDP1_DIR}PDP1_DRM.C -PDP1_OBJS = $(PDP1_DIR)PDP1_LP.OBJ,$(PDP1_DIR)PDP1_CPU.OBJ,\ - $(PDP1_DIR)PDP1_STDDEV.OBJ,$(PDP1_DIR)PDP1_SYS.OBJ,\ - $(PDP1_DIR)PDP1_DT.OBJ,{PDP1_DIR}PDP1_DRM.OBJ -PDP1_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP1_DIR)) - -# -# Digital Equipment PDP-8 Simulator Definitions. -# -PDP8_DIR = SYS$DISK:[.PDP8] -PDP8_LIB = $(LIB_DIR)PDP8-$(ARCH).OLB -PDP8_SOURCE = $(PDP8_DIR)PDP8_CPU.C,$(PDP8_DIR)PDP8_CLK.C,\ - $(PDP8_DIR)PDP8_DF.C,$(PDP8_DIR)PDP8_DT.C,\ - $(PDP8_DIR)PDP8_LP.C,$(PDP8_DIR)PDP8_MT.C,\ - $(PDP8_DIR)PDP8_PT.C,$(PDP8_DIR)PDP8_RF.C,\ - $(PDP8_DIR)PDP8_RK.C,$(PDP8_DIR)PDP8_RX.C,\ - $(PDP8_DIR)PDP8_SYS.C,$(PDP8_DIR)PDP8_TT.C,\ - $(PDP8_DIR)PDP8_TTX.C,$(PDP8_DIR)PDP8_RL.C -PDP8_OBJS = $(PDP8_DIR)PDP8_CPU.OBJ,$(PDP8_DIR)PDP8_CLK.OBJ,\ - $(PDP8_DIR)PDP8_DF.OBJ,$(PDP8_DIR)PDP8_DT.OBJ,\ - $(PDP8_DIR)PDP8_LP.OBJ,$(PDP8_DIR)PDP8_MT.OBJ,\ - $(PDP8_DIR)PDP8_PT.OBJ,$(PDP8_DIR)PDP8_RF.OBJ,\ - $(PDP8_DIR)PDP8_RK.OBJ,$(PDP8_DIR)PDP8_RX.OBJ,\ - $(PDP8_DIR)PDP8_SYS.OBJ,$(PDP8_DIR)PDP8_TT.OBJ,\ - $(PDP8_DIR)PDP8_TTX.OBJ,$(PDP8_DIR)PDP8_RL.OBJ -PDP8_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP8_DIR)) - -# -# Digital Equipment PDP-4, PDP-7, PDP-9 And PDP-15 Simulator Definitions. -# -PDP18B_DIR = SYS$DISK:[.PDP18B] -PDP4_LIB = $(LIB_DIR)PDP4-$(ARCH).OLB -PDP7_LIB = $(LIB_DIR)PDP7-$(ARCH).OLB -PDP9_LIB = $(LIB_DIR)PDP9-$(ARCH).OLB -PDP15_LIB = $(LIB_DIR)PDP15-$(ARCH).OLB -PDP18B_SOURCE = $(PDP18B_DIR)PDP18B_DT.C,$(PDP18B_DIR)PDP18B_DRM.C,\ - $(PDP18B_DIR)PDP18B_CPU.C,$(PDP18B_DIR)PDP18B_LP.C,\ - $(PDP18B_DIR)PDP18B_MT.C,$(PDP18B_DIR)PDP18B_RF.C,\ - $(PDP18B_DIR)PDP18B_RP.C,$(PDP18B_DIR)PDP18B_STDDEV.C,\ - $(PDP18B_DIR)PDP18B_SYS.C,$(PDP18B_DIR)PDP18B_TT1.C,\ - $(PDP18B_DIR)PDP18B_RB.C -PDP18B_OBJS = $(PDP18B_DIR)PDP18B_DT.OBJ,$(PDP18B_DIR)PDP18B_DRM.OBJ,\ - $(PDP18B_DIR)PDP18B_CPU.OBJ,$(PDP18B_DIR)PDP18B_LP.OBJ,\ - $(PDP18B_DIR)PDP18B_MT.OBJ,$(PDP18B_DIR)PDP18B_RF.OBJ,\ - $(PDP18B_DIR)PDP18B_RP.OBJ,$(PDP18B_DIR)PDP18B_STDDEV.OBJ,\ - $(PDP18B_DIR)PDP18B_SYS.OBJ,$(PDP18B_DIR)PDP18B_TT1.OBJ,\ - $(PDP18B_DIR)PDP18B_RB.OBJ -PDP4_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP4=1") -PDP7_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP7=1") -PDP9_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP9=1") -PDP15_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP15=1") - -# -# Digital Equipment PDP-11 Simulator Definitions. -# -PDP11_DIR = SYS$DISK:[.PDP11] -PDP11_LIB = $(LIB_DIR)PDP11-$(ARCH).OLB -PDP11_SOURCE = $(PDP11_DIR)PDP11_FP.C,$(PDP11_DIR)PDP11_CPU.C,\ - $(PDP11_DIR)PDP11_DZ.C,$(PDP11_DIR)PDP11_CIS.C,\ - $(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_RK.C,\ - $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RP.C,\ - $(PDP11_DIR)PDP11_RX.C,$(PDP11_DIR)PDP11_STDDEV.C,\ - $(PDP11_DIR)PDP11_SYS.C,$(PDP11_DIR)PDP11_TC.C,\ - $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\ - $(PDP11_DIR)PDP11_IO.C,$(PDP11_DIR)PDP11_RQ.C,\ - $(PDP11_DIR)PDP11_TQ.C,$(PDP11_DIR)PDP11_PCLK.C,\ - $(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_PT.C,\ - $(PDP11_DIR)PDP11_HK.C,$(PDP11_DIR)PDP11_XQ.C,\ - $(PDP11_DIR)PDP11_XU.C -PDP11_OBJS = $(PDP11_DIR)PDP11_FP.OBJ,$(PDP11_DIR)PDP11_CPU.OBJ,\ - $(PDP11_DIR)PDP11_DZ.OBJ,$(PDP11_DIR)PDP11_CIS.OBJ,\ - $(PDP11_DIR)PDP11_LP.OBJ,$(PDP11_DIR)PDP11_RK.OBJ,\ - $(PDP11_DIR)PDP11_RL.OBJ,$(PDP11_DIR)PDP11_RP.OBJ,\ - $(PDP11_DIR)PDP11_RX.OBJ,$(PDP11_DIR)PDP11_STDDEV.OBJ,\ - $(PDP11_DIR)PDP11_SYS.OBJ,$(PDP11_DIR)PDP11_TC.OBJ,\ - $(PDP11_DIR)PDP11_TM.OBJ,$(PDP11_DIR)PDP11_TS.OBJ,\ - $(PDP11_DIR)PDP11_IO.OBJ,$(PDP11_DIR)PDP11_RQ.OBJ,\ - $(PDP11_DIR)PDP11_TQ.OBJ,$(PDP11_DIR)PDP11_PCLK.OBJ,\ - $(PDP11_DIR)PDP11_RY.OBJ,$(PDP11_DIR)PDP11_PT.OBJ,\ - $(PDP11_DIR)PDP11_HK.OBJ,$(PDP11_DIR)PDP11_XQ.OBJ,\ - $(PDP11_DIR)PDP11_XU.OBJ -PDP11_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP11_DIR)) - -# -# Digital Equipment PDP-10 Simulator Definitions. -# -PDP10_DIR = SYS$DISK:[.PDP10] -PDP10_LIB = $(LIB_DIR)PDP10-$(ARCH).OLB -PDP10_SOURCE = $(PDP10_DIR)PDP10_FE.C,$(PDP10_DIR)PDP10_DZ.C,\ - $(PDP10_DIR)PDP10_CPU.C,$(PDP10_DIR)PDP10_KSIO.C,\ - $(PDP10_DIR)PDP10_LP20.C,$(PDP10_DIR)PDP10_MDFP.C,\ - $(PDP10_DIR)PDP10_PAG.C,$(PDP10_DIR)PDP10_PT.C,\ - $(PDP10_DIR)PDP10_RP.C,$(PDP10_DIR)PDP10_SYS.C,\ - $(PDP10_DIR)PDP10_TIM.C,$(PDP10_DIR)PDP10_TU.C,\ - $(PDP10_DIR)PDP10_XTND.C,$(PDP10_DIR)PDP10_PT.C,\ - $(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_XU.C -PDP10_OBJS = $(PDP10_DIR)PDP10_FE.OBJ,$(PDP10_DIR)PDP10_DZ.OBJ,\ - $(PDP10_DIR)PDP10_CPU.OBJ,$(PDP10_DIR)PDP10_KSIO.OBJ,\ - $(PDP10_DIR)PDP10_LP20.OBJ,$(PDP10_DIR)PDP10_MDFP.OBJ,\ - $(PDP10_DIR)PDP10_PAG.OBJ,$(PDP10_DIR)PDP10_PT.OBJ,\ - $(PDP10_DIR)PDP10_RP.OBJ,$(PDP10_DIR)PDP10_SYS.OBJ,\ - $(PDP10_DIR)PDP10_TIM.OBJ,$(PDP10_DIR)PDP10_TU.OBJ,\ - $(PDP10_DIR)PDP10_XTND.OBJ,$(PDP10_DIR)PDP10_PT.OBJ,\ - $(PDP10_DIR)PDP11_RY.OBJ,(PDP10_DIR)PDP11_XU.OBJ -PDP10_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP10_DIR),$(PDP11_DIR))/DEFINE=("USE_INT64=1") - -# -# IBM System 3 Simulator Definitions. -# -S3_DIR = SYS$DISK:[.S3] -S3_LIB = $(LIB_DIR)S3-$(ARCH).OLB -S3_SOURCE = $(S3_DIR)S3_CD.C,$(S3_DIR)S3_CPU.C,$(S3_DIR)S3_DISK.C,\ - $(S3_DIR)S3_LP.C,$(S3_DIR)S3_PKB.C,$(S3_DIR)S3_SYS.C -S3_OBJS = $(S3_DIR)S3_CD.OBJ,$(S3_DIR)S3_CPU.OBJ,$(S3_DIR)S3_DISK.OBJ,\ - $(S3_DIR)S3_LP.OBJ,$(S3_DIR)S3_PKB.OBJ,$(S3_DIR)S3_SYS.OBJ -S3_OPTIONS = /INCLUDE=($(SIMH_DIR),$(S3_DIR)) - -# -# SDS 940 -# -SDS_DIR = SYS$DISK:[.SDS] -SDS_LIB = $(LIB_DIR)SDS-$(ARCH).OLB -SDS_SOURCE = $(SDS_DIR)SDS_CPU.C,$(SDS_DIR)SDS_DRM.C,$(SDS_DIR)SDS_DSK.C,\ - $(SDS_DIR)SDS_IO.C,$(SDS_DIR)SDS_LP.C,$(SDS_DIR)SDS_MT.C,\ - $(SDS_DIR)SDS_MUX.C,$(SDS_DIR)SDS_RAD.C,$(SDS_DIR)SDS_STDDEV.C,\ - $(SDS_DIR)SDS_SYS.C -SDS_OBJS = $(SDS_DIR)SDS_CPU.OBJ,$(SDS_DIR)SDS_DRM.OBJ,$(SDS_DIR)SDS_DSK.OBJ,\ - $(SDS_DIR)SDS_IO.OBJ,$(SDS_DIR)SDS_LP.OBJ,$(SDS_DIR)SDS_MT.OBJ,\ - $(SDS_DIR)SDS_MUX.OBJ,$(SDS_DIR)SDS_RAD.OBJ,$(SDS_DIR)SDS_STDDEV.OBJ,\ - $(SDS_DIR)SDS_SYS.OBJ -SDS_OPTIONS = /INCLUDE=($(SIMH_DIR),$(SDS_DIR)) - -# -# Digital Equipment VAX Simulator Definitions. -# -VAX_DIR = SYS$DISK:[.VAX] -VAX_LIB = $(LIB_DIR)VAX-$(ARCH).OLB -VAX_SOURCE = $(VAX_DIR)VAX_CPU1.C,$(VAX_DIR)VAX_CPU.C,\ - $(VAX_DIR)VAX_FPA.C,$(VAX_DIR)VAX_IO.C,\ - $(VAX_DIR)VAX_MMU.C,$(VAX_DIR)VAX_STDDEV.C,\ - $(VAX_DIR)VAX_SYS.C,$(VAX_DIR)VAX_SYSDEV.C,\ - $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RQ.C,\ - $(PDP11_DIR)PDP11_TS.C,$(PDP11_DIR)PDP11_DZ.C,\ - $(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_TQ.C,\ - $(PDP11_DIR)PDP11_PT.C,$(PDP11_DIR)PDP11_XQ.C -VAX_OBJS = $(VAX_DIR)VAX_CPU1.OBJ,$(VAX_DIR)VAX_CPU.OBJ,\ - $(VAX_DIR)VAX_FPA.OBJ,$(VAX_DIR)VAX_IO.OBJ,\ - $(VAX_DIR)VAX_MMU.OBJ,$(VAX_DIR)VAX_STDDEV.OBJ,\ - $(VAX_DIR)VAX_SYS.OBJ,$(VAX_DIR)VAX_SYSDEV.OBJ,\ - $(VAX_DIR)PDP11_RL.OBJ,$(VAX_DIR)PDP11_RQ.OBJ,\ - $(VAX_DIR)PDP11_TS.OBJ,$(VAX_DIR)PDP11_DZ.OBJ,\ - $(VAX_DIR)PDP11_LP.OBJ,$(VAX_DIR)PDP11_TQ.OBJ,\ - $(VAX_DIR)PDP11_PT.OBJ,$(VAX_DIR)PDP11_XQ.OBJ -VAX_OPTIONS = /INCLUDE=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR))/DEFINE=("USE_INT64=1") - -# -# If On Alpha, Build Everything. -# -.IFDEF __ALPHA__ -ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI H316 HP2100 I1401 I1620 IBM1130 NOVA PDP1 \ - PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 VAX -.ELSE -# -# Else We Are On VAX And Build Everything EXCEPT PDP-10 And VAX Since VAX -# Dosen't Have INT64 -# -ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI H316 HP2100 I1401 I1620 IBM1130 NOVA PDP1 \ - PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 S3 -.ENDIF - -# -# Build The Libraries. -# -$(LIB_DIR)SIMH-$(ARCH).OLB : $(SIMH_SOURCE) - $! - $! Building The $(SIMH_LIB) Library. - $! - $ $(CC)/OBJECT=$(SIMH_DIR) $(SIMH_SOURCE) - $ IF (F$SEARCH("$(SIMH_LIB)").EQS."") THEN - - LIBRARY/CREATE $(SIMH_LIB) - $ LIBRARY/REPLACE $(SIMH_LIB) $(SIMH_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -$(LIB_DIR)ALTAIR-$(ARCH).OLB : $(ALTAIR_SOURCE) - $! - $! Building The $(ALTAIR_LIB) Library. - $! - $ $(CC)$(ALTAIR_OPTIONS)/OBJECT=$(ALTAIR_DIR) - - $(ALTAIR_SOURCE) - $ IF (F$SEARCH("$(ALTAIR_LIB)").EQS."") THEN - - LIBRARY/CREATE $(ALTAIR_LIB) - $ LIBRARY/REPLACE $(ALTAIR_LIB) - - $(ALTAIR_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(ALTAIR_DIR)*.OBJ;* - -$(LIB_DIR)ALTAIRZ80-$(ARCH).OLB : $(ALTAIRZ80_SOURCE) - $! - $! Building The $(ALTAIRZ80_LIB) Library. - $! - $ $(CC)$(ALTAIRZ80_OPTIONS) - - /OBJECT=$(ALTAIRZ80_DIR) - - $(ALTAIRZ80_SOURCE) - $ IF (F$SEARCH("$(ALTAIRZ80_LIB)").EQS."") - - THEN LIBRARY/CREATE $(ALTAIRZ80_LIB) - $ LIBRARY/REPLACE $(ALTAIRZ80_LIB) - - $(ALTAIRZ80_OBJS) - $ DELETE/NOLOG/NOCONFIRM - - $(ALTAIRZ80_DIR)*.OBJ;* - -$(LIB_DIR)ECLIPSE-$(ARCH).OLB : $(ECLIPSE_SOURCE) - $! - $! Building The $(ECLIPSE_LIB) Library. - $! - $ $(CC)$(ECLIPSE_OPTIONS)/OBJECT=$(NOVA_DIR) - - $(ECLIPSE_SOURCE) - $ IF (F$SEARCH("$(ECLIPSE_LIB)").EQS."") THEN - - LIBRARY/CREATE $(ECLIPSE_LIB) - $ LIBRARY/REPLACE $(ECLIPSE_LIB) - - $(ECLIPSE_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(NOVA_DIR)*.OBJ;* - -$(LIB_DIR)GRI-$(ARCH).OLB : $(GRI_SOURCE) - $! - $! Building The $(GRI_LIB) Library. - $! - $ $(CC)$(GRI_OPTIONS)/OBJECT=$(GRI_DIR) - - $(GRI_SOURCE) - $ IF (F$SEARCH("$(GRI_LIB)").EQS."") THEN - - LIBRARY/CREATE $(GRI_LIB) - $ LIBRARY/REPLACE $(GRI_LIB) $(GRI_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(GRI_DIR)*.OBJ;* - -$(LIB_DIR)H316-$(ARCH).OLB : $(H316_SOURCE) - $! - $! Building The $(H316_LIB) Library. - $! - $ $(CC)$(H316_OPTIONS)/OBJECT=$(H316_DIR) - - $(H316_SOURCE) - $ IF (F$SEARCH("$(H316_LIB)").EQS."") THEN - - LIBRARY/CREATE $(H316_LIB) - $ LIBRARY/REPLACE $(H316_LIB) $(H316_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(H316_DIR)*.OBJ;* - -$(LIB_DIR)HP2100-$(ARCH).OLB : $(HP2100_SOURCE) - $! - $! Building The $(HP2100_LIB) Library. - $! - $ $(CC)$(HP2100_OPTIONS)/OBJECT=$(HP2100_DIR) - - $(HP2100_SOURCE) - $ IF (F$SEARCH("$(HP2100_LIB)").EQS."") THEN - - LIBRARY/CREATE $(HP2100_LIB) - $ LIBRARY/REPLACE $(HP2100_LIB) $(HP2100_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(HP2100_DIR)*.OBJ;* - -$(LIB_DIR)I1401-$(ARCH).OLB : $(I1401_SOURCE) - $! - $! Building The $(I1401_LIB) Library. - $! - $ $(CC)$(I1401_OPTIONS)/OBJECT=$(I1401_DIR) - - $(I1401_SOURCE) - $ IF (F$SEARCH("$(I1401_LIB)").EQS."") THEN - - LIBRARY/CREATE $(I1401_LIB) - $ LIBRARY/REPLACE $(I1401_LIB) $(I1401_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(I1401_DIR)*.OBJ;* - -$(LIB_DIR)I1620-$(ARCH).OLB : $(I1620_SOURCE) - $! - $! Building The $(I1620_LIB) Library. - $! - $ $(CC)$(I1620_OPTIONS)/OBJECT=$(I1620_DIR) - - $(I1620_SOURCE) - $ IF (F$SEARCH("$(I1620_LIB)").EQS."") THEN - - LIBRARY/CREATE $(I1620_LIB) - $ LIBRARY/REPLACE $(I1620_LIB) $(I1620_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(I1620_DIR)*.OBJ;* - -$(LIB_DIR)IBM1130-$(ARCH).OLB : $(IBM1130_SOURCE) - $! - $! Building The $(IBM1130_LIB) Library. - $! - $ $(CC)$(IBM1130_OPTIONS) - - /OBJECT=$(IBM1130_DIR) - - $(IBM1130_SOURCE) - $ IF (F$SEARCH("$(IBM1130_LIB)").EQS."") THEN - - LIBRARY/CREATE $(IBM1130_LIB) - $ LIBRARY/REPLACE $(IBM1130_LIB) $(IBM1130_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(IBM1130_DIR)*.OBJ;* - -$(LIB_DIR)ID16-$(ARCH).OLB : $(ID16_SOURCE) - $! - $! Building The $(ID16_LIB) Library. - $! - $ $(CC)$(ID16_OPTIONS)/OBJECT=$(ID16_DIR) - - $(ID16_SOURCE) - $ IF (F$SEARCH("$(ID16_LIB)").EQS."") THEN - - LIBRARY/CREATE $(ID16_LIB) - $ LIBRARY/REPLACE $(ID16_LIB) $(ID16_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(ID16_DIR)*.OBJ;* - -$(LIB_DIR)ID32-$(ARCH).OLB : $(ID32_SOURCE) - $! - $! Building The $(ID32_LIB) Library. - $! - $ $(CC)$(ID32_OPTIONS)/OBJECT=$(ID32_DIR) - - $(ID32_SOURCE) - $ IF (F$SEARCH("$(ID32_LIB)").EQS."") THEN - - LIBRARY/CREATE $(ID32_LIB) - $ LIBRARY/REPLACE $(ID32_LIB) $(ID32_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(ID32_DIR)*.OBJ;* - -$(LIB_DIR)NOVA-$(ARCH).OLB : $(NOVA_SOURCE) - $! - $! Building The $(NOVA_LIB) Library. - $! - $ $(CC)$(NOVA_OPTIONS)/OBJECT=$(NOVA_DIR) - - $(NOVA_SOURCE) - $ IF (F$SEARCH("$(NOVA_LIB)").EQS."") THEN - - LIBRARY/CREATE $(NOVA_LIB) - $ LIBRARY/REPLACE $(NOVA_LIB) $(NOVA_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(NOVA_DIR)*.OBJ;* - -$(LIB_DIR)PDP1-$(ARCH).OLB : $(PDP1_SOURCE) - $! - $! Building The $(PDP1_LIB) Library. - $! - $ $(CC)$(PDP1_OPTIONS)/OBJECT=$(PDP1_DIR) - - $(PDP1_SOURCE) - $ IF (F$SEARCH("$(PDP1_LIB)").EQS."") THEN - - LIBRARY/CREATE $(PDP1_LIB) - $ LIBRARY/REPLACE $(PDP1_LIB) $(PDP1_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(PDP1_DIR)*.OBJ;* - -$(LIB_DIR)PDP4-$(ARCH).OLB : $(PDP18B_SOURCE) - $! - $! Building The $(PDP4_LIB) Library. - $! - $ $(CC)$(PDP4_OPTIONS)/OBJECT=$(PDP18B_DIR) - - $(PDP18B_SOURCE) - $ IF (F$SEARCH("$(PDP4_LIB)").EQS."") THEN - - LIBRARY/CREATE $(PDP4_LIB) - $ LIBRARY/REPLACE $(PDP4_LIB) $(PDP18B_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(PDP18B_DIR)*.OBJ;* - -$(LIB_DIR)PDP7-$(ARCH).OLB : $(PDP18B_SOURCE) - $! - $! Building The $(PDP7_LIB) Library. - $! - $ $(CC)$(PDP7_OPTIONS)/OBJECT=$(PDP18B_DIR) - - $(PDP18B_SOURCE) - $ IF (F$SEARCH("$(PDP7_LIB)").EQS."") THEN - - LIBRARY/CREATE $(PDP7_LIB) - $ LIBRARY/REPLACE $(PDP7_LIB) $(PDP18B_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(PDP18B_DIR)*.OBJ;* - -$(LIB_DIR)PDP8-$(ARCH).OLB : $(PDP8_SOURCE) - $! - $! Building The $(PDP8_LIB) Library. - $! - $ $(CC)$(PDP8_OPTIONS)/OBJECT=$(PDP8_DIR) - - $(PDP8_SOURCE) - $ IF (F$SEARCH("$(PDP8_LIB)").EQS."") THEN - - LIBRARY/CREATE $(PDP8_LIB) - $ LIBRARY/REPLACE $(PDP8_LIB) $(PDP8_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(PDP8_DIR)*.OBJ;* - -$(LIB_DIR)PDP9-$(ARCH).OLB : $(PDP18B_SOURCE) - $! - $! Building The $(PDP9_LIB) Library. - $! - $ $(CC)$(PDP9_OPTIONS)/OBJECT=$(PDP18B_DIR) - - $(PDP18B_SOURCE) - $ IF (F$SEARCH("$(PDP9_LIB)").EQS."") THEN - - LIBRARY/CREATE $(PDP9_LIB) - $ LIBRARY/REPLACE $(PDP9_LIB) $(PDP18B_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(PDP18B_DIR)*.OBJ;* - -# -# If On Alpha, Build The PDP-10 Library. -# -.IFDEF __ALPHA__ -$(LIB_DIR)PDP10-$(ARCH).OLB : $(PDP10_SOURCE) - $! - $! Building The $(PDP10_LIB) Library. - $! - $ $(CC)$(PDP10_OPTIONS)/OBJECT=$(PDP10_DIR) - - $(PDP10_SOURCE) - $ IF (F$SEARCH("$(PDP10_LIB)").EQS."") THEN - - LIBRARY/CREATE $(PDP10_LIB) - $ LIBRARY/REPLACE $(PDP10_LIB) $(PDP10_OBJS) - DELETE/NOLOG/NOCONFIRM $(PDP10_DIR)*.OBJ;* -.ELSE -# -# We Are On VAX And Due To The Use of INT64 We Can't Build It. -# -$(LIB_DIR)PDP10-$(ARCH).OLB : - $! - $! Due To The Use Of INT64 We Can't Build The - $! $(LIB_DIR)PDP10-$(ARCH).OLB Library On VAX. - $! -.ENDIF - -$(LIB_DIR)PDP11-$(ARCH).OLB : $(PDP11_SOURCE) - $! - $! Building The $(PDP11_LIB) Library. - $! - $(CC)$(PDP11_OPTIONS)/OBJECT=$(PDP11_DIR) - - $(PDP11_SOURCE) - $ IF (F$SEARCH("$(PDP11_LIB)").EQS."") THEN - - LIBRARY/CREATE $(PDP11_LIB) - $ LIBRARY/REPLACE $(PDP11_LIB) $(PDP11_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(PDP11_DIR)*.OBJ;* - -$(LIB_DIR)PDP15-$(ARCH).OLB : $(PDP18B_SOURCE) - $! - $! Building The $(PDP15_LIB) Library. - $! - $ $(CC)$(PDP15_OPTIONS)/OBJECT=$(PDP18B_DIR) - - $(PDP18B_SOURCE) - $ IF (F$SEARCH("$(PDP15_LIB)").EQS."") THEN - - LIBRARY/CREATE $(PDP15_LIB) - $ LIBRARY/REPLACE $(PDP15_LIB) $(PDP18B_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(PDP18B_DIR)*.OBJ;* - -$(LIB_DIR)S3-$(ARCH).OLB : $(S3_SOURCE) - $! - $! Building The $(S3_LIB) Library. - $! - $ $(CC)$(S3_OPTIONS)/OBJECT=$(S3_DIR) $(S3_SOURCE) - $ IF (F$SEARCH("$(S3_LIB)").EQS."") THEN - - LIBRARY/CREATE $(S3_LIB) - $ LIBRARY/REPLACE $(S3_LIB) $(S3_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(S3_DIR)*.OBJ;* - -$(LIB_DIR)SDS-$(ARCH).OLB : $(SDS_SOURCE) - $! - $! Building The $(SDS_LIB) Library. - $! - $ $(CC)$(SDS_OPTIONS)/OBJECT=$(SDS_DIR) - - $(SDS_SOURCE) - $ IF (F$SEARCH("$(SDS_LIB)").EQS."") THEN - - LIBRARY/CREATE $(SDS_LIB) - $ LIBRARY/REPLACE $(SDS_LIB) $(SDS_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(SDS_DIR)*.OBJ;* - -# -# If On Alpha, Build The VAX Library. -# -.IFDEF __ALPHA__ -$(LIB_DIR)VAX-$(ARCH).OLB : $(VAX_SOURCE) - $! - $! Building The $(VAX_LIB) Library. - $! - $ $(CC)$(VAX_OPTIONS)/OBJECT=$(VAX_DIR) - - $(VAX_SOURCE) - $ IF (F$SEARCH("$(VAX_LIB)").EQS."") THEN - - LIBRARY/CREATE $(VAX_LIB) - $ LIBRARY/REPLACE $(VAX_LIB) $(VAX_OBJS) - $ DELETE/NOLOG/NOCONFIRM $(VAX_DIR)*.OBJ;* -.ELSE -# -# We Are On VAX And Due To The Use of INT64 We Can't Build It. -# -$(LIB_DIR)VAX-$(ARCH).OLB : - $! - $! Due To The Use Of INT64 We Can't Build The - $! $(LIB_DIR)VAX-$(ARCH).OLB Library On VAX. - $! -.ENDIF - -# -# Individual Simulator Builds. -# -ALTAIR : $(SIMH_LIB) $(ALTAIR_LIB) - $! - $! Building The $(BIN_DIR)ALTAIR-$(ARCH).EXE Simulator. - $! - $ $(CC)$(ALTAIR_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ALTAIR-$(ARCH).EXE - - SCP.OBJ,$(ALTAIR_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -ALTAIRZ80 : $(SIMH_LIB) $(ALTAIRZ80_LIB) - $! - $! Building The $(BIN_DIR)ALTAIRZ80-$(ARCH).EXE Simulator. - $! - $ $(CC)$(ALTAIRZ80_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ALTAIRZ80-$(ARCH).EXE - - SCP.OBJ,$(ALTAIRZ80_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -ECLIPSE : $(SIMH_LIB) $(ECLIPSE_LIB) - $! - $! Building The $(BIN_DIR)ECLPISE-$(ARCH).EXE Simulator. - $! - $ $(CC)$(ECLIPSE_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ECLIPSE-$(ARCH).EXE - - SCP.OBJ,$(ECLIPSE_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -GRI : $(SIMH_LIB) $(GRI_LIB) - $! - $! Building The $(BIN_DIR)GRI-$(ARCH).EXE Simulator. - $! - $ $(CC)$(GRI_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)GRI-$(ARCH).EXE - - SCP.OBJ,$(GRI_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -H316 : $(SIMH_LIB) $(H316_LIB) - $! - $! Building The $(BIN_DIR)H316-$(ARCH).EXE Simulator. - $! - $ $(CC)$(H316_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)H316-$(ARCH).EXE - - SCP.OBJ,$(H316_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -HP2100 : $(SIMH_LIB) $(HP2100_LIB) - $! - $! Building The $(BIN_DIR)HP2100-$(ARCH).EXE Simulator. - $! - $ $(CC)$(HP2100_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)HP2100-$(ARCH).EXE - - SCP.OBJ,$(HP2100_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -I1401 : $(SIMH_LIB) $(I1401_LIB) - $! - $! Building The $(BIN_DIR)I1401-$(ARCH).EXE Simulator. - $! - $ $(CC)$(I1401_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)I1401-$(ARCH).EXE - - SCP.OBJ,$(I1401_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -I1620 : $(SIMH_LIB) $(I1620_LIB) - $! - $! Building The $(BIN_DIR)I1620-$(ARCH).EXE Simulator. - $! - $ $(CC)$(I1620_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)I1620-$(ARCH).EXE - - SCP.OBJ,$(I1620_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -IBM1130 : $(SIMH_LIB) $(IBM1130_LIB) - $! - $! Building The $(BIN_DIR)IBM1130-$(ARCH).EXE Simulator. - $! - $ $(CC)$(IBM1130_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)IBM1130-$(ARCH).EXE - - SCP.OBJ,$(IBM1130_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -ID16 : $(SIMH_LIB) $(ID16_LIB) - $! - $! Building The $(BIN_DIR)ID16-$(ARCH).EXE Simulator. - $! - $ $(CC)$(ID16_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ID16-$(ARCH).EXE - - SCP.OBJ,$(ID16_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -ID32 : $(SIMH_LIB) $(ID32_LIB) - $! - $! Building The $(BIN_DIR)ID32-$(ARCH).EXE Simulator. - $! - $ $(CC)$(ID32_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ID32-$(ARCH).EXE - - SCP.OBJ,$(ID32_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -NOVA : $(SIMH_LIB) $(NOVA_LIB) - $! - $! Building The $(BIN_DIR)NOVA-$(ARCH).EXE Simulator. - $! - $ $(CC)$(NOVA_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)NOVA-$(ARCH).EXE - - SCP.OBJ,$(NOVA_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -PDP1 : $(SIMH_LIB) $(PDP1_LIB) - $! - $! Building The $(BIN_DIR)PDP1-$(ARCH).EXE Simulator. - $! - $ $(CC)$(PDP1_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP1-$(ARCH).EXE - - SCP.OBJ,$(PDP1_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -PDP4 : $(SIMH_LIB) $(PDP4_LIB) - $! - $! Building The $(BIN_DIR)PDP4-$(ARCH).EXE Simulator. - $! - $ $(CC)$(PDP4_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP4-$(ARCH).EXE - - SCP.OBJ,$(PDP4_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -PDP7 : $(SIMH_LIB) $(PDP7_LIB) - $! - $! Building The $(BIN_DIR)PDP7-$(ARCH).EXE Simulator. - $! - $ $(CC)$(PDP7_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP7-$(ARCH).EXE - - SCP.OBJ,$(PDP7_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -PDP8 : $(SIMH_LIB) $(PDP8_LIB) - $! - $! Building The $(BIN_DIR)PDP8-$(ARCH).EXE Simulator. - $! - $ $(CC)$(PDP8_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP8-$(ARCH).EXE - - SCP.OBJ,$(PDP8_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -PDP9 : $(SIMH_LIB) $(PDP9_LIB) - $! - $! Building The $(BIN_DIR)PDP9-$(ARCH).EXE Simulator. - $! - $ $(CC)$(PDP9_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP9-$(ARCH).EXE - - SCP.OBJ,$(PDP9_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -# -# If On Alpha, Build The PDP-10 Simulator. -# -.IFDEF __ALPHA__ -PDP10 : $(SIMH_LIB) $(PDP10_LIB) - $! - $! Building The $(BIN_DIR)PDP10-$(ARCH).EXE Simulator. - $! - $ $(CC)$(PDP10_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP10-$(ARCH).EXE - - SCP.OBJ,$(PDP10_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* -.ELSE -# -# Else We Are On VAX And Tell The User We Can't Build On VAX -# Due To The Use Of INT64. -# -PDP10 : - $! - $! Sorry, Can't Build $(BIN_DIR)PDP10-$(ARCH).EXE Simulator - $! Because It Requires The Use Of INT64. - $! -.ENDIF - -PDP11 : $(SIMH_LIB) $(PDP11_LIB) - $! - $! Building The $(BIN_DIR)PDP11-$(ARCH).EXE Simulator. - $! - $ $(CC)$(PDP11_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP11-$(ARCH).EXE - - SCP.OBJ,$(PDP11_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -PDP15 : $(SIMH_LIB) $(PDP15_LIB) - $! - $! Building The $(BIN_DIR)PDP15-$(ARCH).EXE Simulator. - $! - $ $(CC)$(PDP15_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP15-$(ARCH).EXE - - SCP.OBJ,$(PDP15_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -S3 : $(SIMH_LIB) $(S3_LIB) - $! - $! Building The $(BIN_DIR)S3-$(ARCH).EXE Simulator. - $! - $ $(CC)$(S3_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)S3-$(ARCH).EXE - - SCP.OBJ,$(S3_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -SDS : $(SIMH_LIB) $(SDS_LIB) - $! - $! Building The $(BIN_DIR)SDS-$(ARCH).EXE Simulator. - $! - $ $(CC)$(SDS_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)SDS-$(ARCH).EXE - - SCP.OBJ,$(SDS_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* - -# -# If On Alpha, Build The VAX Simulator. -# -.IFDEF __ALPHA__ -VAX : $(SIMH_LIB) $(VAX_LIB) - $! - $! Building The $(BIN_DIR)VAX-$(ARCH).EXE Simulator. - $! - $ $(CC)$(VAX_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C - $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)VAX-$(ARCH).EXE - - SCP.OBJ,$(VAX_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY - $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* -.ELSE -# -# Else We Are On VAX And Tell The User We Can't Build On VAX -# Due To The Use Of INT64. -# -VAX : - $! - $! Sorry, Can't Build $(BIN_DIR)VAX-$(ARCH).EXE Simulator - $! Because It Requires The Use Of INT64. - $! -.ENDIF - +# +# DESCRIP.MMS +# Written By: Robert Alan Byer +# byer@mail.ourservers.net +# +# Modified By: Mark Pizzolato +# mark@infocomm.com +# +# This MMS/MMK build script is used to compile the various simulators in +# the SIMH package for OpenVMS using DEC C v6.0-001. +# +# Notes: On VAX, the PDP-10 and VAX simulator will not be built due to the +# fact that INT64 is required for those simulators. +# +# When using DEC's MMS on an Alpha you must use +# /MACRO=("__ALPHA__=1") to compile properly. +# +# This build script will accept the following build options. +# +# ALL Just Build "Everything". +# ALTAIR Just Build The MITS Altair. +# ALTAIRZ80 Just Build The MITS Altair Z80. +# ECLIPSE Just Build The Data General Eclipse. +# GRI Just Build The GRI Corporation GRI-909. +# H316 Just Build The Honewell 316/516. +# HP2100 Just Build The Hewlett-Packard HP-2100. +# I1401 Just Build The IBM 1401. +# IBM1130 Just Build The IBM 1130. +# ID16 Just Build The Interdata 16-bit CPU. +# ID32 Just Build The Interdata 32-bit CPU. +# NOVA Just Build The Data General Nova. +# PDP1 Just Build The DEC PDP-1. +# PDP4 Just Build The DEC PDP-4. +# PDP7 Just Build The DEC PDP-7. +# PDP8 Just Build The DEC PDP-8. +# PDP9 Just Build The DEC PDP-9. +# PDP10 Just Build The DEC PDP-10. +# PDP11 Just Build The DEC PDP-11. +# PDP15 Just Build The DEC PDP-15. +# S3 Just Build The IBM System 3. +# SDS Just Build The SDS 940. +# VAX Just Build The DEC VAX. +# CLEAN Will Clean Files Back To Base Kit. +# +# To build with debugging enabled (which will also enable traceback +# information) use.. +# +# MMK/FORCE/MACRO=(DEBUG=1) +# +# This will produce an executable named {Simulator}-{VAX|AXP}-DBG.EXE +# + +# +# Define The BIN Directory Where The Executables Will Go. +# +BIN_DIR = SYS$DISK:[.BIN] + +# +# Define Our Library Directory. +# +LIB_DIR = SYS$DISK:[.LIB] + +# +# Let's See If We Are Going To Build With DEBUG Enabled. +# +.IFDEF DEBUG +CC_DEBUG = /DEBUG=ALL +LINK_DEBUG = /DEBUG/TRACEBACK +CC_OPTIMIZE = /NOOPTIMIZE +.IFDEF __ALPHA__ +CC_FLAGS = /PREFIX=ALL +ARCH = AXP-DBG +.ELSE +ARCH = VAX-DBG +CC_FLAGS = $(CC_FLAGS) +.ENDIF +.ELSE +CC_DEBUG = /NODEBUG +LINK_DEBUG = /NODEBUG/NOTRACEBACK +.IFDEF __ALPHA__ +CC_OPTIMIZE = /OPTIMIZE=(LEVEL=5,TUNE=HOST)/ARCH=HOST +CC_FLAGS = /PREFIX=ALL +ARCH = AXP +.ELSE +CC_OPTIMIZE = /OPTIMIZE +ARCH = VAX +CC_FLAGS = $(CC_FLAGS) +.ENDIF +.ENDIF + +# +# Define Our Compiler Flags +# +CC_FLAGS = $(CC_FLAGS)$(CC_DEBUG)$(CC_OPTIMIZE)/NEST=PRIMARY/NAME=(AS_IS,SHORTENED) + +# +# Define The Compile Command. +# +CC = CC/DECC$(CC_FLAGS) + +# +# First, Let's Check To Make Sure We Have A SYS$DISK:[.BIN] And +# SYS$DISK:[.LIB] Directory. +# +.FIRST + @ IF (F$SEARCH("SYS$DISK:[]BIN.DIR").EQS."") THEN CREATE/DIRECTORY $(BIN_DIR) + @ IF (F$SEARCH("SYS$DISK:[]LIB.DIR").EQS."") THEN CREATE/DIRECTORY $(LIB_DIR) + +# +# Core SIMH File Definitions. +# +SIMH_DIR = SYS$DISK:[] +SIMH_LIB = $(LIB_DIR)SIMH-$(ARCH).OLB +SIMH_SOURCE = $(SIMH_DIR)SCP_TTY.C,$(SIMH_DIR)SIM_SOCK.C,\ + $(SIMH_DIR)SIM_TMXR.C,$(SIMH_DIR)SIM_ETHER.C,\ + $(SIMH_DIR)SIM_TAPE.C +SIMH_OBJS = $(SIMH_DIR)SCP_TTY.OBJ,$(SIMH_DIR)SIM_SOCK.OBJ,\ + $(SIMH_DIR)SIM_TMXR.OBJ,$(SIMH_DIR)SIM_ETHER.OBJ,\ + $(SIMH_DIR)SIM_TAPE.OBJ + +# +# MITS Altair Simulator Definitions. +# +ALTAIR_DIR = SYS$DISK:[.ALTAIR] +ALTAIR_LIB = $(LIB_DIR)ALTAIR-$(ARCH).OLB +ALTAIR_SOURCE = $(ALTAIR_DIR)ALTAIR_SIO.C,$(ALTAIR_DIR)ALTAIR_CPU.C,\ + $(ALTAIR_DIR)ALTAIR_DSK.C,$(ALTAIR_DIR)ALTAIR_SYS.C +ALTAIR_OBJS = $(ALTAIR_DIR)ALTAIR_SIO.OBJ,$(ALTAIR_DIR)ALTAIR_CPU.OBJ,\ + $(ALTAIR_DIR)ALTAIR_DSK.OBJ,$(ALTAIR_DIR)ALTAIR_SYS.OBJ +ALTAIR_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ALTAIR_DIR)) + +# +# MITS Altair Z80 Simulator Definitions. +# +ALTAIRZ80_DIR = SYS$DISK:[.ALTAIRZ80] +ALTAIRZ80_LIB = $(LIB_DIR)ALTAIRZ80-$(ARCH).OLB +ALTAIRZ80_SOURCE = $(ALTAIRZ80_DIR)ALTAIRZ80_CPU.C,\ + $(ALTAIRZ80_DIR)ALTAIRZ80_DSK.C,\ + $(ALTAIRZ80_DIR)ALTAIRZ80_SIO.C,\ + $(ALTAIRZ80_DIR)ALTAIRZ80_SYS.C,\ + $(ALTAIRZ80_DIR)ALTAIRZ80_HDSK.C +ALTAIRZ80_OBJS = $(ALTAIRZ80_DIR)ALTAIRZ80_CPU.OBJ,\ + $(ALTAIRZ80_DIR)ALTAIRZ80_DSK.OBJ,\ + $(ALTAIRZ80_DIR)ALTAIRZ80_SIO.OBJ,\ + $(ALTAIRZ80_DIR)ALTAIRZ80_SYS.OBJ,\ + $(ALTAIRZ80_DIR)ALTAIRZ80_HDSK.OBJ +ALTAIRZ80_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ALTAIRZ80_DIR)) + +# +# Data General Nova Simulator Definitions. +# +NOVA_DIR = SYS$DISK:[.NOVA] +NOVA_LIB = $(LIB_DIR)NOVA-$(ARCH).OLB +NOVA_SOURCE = $(NOVA_DIR)NOVA_SYS.C,$(NOVA_DIR)NOVA_CPU.C,\ + $(NOVA_DIR)NOVA_DKP.C,$(NOVA_DIR)NOVA_DSK.C,\ + $(NOVA_DIR)NOVA_LP.C,$(NOVA_DIR)NOVA_MTA.C,\ + $(NOVA_DIR)NOVA_PLT.C,$(NOVA_DIR)NOVA_PT.C,\ + $(NOVA_DIR)NOVA_CLK.C,$(NOVA_DIR)NOVA_TT.C,\ + $(NOVA_DIR)NOVA_TT1.C +NOVA_OBJS = $(NOVA_DIR)NOVA_SYS.OBJ,$(NOVA_DIR)NOVA_CPU.OBJ,\ + $(NOVA_DIR)NOVA_DKP.OBJ,$(NOVA_DIR)NOVA_DSK.OBJ,\ + $(NOVA_DIR)NOVA_LP.OBJ,$(NOVA_DIR)NOVA_MTA.OBJ,\ + $(NOVA_DIR)NOVA_PLT.OBJ,$(NOVA_DIR)NOVA_PT.OBJ,\ + $(NOVA_DIR)NOVA_CLK.OBJ,$(NOVA_DIR)NOVA_TT.OBJ,\ + $(NOVA_DIR)NOVA_TT1.OBJ +NOVA_OPTIONS = /INCLUDE=($(SIMH_DIR),$(NOVA_DIR)) + +# +# Data General Eclipse Simulator Definitions. +# +ECLIPSE_LIB = $(LIB_DIR)ECLIPSE-$(ARCH).OLB +ECLIPSE_SOURCE = $(NOVA_DIR)ECLIPSE_CPU.C,$(NOVA_DIR)ECLIPSE_TT.C,\ + $(NOVA_DIR)NOVA_SYS.C,$(NOVA_DIR)NOVA_DKP.C,\ + $(NOVA_DIR)NOVA_DSK.C,$(NOVA_DIR)NOVA_LP.C,\ + $(NOVA_DIR)NOVA_MTA.C,$(NOVA_DIR)NOVA_PLT.C,\ + $(NOVA_DIR)NOVA_PT.C,$(NOVA_DIR)NOVA_CLK.C,\ + $(NOVA_DIR)NOVA_TT1.C +ECLIPSE_OBJS = $(NOVA_DIR)ECLIPSE_CPU.OBJ,$(NOVA_DIR)ECLIPSE_TT.OBJ,\ + $(NOVA_DIR)NOVA_SYS.OBJ,$(NOVA_DIR)NOVA_DKP.OBJ,\ + $(NOVA_DIR)NOVA_DSK.OBJ,$(NOVA_DIR)NOVA_LP.OBJ,\ + $(NOVA_DIR)NOVA_MTA.OBJ,$(NOVA_DIR)NOVA_PLT.OBJ,\ + $(NOVA_DIR)NOVA_PT.OBJ,$(NOVA_DIR)NOVA_CLK.OBJ,\ + $(NOVA_DIR)NOVA_TT1.OBJ +ECLIPSE_OPTIONS = /INCLUDE=($(SIMH_DIR),$(NOVA_DIR))/DEFINE=("ECLIPSE=1") + +# +# GRI Corporation GRI-909 Simulator Definitions. +# +GRI_DIR = SYS$DISK:[.GRI] +GRI_LIB = $(LIB_DIR)GRI-$(ARCH).OLB +GRI_SOURCE = $(GRI_DIR)GRI_CPU.C,$(GRI_DIR)GRI_STDDEV.C,$(GRI_DIR)GRI_SYS.C +GRI_OBJS = $(GRI_DIR)GRI_CPU.OBJ,$(GRI_DIR)GRI_STDDEV.OBJ,\ + $(GRI_DIR)GRI_SYS.OBJ +GRI_OPTIONS = /INCLUDE=($(SIMH_DIR),$(GRI_DIR)) + +# +# Honeywell 316/516 Simulator Definitions. +# +H316_DIR = SYS$DISK:[.H316] +H316_LIB = $(LIB_DIR)H316-$(ARCH).OLB +H316_SOURCE = $(H316_DIR)H316_STDDEV.C,$(H316_DIR)H316_LP.C,\ + $(H316_DIR)H316_CPU.C,$(H316_DIR)H316_SYS.C +H316_OBJS = $(H316_DIR)H316_STDDEV.OBJ,$(H316_DIR)H316_LP.OBJ,\ + $(H316_DIR)H316_CPU.OBJ,$(H316_DIR)H316_SYS.OBJ +H316_OPTIONS = /INCLUDE=($(SIMH_DIR),$(H316_DIR)) + +# +# Hewlett-Packard HP-2100 Simulator Definitions. +# +HP2100_DIR = SYS$DISK:[.HP2100] +HP2100_LIB = $(LIB_DIR)HP2100-$(ARCH).OLB +HP2100_SOURCE = $(HP2100_DIR)HP2100_STDDEV.C,$(HP2100_DIR)HP2100_DP.C,\ + $(HP2100_DIR)HP2100_DQ.C,$(HP2100_DIR)HP2100_DR.C,\ + $(HP2100_DIR)HP2100_LPS.C,$(HP2100_DIR)HP2100_MS.C,\ + $(HP2100_DIR)HP2100_MT.C,$(HP2100_DIR)HP2100_MUX.C,\ + $(HP2100_DIR)HP2100_CPU.C,$(HP2100_DIR)HP2100_FP.C,\ + $(HP2100_DIR)HP2100_SYS.C,$(HP2100_DIR)HP2100_LPT.C,\ + $(HP2100_DIR)HP2100_IPL.C +HP2100_OBJS = $(HP2100_DIR)HP2100_STDDEV.OBJ,$(HP2100_DIR)HP2100_DP.OBJ,\ + $(HP2100_DIR)HP2100_DQ.OBJ,$(HP2100_DIR)HP2100_DR.OBJ,\ + $(HP2100_DIR)HP2100_LPS.OBJ,$(HP2100_DIR)HP2100_MS.OBJ,\ + $(HP2100_DIR)HP2100_MT.OBJ,$(HP2100_DIR)HP2100_MUX.OBJ,\ + $(HP2100_DIR)HP2100_CPU.OBJ,$(HP2100_DIR)HP2100_FP.OBJ,\ + $(HP2100_DIR)HP2100_SYS.OBJ,$(HP2100_DIR)HP2100_LPT.OBJ,\ + $(HP2100_DIR)HP2100_IPL.OBJ +HP2100_OPTIONS = /INCLUDE=($(SIMH_DIR),$(HP2100_DIR)) + +# +# Interdata 16-bit CPU. +# +ID16_DIR = SYS$DISK:[.INTERDATA] +ID16_LIB = $(LIB_DIR)ID16-$(ARCH).OLB +ID16_SOURCE = $(ID16_DIR)ID16_CPU.C,$(ID16_DIR)ID16_SYS.C,$(ID16_DIR)ID_DP.C,\ + $(ID16_DIR)ID_FD.C,$(ID16_DIR)ID_FP.C,$(ID16_DIR)ID_IDC.C,\ + $(ID16_DIR)ID_IO.C,$(ID16_DIR)ID_LP.C,$(ID16_DIR)ID_MT.C,\ + $(ID16_DIR)ID_PAS.C,$(ID16_DIR)ID_PT.C,$(ID16_DIR)ID_TT.C,\ + $(ID16_DIR)ID_UVC.C,$(ID16_DIR)ID16_DBOOT.C,$(ID16_DIR)ID_TTP.C +ID16_OBJS = $(ID16_DIR)ID16_CPU.OBJ,$(ID16_DIR)ID16_SYS.OBJ,\ + $(ID16_DIR)ID_DP.OBJ,$(ID16_DIR)ID_FD.OBJ,$(ID16_DIR)ID_FP.OBJ,\ + $(ID16_DIR)ID_IDC.OBJ,$(ID16_DIR)ID_IO.OBJ,$(ID16_DIR)ID_LP.OBJ,\ + $(ID16_DIR)ID_MT.OBJ,$(ID16_DIR)ID_PAS.OBJ,$(ID16_DIR)ID_PT.OBJ,\ + $(ID16_DIR)ID_TT.OBJ,$(ID16_DIR)ID_UVC.OBJ,\ + $(ID16_DIR)ID16_DBOOT.OBJ,$(ID16_DIR)ID_TTP.OBJ +ID16_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ID16_DIR)) + +# +# Interdata 32-bit CPU. +# +ID32_DIR = SYS$DISK:[.INTERDATA] +ID32_LIB = $(LIB_DIR)ID32-$(ARCH).OLB +ID32_SOURCE = $(ID32_DIR)ID32_CPU.C,$(ID32_DIR)ID32_SYS.C,$(ID32_DIR)ID_DP.C,\ + $(ID32_DIR)ID_FD.C,$(ID32_DIR)ID_FP.C,$(ID32_DIR)ID_IDC.C,\ + $(ID32_DIR)ID_IO.C,$(ID32_DIR)ID_LP.C,$(ID32_DIR)ID_MT.C,\ + $(ID32_DIR)ID_PAS.C,$(ID32_DIR)ID_PT.C,$(ID32_DIR)ID_TT.C,\ + $(ID32_DIR)ID_UVC.C,$(ID32_DIR)ID32_DBOOT.C,$(ID32_DIR)ID_TTP.C +ID32_OBJS = $(ID32_DIR)ID32_CPU.OBJ,$(ID32_DIR)ID32_SYS.OBJ,\ + $(ID32_DIR)ID_DP.OBJ,$(ID32_DIR)ID_FD.OBJ,\ + $(ID32_DIR)ID_FP.OBJ,$(ID32_DIR)ID_IDC.OBJ,\ + $(ID32_DIR)ID_IO.OBJ,$(ID32_DIR)ID_LP.OBJ,$(ID32_DIR)ID_MT.OBJ,\ + $(ID32_DIR)ID_PAS.OBJ,$(ID32_DIR)ID_PT.OBJ,$(ID32_DIR)ID_TT.OBJ,\ + $(ID32_DIR)ID_UVC.OBJ,$(ID32_DIR)ID32_DBOOT.OBJ,\ + $(ID32_DIR)ID_TTP.OBJ +ID32_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ID32_DIR)) + +# +# IBM 1130 Simulator Definitions. +# +IBM1130_DIR = SYS$DISK:[.IBM1130] +IBM1130_LIB = $(LIB_DIR)IBM1130-$(ARCH).OLB +IBM1130_SOURCE = $(IBM1130_DIR)IBM1130_CPU.C,$(IBM1130_DIR)IBM1130_CR.C,\ + $(IBM1130_DIR)IBM1130_DISK.C,$(IBM1130_DIR)IBM1130_STDDEV.C,\ + $(IBM1130_DIR)IBM1130_SYS.C,$(IBM1130_DIR)IBM1130_GDU.C,\ + $(IBM1130_DIR)IBM1130_GUI.C,$(IBM1130_DIR)IBM1130_PRT.C +IBM1130_OBJS = $(IBM1130_DIR)IBM1130_CPU.OBJ,$(IBM1130_DIR)IBM1130_CR.OBJ,\ + $(IBM1130_DIR)IBM1130_DISK.OBJ,$(IBM1130_DIR)IBM1130_STDDEV.OBJ,\ + $(IBM1130_DIR)IBM1130_SYS.OBJ,$(IBM1130_DIR)IBM1130_GDU.OBJ,\ + $(IBM1130_DIR)IBM1130_GUI.OBJ,$(IBM1130_DIR)IBM1130_PRT.OBJ +IBM1130_OPTIONS = /INCLUDE=($(SIMH_DIR),$(IBM1130_DIR)) + +# +# IBM 1401 Simulator Definitions. +# +I1401_DIR = SYS$DISK:[.I1401] +I1401_LIB = $(LIB_DIR)I1401-$(ARCH).OLB +I1401_SOURCE = $(I1401_DIR)I1401_LP.C,$(I1401_DIR)I1401_CPU.C,\ + $(I1401_DIR)I1401_IQ.C,$(I1401_DIR)I1401_CD.C,\ + $(I1401_DIR)I1401_MT.C,$(I1401_DIR)I1401_DP.C,\ + $(I1401_DIR)I1401_SYS.C +I1401_OBJS = $(I1401_DIR)I1401_LP.OBJ,$(I1401_DIR)I1401_CPU.OBJ,\ + $(I1401_DIR)I1401_IQ.OBJ,$(I1401_DIR)I1401_CD.OBJ,\ + $(I1401_DIR)I1401_MT.OBJ,$(I1401_DIR)I1401_DP.OBJ,\ + $(I1401_DIR)I1401_SYS.OBJ +I1401_OPTIONS = /INCLUDE=($(SIMH_DIR),$(I1401_DIR)) + + +# +# IBM 1620 Simulators Definitions. +# +I1620_DIR = SYS$DISK:[.I1620] +I1620_LIB = $(LIB_DIR)I1620-$(ARCH).OLB +I1620_SOURCE = $(I1620_DIR)I1620_CD.C,$(I1620_DIR)I1620_DP.C,\ + $(I1620_DIR)I1620_PT.C,$(I1620_DIR)I1620_TTY.C,\ + $(I1620_DIR)I1620_CPU.C,$(I1620_DIR)I1620_LP.C,\ + $(I1620_DIR)I1620_FP.C,$(I1620_DIR)I1620_SYS.C +I1620_OBJS = $(I1620_DIR)I1620_CD.OBJ,$(I1620_DIR)I1620_DP.OBJ,\ + $(I1620_DIR)I1620_PT.OBJ,$(I1620_DIR)I1620_TTY.OBJ,\ + $(I1620_DIR)I1620_CPU.OBJ,$(I1620_DIR)I1620_LP.OBJ,\ + $(I1620_DIR)I1620_FP.OBJ,$(I1620_DIR)I1620_SYS.OBJ +I1620_OPTIONS = /INCLUDE=($(SIMH_DIR),$(I1620_DIR)) + +# +# PDP-1 Simulator Definitions. +# +PDP1_DIR = SYS$DISK:[.PDP1] +PDP1_LIB = $(LIB_DIR)PDP1-$(ARCH).OLB +PDP1_SOURCE = $(PDP1_DIR)PDP1_LP.C,$(PDP1_DIR)PDP1_CPU.C,\ + $(PDP1_DIR)PDP1_STDDEV.C,$(PDP1_DIR)PDP1_SYS.C,\ + $(PDP1_DIR)PDP1_DT.C,$(PDP1_DIR)PDP1_DRM.C +PDP1_OBJS = $(PDP1_DIR)PDP1_LP.OBJ,$(PDP1_DIR)PDP1_CPU.OBJ,\ + $(PDP1_DIR)PDP1_STDDEV.OBJ,$(PDP1_DIR)PDP1_SYS.OBJ,\ + $(PDP1_DIR)PDP1_DT.OBJ,$(PDP1_DIR)PDP1_DRM.OBJ +PDP1_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP1_DIR)) + +# +# Digital Equipment PDP-8 Simulator Definitions. +# +PDP8_DIR = SYS$DISK:[.PDP8] +PDP8_LIB = $(LIB_DIR)PDP8-$(ARCH).OLB +PDP8_SOURCE = $(PDP8_DIR)PDP8_CPU.C,$(PDP8_DIR)PDP8_CLK.C,\ + $(PDP8_DIR)PDP8_DF.C,$(PDP8_DIR)PDP8_DT.C,\ + $(PDP8_DIR)PDP8_LP.C,$(PDP8_DIR)PDP8_MT.C,\ + $(PDP8_DIR)PDP8_PT.C,$(PDP8_DIR)PDP8_RF.C,\ + $(PDP8_DIR)PDP8_RK.C,$(PDP8_DIR)PDP8_RX.C,\ + $(PDP8_DIR)PDP8_SYS.C,$(PDP8_DIR)PDP8_TT.C,\ + $(PDP8_DIR)PDP8_TTX.C,$(PDP8_DIR)PDP8_RL.C +PDP8_OBJS = $(PDP8_DIR)PDP8_CPU.OBJ,$(PDP8_DIR)PDP8_CLK.OBJ,\ + $(PDP8_DIR)PDP8_DF.OBJ,$(PDP8_DIR)PDP8_DT.OBJ,\ + $(PDP8_DIR)PDP8_LP.OBJ,$(PDP8_DIR)PDP8_MT.OBJ,\ + $(PDP8_DIR)PDP8_PT.OBJ,$(PDP8_DIR)PDP8_RF.OBJ,\ + $(PDP8_DIR)PDP8_RK.OBJ,$(PDP8_DIR)PDP8_RX.OBJ,\ + $(PDP8_DIR)PDP8_SYS.OBJ,$(PDP8_DIR)PDP8_TT.OBJ,\ + $(PDP8_DIR)PDP8_TTX.OBJ,$(PDP8_DIR)PDP8_RL.OBJ +PDP8_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP8_DIR)) + +# +# Digital Equipment PDP-4, PDP-7, PDP-9 And PDP-15 Simulator Definitions. +# +PDP18B_DIR = SYS$DISK:[.PDP18B] +PDP4_LIB = $(LIB_DIR)PDP4-$(ARCH).OLB +PDP7_LIB = $(LIB_DIR)PDP7-$(ARCH).OLB +PDP9_LIB = $(LIB_DIR)PDP9-$(ARCH).OLB +PDP15_LIB = $(LIB_DIR)PDP15-$(ARCH).OLB +PDP18B_SOURCE = $(PDP18B_DIR)PDP18B_DT.C,$(PDP18B_DIR)PDP18B_DRM.C,\ + $(PDP18B_DIR)PDP18B_CPU.C,$(PDP18B_DIR)PDP18B_LP.C,\ + $(PDP18B_DIR)PDP18B_MT.C,$(PDP18B_DIR)PDP18B_RF.C,\ + $(PDP18B_DIR)PDP18B_RP.C,$(PDP18B_DIR)PDP18B_STDDEV.C,\ + $(PDP18B_DIR)PDP18B_SYS.C,$(PDP18B_DIR)PDP18B_TT1.C,\ + $(PDP18B_DIR)PDP18B_RB.C +PDP18B_OBJS = $(PDP18B_DIR)PDP18B_DT.OBJ,$(PDP18B_DIR)PDP18B_DRM.OBJ,\ + $(PDP18B_DIR)PDP18B_CPU.OBJ,$(PDP18B_DIR)PDP18B_LP.OBJ,\ + $(PDP18B_DIR)PDP18B_MT.OBJ,$(PDP18B_DIR)PDP18B_RF.OBJ,\ + $(PDP18B_DIR)PDP18B_RP.OBJ,$(PDP18B_DIR)PDP18B_STDDEV.OBJ,\ + $(PDP18B_DIR)PDP18B_SYS.OBJ,$(PDP18B_DIR)PDP18B_TT1.OBJ,\ + $(PDP18B_DIR)PDP18B_RB.OBJ +PDP4_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP4=1") +PDP7_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP7=1") +PDP9_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP9=1") +PDP15_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP15=1") + +# +# Digital Equipment PDP-11 Simulator Definitions. +# +PDP11_DIR = SYS$DISK:[.PDP11] +PDP11_LIB = $(LIB_DIR)PDP11-$(ARCH).OLB +PDP11_SOURCE = $(PDP11_DIR)PDP11_FP.C,$(PDP11_DIR)PDP11_CPU.C,\ + $(PDP11_DIR)PDP11_DZ.C,$(PDP11_DIR)PDP11_CIS.C,\ + $(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_RK.C,\ + $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RP.C,\ + $(PDP11_DIR)PDP11_RX.C,$(PDP11_DIR)PDP11_STDDEV.C,\ + $(PDP11_DIR)PDP11_SYS.C,$(PDP11_DIR)PDP11_TC.C,\ + $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\ + $(PDP11_DIR)PDP11_IO.C,$(PDP11_DIR)PDP11_RQ.C,\ + $(PDP11_DIR)PDP11_TQ.C,$(PDP11_DIR)PDP11_PCLK.C,\ + $(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_PT.C,\ + $(PDP11_DIR)PDP11_HK.C,$(PDP11_DIR)PDP11_XQ.C,\ + $(PDP11_DIR)PDP11_XU.C +PDP11_OBJS = $(PDP11_DIR)PDP11_FP.OBJ,$(PDP11_DIR)PDP11_CPU.OBJ,\ + $(PDP11_DIR)PDP11_DZ.OBJ,$(PDP11_DIR)PDP11_CIS.OBJ,\ + $(PDP11_DIR)PDP11_LP.OBJ,$(PDP11_DIR)PDP11_RK.OBJ,\ + $(PDP11_DIR)PDP11_RL.OBJ,$(PDP11_DIR)PDP11_RP.OBJ,\ + $(PDP11_DIR)PDP11_RX.OBJ,$(PDP11_DIR)PDP11_STDDEV.OBJ,\ + $(PDP11_DIR)PDP11_SYS.OBJ,$(PDP11_DIR)PDP11_TC.OBJ,\ + $(PDP11_DIR)PDP11_TM.OBJ,$(PDP11_DIR)PDP11_TS.OBJ,\ + $(PDP11_DIR)PDP11_IO.OBJ,$(PDP11_DIR)PDP11_RQ.OBJ,\ + $(PDP11_DIR)PDP11_TQ.OBJ,$(PDP11_DIR)PDP11_PCLK.OBJ,\ + $(PDP11_DIR)PDP11_RY.OBJ,$(PDP11_DIR)PDP11_PT.OBJ,\ + $(PDP11_DIR)PDP11_HK.OBJ,$(PDP11_DIR)PDP11_XQ.OBJ,\ + $(PDP11_DIR)PDP11_XU.OBJ +PDP11_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP11_DIR))/DEFINE=("VM_PDP11=1") + +# +# Digital Equipment PDP-10 Simulator Definitions. +# +PDP10_DIR = SYS$DISK:[.PDP10] +PDP10_LIB = $(LIB_DIR)PDP10-$(ARCH).OLB +PDP10_SOURCE = $(PDP10_DIR)PDP10_FE.C,\ + $(PDP10_DIR)PDP10_CPU.C,$(PDP10_DIR)PDP10_KSIO.C,\ + $(PDP10_DIR)PDP10_LP20.C,$(PDP10_DIR)PDP10_MDFP.C,\ + $(PDP10_DIR)PDP10_PAG.C,$(PDP10_DIR)PDP10_XTND.C,\ + $(PDP10_DIR)PDP10_RP.C,$(PDP10_DIR)PDP10_SYS.C,\ + $(PDP10_DIR)PDP10_TIM.C,$(PDP10_DIR)PDP10_TU.C,\ + $(PDP11_DIR)PDP11_PT.C,$(PDP11_DIR)PDP11_DZ.C,\ + $(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_XU.C +PDP10_OBJS = $(PDP10_DIR)PDP10_FE.OBJ,\ + $(PDP10_DIR)PDP10_CPU.OBJ,$(PDP10_DIR)PDP10_KSIO.OBJ,\ + $(PDP10_DIR)PDP10_LP20.OBJ,$(PDP10_DIR)PDP10_MDFP.OBJ,\ + $(PDP10_DIR)PDP10_PAG.OBJ,$(PDP10_DIR)PDP10_XTND.OBJ,\ + $(PDP10_DIR)PDP10_RP.OBJ,$(PDP10_DIR)PDP10_SYS.OBJ,\ + $(PDP10_DIR)PDP10_TIM.OBJ,$(PDP10_DIR)PDP10_TU.OBJ,\ + $(PDP10_DIR)PDP11_PT.OBJ,$(PDP10_DIR)PDP11_DZ.OBJ,\ + $(PDP10_DIR)PDP11_RY.OBJ,$(PDP10_DIR)PDP11_XU.OBJ +PDP10_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP10_DIR),$(PDP11_DIR))/DEFINE=("USE_INT64=1","VM_PDP10=1") + +# +# IBM System 3 Simulator Definitions. +# +S3_DIR = SYS$DISK:[.S3] +S3_LIB = $(LIB_DIR)S3-$(ARCH).OLB +S3_SOURCE = $(S3_DIR)S3_CD.C,$(S3_DIR)S3_CPU.C,$(S3_DIR)S3_DISK.C,\ + $(S3_DIR)S3_LP.C,$(S3_DIR)S3_PKB.C,$(S3_DIR)S3_SYS.C +S3_OBJS = $(S3_DIR)S3_CD.OBJ,$(S3_DIR)S3_CPU.OBJ,$(S3_DIR)S3_DISK.OBJ,\ + $(S3_DIR)S3_LP.OBJ,$(S3_DIR)S3_PKB.OBJ,$(S3_DIR)S3_SYS.OBJ +S3_OPTIONS = /INCLUDE=($(SIMH_DIR),$(S3_DIR)) + +# +# SDS 940 +# +SDS_DIR = SYS$DISK:[.SDS] +SDS_LIB = $(LIB_DIR)SDS-$(ARCH).OLB +SDS_SOURCE = $(SDS_DIR)SDS_CPU.C,$(SDS_DIR)SDS_DRM.C,$(SDS_DIR)SDS_DSK.C,\ + $(SDS_DIR)SDS_IO.C,$(SDS_DIR)SDS_LP.C,$(SDS_DIR)SDS_MT.C,\ + $(SDS_DIR)SDS_MUX.C,$(SDS_DIR)SDS_RAD.C,$(SDS_DIR)SDS_STDDEV.C,\ + $(SDS_DIR)SDS_SYS.C +SDS_OBJS = $(SDS_DIR)SDS_CPU.OBJ,$(SDS_DIR)SDS_DRM.OBJ,$(SDS_DIR)SDS_DSK.OBJ,\ + $(SDS_DIR)SDS_IO.OBJ,$(SDS_DIR)SDS_LP.OBJ,$(SDS_DIR)SDS_MT.OBJ,\ + $(SDS_DIR)SDS_MUX.OBJ,$(SDS_DIR)SDS_RAD.OBJ,\ + $(SDS_DIR)SDS_STDDEV.OBJ,$(SDS_DIR)SDS_SYS.OBJ +SDS_OPTIONS = /INCLUDE=($(SIMH_DIR),$(SDS_DIR)) + +# +# Digital Equipment VAX Simulator Definitions. +# +VAX_DIR = SYS$DISK:[.VAX] +VAX_LIB = $(LIB_DIR)VAX-$(ARCH).OLB +VAX_SOURCE = $(VAX_DIR)VAX_CPU1.C,$(VAX_DIR)VAX_CPU.C,\ + $(VAX_DIR)VAX_FPA.C,$(VAX_DIR)VAX_IO.C,\ + $(VAX_DIR)VAX_MMU.C,$(VAX_DIR)VAX_STDDEV.C,\ + $(VAX_DIR)VAX_SYS.C,$(VAX_DIR)VAX_SYSDEV.C,\ + $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RQ.C,\ + $(PDP11_DIR)PDP11_TS.C,$(PDP11_DIR)PDP11_DZ.C,\ + $(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_TQ.C,\ + $(PDP11_DIR)PDP11_PT.C,$(PDP11_DIR)PDP11_XQ.C +VAX_OBJS = $(VAX_DIR)VAX_CPU1.OBJ,$(VAX_DIR)VAX_CPU.OBJ,\ + $(VAX_DIR)VAX_FPA.OBJ,$(VAX_DIR)VAX_IO.OBJ,\ + $(VAX_DIR)VAX_MMU.OBJ,$(VAX_DIR)VAX_STDDEV.OBJ,\ + $(VAX_DIR)VAX_SYS.OBJ,$(VAX_DIR)VAX_SYSDEV.OBJ,\ + $(VAX_DIR)PDP11_RL.OBJ,$(VAX_DIR)PDP11_RQ.OBJ,\ + $(VAX_DIR)PDP11_TS.OBJ,$(VAX_DIR)PDP11_DZ.OBJ,\ + $(VAX_DIR)PDP11_LP.OBJ,$(VAX_DIR)PDP11_TQ.OBJ,\ + $(VAX_DIR)PDP11_PT.OBJ,$(VAX_DIR)PDP11_XQ.OBJ +# +# If On Alpha, Define "USE_INT64" As We Have INT64. +# +.IFDEF __ALPHA__ +VAX_OPTIONS = /INCLUDE=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR))/DEFINE=("USE_INT64=1","VM_VAX=1") +.ELSE +# +# We Are On A VAX Platform So Don't Define "USE_INT64" As We Don't Have +# INT64. +# +VAX_OPTIONS = /INCLUDE=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR))/DEFINE=("VM_VAX=1") +.ENDIF + +# +# If On Alpha, Build Everything. +# +.IFDEF __ALPHA__ +ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \ + NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 VAX SDS +.ELSE +# +# Else We Are On VAX And Build Everything EXCEPT The PDP-10 Since VAX +# Dosen't Have INT64 +# +ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \ + NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 S3 VAX SDS +.ENDIF + +CLEAN : + $! + $! Clean out all targets and building Remnants + $! + $ IF (F$SEARCH("$(BIN_DIR)*.EXE;*").NES."") THEN - + DELETE/NOLOG/NOCONFIRM $(BIN_DIR)*.EXE;* + $ IF (F$SEARCH("$(LIB_DIR)*.EXE;*").NES."") THEN - + DELETE/NOLOG/NOCONFIRM $(LIB_DIR)*.OLB;* + $ IF (F$SEARCH("SYS$DISK:[...]*.OBJ;*").NES."") THEN - + DELETE/NOLOG/NOCONFIRM SYS$DISK:[...]*.OBJ;* + +# +# Build The Libraries. +# +$(LIB_DIR)SIMH-$(ARCH).OLB : $(SIMH_SOURCE) + $! + $! Building The $(SIMH_LIB) Library. + $! + $ $(CC)/OBJECT=$(SIMH_DIR) $(SIMH_SOURCE) + $ IF (F$SEARCH("$(SIMH_LIB)").EQS."") THEN - + LIBRARY/CREATE $(SIMH_LIB) + $ LIBRARY/REPLACE $(SIMH_LIB) $(SIMH_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +$(LIB_DIR)ALTAIR-$(ARCH).OLB : $(ALTAIR_SOURCE) + $! + $! Building The $(ALTAIR_LIB) Library. + $! + $ $(CC)$(ALTAIR_OPTIONS)/OBJECT=$(ALTAIR_DIR) - + $(ALTAIR_SOURCE) + $ IF (F$SEARCH("$(ALTAIR_LIB)").EQS."") THEN - + LIBRARY/CREATE $(ALTAIR_LIB) + $ LIBRARY/REPLACE $(ALTAIR_LIB) - + $(ALTAIR_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(ALTAIR_DIR)*.OBJ;* + +$(LIB_DIR)ALTAIRZ80-$(ARCH).OLB : $(ALTAIRZ80_SOURCE) + $! + $! Building The $(ALTAIRZ80_LIB) Library. + $! + $ $(CC)$(ALTAIRZ80_OPTIONS) - + /OBJECT=$(ALTAIRZ80_DIR) - + $(ALTAIRZ80_SOURCE) + $ IF (F$SEARCH("$(ALTAIRZ80_LIB)").EQS."") - + THEN LIBRARY/CREATE $(ALTAIRZ80_LIB) + $ LIBRARY/REPLACE $(ALTAIRZ80_LIB) - + $(ALTAIRZ80_OBJS) + $ DELETE/NOLOG/NOCONFIRM - + $(ALTAIRZ80_DIR)*.OBJ;* + +$(LIB_DIR)ECLIPSE-$(ARCH).OLB : $(ECLIPSE_SOURCE) + $! + $! Building The $(ECLIPSE_LIB) Library. + $! + $ $(CC)$(ECLIPSE_OPTIONS)/OBJECT=$(NOVA_DIR) - + $(ECLIPSE_SOURCE) + $ IF (F$SEARCH("$(ECLIPSE_LIB)").EQS."") THEN - + LIBRARY/CREATE $(ECLIPSE_LIB) + $ LIBRARY/REPLACE $(ECLIPSE_LIB) - + $(ECLIPSE_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(NOVA_DIR)*.OBJ;* + +$(LIB_DIR)GRI-$(ARCH).OLB : $(GRI_SOURCE) + $! + $! Building The $(GRI_LIB) Library. + $! + $ $(CC)$(GRI_OPTIONS)/OBJECT=$(GRI_DIR) - + $(GRI_SOURCE) + $ IF (F$SEARCH("$(GRI_LIB)").EQS."") THEN - + LIBRARY/CREATE $(GRI_LIB) + $ LIBRARY/REPLACE $(GRI_LIB) $(GRI_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(GRI_DIR)*.OBJ;* + +$(LIB_DIR)H316-$(ARCH).OLB : $(H316_SOURCE) + $! + $! Building The $(H316_LIB) Library. + $! + $ $(CC)$(H316_OPTIONS)/OBJECT=$(H316_DIR) - + $(H316_SOURCE) + $ IF (F$SEARCH("$(H316_LIB)").EQS."") THEN - + LIBRARY/CREATE $(H316_LIB) + $ LIBRARY/REPLACE $(H316_LIB) $(H316_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(H316_DIR)*.OBJ;* + +$(LIB_DIR)HP2100-$(ARCH).OLB : $(HP2100_SOURCE) + $! + $! Building The $(HP2100_LIB) Library. + $! + $ $(CC)$(HP2100_OPTIONS)/OBJECT=$(HP2100_DIR) - + $(HP2100_SOURCE) + $ IF (F$SEARCH("$(HP2100_LIB)").EQS."") THEN - + LIBRARY/CREATE $(HP2100_LIB) + $ LIBRARY/REPLACE $(HP2100_LIB) $(HP2100_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(HP2100_DIR)*.OBJ;* + +$(LIB_DIR)I1401-$(ARCH).OLB : $(I1401_SOURCE) + $! + $! Building The $(I1401_LIB) Library. + $! + $ $(CC)$(I1401_OPTIONS)/OBJECT=$(I1401_DIR) - + $(I1401_SOURCE) + $ IF (F$SEARCH("$(I1401_LIB)").EQS."") THEN - + LIBRARY/CREATE $(I1401_LIB) + $ LIBRARY/REPLACE $(I1401_LIB) $(I1401_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(I1401_DIR)*.OBJ;* + +$(LIB_DIR)I1620-$(ARCH).OLB : $(I1620_SOURCE) + $! + $! Building The $(I1620_LIB) Library. + $! + $ $(CC)$(I1620_OPTIONS)/OBJECT=$(I1620_DIR) - + $(I1620_SOURCE) + $ IF (F$SEARCH("$(I1620_LIB)").EQS."") THEN - + LIBRARY/CREATE $(I1620_LIB) + $ LIBRARY/REPLACE $(I1620_LIB) $(I1620_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(I1620_DIR)*.OBJ;* + +$(LIB_DIR)IBM1130-$(ARCH).OLB : $(IBM1130_SOURCE) + $! + $! Building The $(IBM1130_LIB) Library. + $! + $ $(CC)$(IBM1130_OPTIONS) - + /OBJECT=$(IBM1130_DIR) - + $(IBM1130_SOURCE) + $ IF (F$SEARCH("$(IBM1130_LIB)").EQS."") THEN - + LIBRARY/CREATE $(IBM1130_LIB) + $ LIBRARY/REPLACE $(IBM1130_LIB) $(IBM1130_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(IBM1130_DIR)*.OBJ;* + +$(LIB_DIR)ID16-$(ARCH).OLB : $(ID16_SOURCE) + $! + $! Building The $(ID16_LIB) Library. + $! + $ $(CC)$(ID16_OPTIONS)/OBJECT=$(ID16_DIR) - + $(ID16_SOURCE) + $ IF (F$SEARCH("$(ID16_LIB)").EQS."") THEN - + LIBRARY/CREATE $(ID16_LIB) + $ LIBRARY/REPLACE $(ID16_LIB) $(ID16_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(ID16_DIR)*.OBJ;* + +$(LIB_DIR)ID32-$(ARCH).OLB : $(ID32_SOURCE) + $! + $! Building The $(ID32_LIB) Library. + $! + $ $(CC)$(ID32_OPTIONS)/OBJECT=$(ID32_DIR) - + $(ID32_SOURCE) + $ IF (F$SEARCH("$(ID32_LIB)").EQS."") THEN - + LIBRARY/CREATE $(ID32_LIB) + $ LIBRARY/REPLACE $(ID32_LIB) $(ID32_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(ID32_DIR)*.OBJ;* + +$(LIB_DIR)NOVA-$(ARCH).OLB : $(NOVA_SOURCE) + $! + $! Building The $(NOVA_LIB) Library. + $! + $ $(CC)$(NOVA_OPTIONS)/OBJECT=$(NOVA_DIR) - + $(NOVA_SOURCE) + $ IF (F$SEARCH("$(NOVA_LIB)").EQS."") THEN - + LIBRARY/CREATE $(NOVA_LIB) + $ LIBRARY/REPLACE $(NOVA_LIB) $(NOVA_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(NOVA_DIR)*.OBJ;* + +$(LIB_DIR)PDP1-$(ARCH).OLB : $(PDP1_SOURCE) + $! + $! Building The $(PDP1_LIB) Library. + $! + $ $(CC)$(PDP1_OPTIONS)/OBJECT=$(PDP1_DIR) - + $(PDP1_SOURCE) + $ IF (F$SEARCH("$(PDP1_LIB)").EQS."") THEN - + LIBRARY/CREATE $(PDP1_LIB) + $ LIBRARY/REPLACE $(PDP1_LIB) $(PDP1_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(PDP1_DIR)*.OBJ;* + +$(LIB_DIR)PDP4-$(ARCH).OLB : $(PDP18B_SOURCE) + $! + $! Building The $(PDP4_LIB) Library. + $! + $ $(CC)$(PDP4_OPTIONS)/OBJECT=$(PDP18B_DIR) - + $(PDP18B_SOURCE) + $ IF (F$SEARCH("$(PDP4_LIB)").EQS."") THEN - + LIBRARY/CREATE $(PDP4_LIB) + $ LIBRARY/REPLACE $(PDP4_LIB) $(PDP18B_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(PDP18B_DIR)*.OBJ;* + +$(LIB_DIR)PDP7-$(ARCH).OLB : $(PDP18B_SOURCE) + $! + $! Building The $(PDP7_LIB) Library. + $! + $ $(CC)$(PDP7_OPTIONS)/OBJECT=$(PDP18B_DIR) - + $(PDP18B_SOURCE) + $ IF (F$SEARCH("$(PDP7_LIB)").EQS."") THEN - + LIBRARY/CREATE $(PDP7_LIB) + $ LIBRARY/REPLACE $(PDP7_LIB) $(PDP18B_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(PDP18B_DIR)*.OBJ;* + +$(LIB_DIR)PDP8-$(ARCH).OLB : $(PDP8_SOURCE) + $! + $! Building The $(PDP8_LIB) Library. + $! + $ $(CC)$(PDP8_OPTIONS)/OBJECT=$(PDP8_DIR) - + $(PDP8_SOURCE) + $ IF (F$SEARCH("$(PDP8_LIB)").EQS."") THEN - + LIBRARY/CREATE $(PDP8_LIB) + $ LIBRARY/REPLACE $(PDP8_LIB) $(PDP8_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(PDP8_DIR)*.OBJ;* + +$(LIB_DIR)PDP9-$(ARCH).OLB : $(PDP18B_SOURCE) + $! + $! Building The $(PDP9_LIB) Library. + $! + $ $(CC)$(PDP9_OPTIONS)/OBJECT=$(PDP18B_DIR) - + $(PDP18B_SOURCE) + $ IF (F$SEARCH("$(PDP9_LIB)").EQS."") THEN - + LIBRARY/CREATE $(PDP9_LIB) + $ LIBRARY/REPLACE $(PDP9_LIB) $(PDP18B_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(PDP18B_DIR)*.OBJ;* + +# +# If On Alpha, Build The PDP-10 Library. +# +.IFDEF __ALPHA__ +$(LIB_DIR)PDP10-$(ARCH).OLB : $(PDP10_SOURCE) + $! + $! Building The $(PDP10_LIB) Library. + $! + $ $(CC)$(PDP10_OPTIONS)/OBJECT=$(PDP10_DIR) - + $(PDP10_SOURCE) + $ IF (F$SEARCH("$(PDP10_LIB)").EQS."") THEN - + LIBRARY/CREATE $(PDP10_LIB) + $ LIBRARY/REPLACE $(PDP10_LIB) $(PDP10_OBJS) + DELETE/NOLOG/NOCONFIRM $(PDP10_DIR)*.OBJ;* +.ELSE +# +# We Are On VAX And Due To The Use of INT64 We Can't Build It. +# +$(LIB_DIR)PDP10-$(ARCH).OLB : + $! + $! Due To The Use Of INT64 We Can't Build The + $! $(LIB_DIR)PDP10-$(ARCH).OLB Library On VAX. + $! +.ENDIF + +$(LIB_DIR)PDP11-$(ARCH).OLB : $(PDP11_SOURCE) + $! + $! Building The $(PDP11_LIB) Library. + $! + $(CC)$(PDP11_OPTIONS)/OBJECT=$(PDP11_DIR) - + $(PDP11_SOURCE) + $ IF (F$SEARCH("$(PDP11_LIB)").EQS."") THEN - + LIBRARY/CREATE $(PDP11_LIB) + $ LIBRARY/REPLACE $(PDP11_LIB) $(PDP11_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(PDP11_DIR)*.OBJ;* + +$(LIB_DIR)PDP15-$(ARCH).OLB : $(PDP18B_SOURCE) + $! + $! Building The $(PDP15_LIB) Library. + $! + $ $(CC)$(PDP15_OPTIONS)/OBJECT=$(PDP18B_DIR) - + $(PDP18B_SOURCE) + $ IF (F$SEARCH("$(PDP15_LIB)").EQS."") THEN - + LIBRARY/CREATE $(PDP15_LIB) + $ LIBRARY/REPLACE $(PDP15_LIB) $(PDP18B_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(PDP18B_DIR)*.OBJ;* + +$(LIB_DIR)S3-$(ARCH).OLB : $(S3_SOURCE) + $! + $! Building The $(S3_LIB) Library. + $! + $ $(CC)$(S3_OPTIONS)/OBJECT=$(S3_DIR) $(S3_SOURCE) + $ IF (F$SEARCH("$(S3_LIB)").EQS."") THEN - + LIBRARY/CREATE $(S3_LIB) + $ LIBRARY/REPLACE $(S3_LIB) $(S3_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(S3_DIR)*.OBJ;* + +$(LIB_DIR)SDS-$(ARCH).OLB : $(SDS_SOURCE) + $! + $! Building The $(SDS_LIB) Library. + $! + $ $(CC)$(SDS_OPTIONS)/OBJECT=$(SDS_DIR) - + $(SDS_SOURCE) + $ IF (F$SEARCH("$(SDS_LIB)").EQS."") THEN - + LIBRARY/CREATE $(SDS_LIB) + $ LIBRARY/REPLACE $(SDS_LIB) $(SDS_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(SDS_DIR)*.OBJ;* + +# +# If On Alpha, Build The VAX Library. +# +$(LIB_DIR)VAX-$(ARCH).OLB : $(VAX_SOURCE) + $! + $! Building The $(VAX_LIB) Library. + $! + $ $(CC)$(VAX_OPTIONS)/OBJECT=$(VAX_DIR) - + $(VAX_SOURCE) + $ IF (F$SEARCH("$(VAX_LIB)").EQS."") THEN - + LIBRARY/CREATE $(VAX_LIB) + $ LIBRARY/REPLACE $(VAX_LIB) $(VAX_OBJS) + $ DELETE/NOLOG/NOCONFIRM $(VAX_DIR)*.OBJ;* + +# +# Individual Simulator Builds. +# +ALTAIR : $(SIMH_LIB) $(ALTAIR_LIB) + $! + $! Building The $(BIN_DIR)ALTAIR-$(ARCH).EXE Simulator. + $! + $ $(CC)$(ALTAIR_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ALTAIR-$(ARCH).EXE - + SCP.OBJ,$(ALTAIR_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +ALTAIRZ80 : $(SIMH_LIB) $(ALTAIRZ80_LIB) + $! + $! Building The $(BIN_DIR)ALTAIRZ80-$(ARCH).EXE Simulator. + $! + $ $(CC)$(ALTAIRZ80_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ALTAIRZ80-$(ARCH).EXE - + SCP.OBJ,$(ALTAIRZ80_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +ECLIPSE : $(SIMH_LIB) $(ECLIPSE_LIB) + $! + $! Building The $(BIN_DIR)ECLPISE-$(ARCH).EXE Simulator. + $! + $ $(CC)$(ECLIPSE_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ECLIPSE-$(ARCH).EXE - + SCP.OBJ,$(ECLIPSE_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +GRI : $(SIMH_LIB) $(GRI_LIB) + $! + $! Building The $(BIN_DIR)GRI-$(ARCH).EXE Simulator. + $! + $ $(CC)$(GRI_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)GRI-$(ARCH).EXE - + SCP.OBJ,$(GRI_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +H316 : $(SIMH_LIB) $(H316_LIB) + $! + $! Building The $(BIN_DIR)H316-$(ARCH).EXE Simulator. + $! + $ $(CC)$(H316_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)H316-$(ARCH).EXE - + SCP.OBJ,$(H316_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +HP2100 : $(SIMH_LIB) $(HP2100_LIB) + $! + $! Building The $(BIN_DIR)HP2100-$(ARCH).EXE Simulator. + $! + $ $(CC)$(HP2100_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)HP2100-$(ARCH).EXE - + SCP.OBJ,$(HP2100_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +I1401 : $(SIMH_LIB) $(I1401_LIB) + $! + $! Building The $(BIN_DIR)I1401-$(ARCH).EXE Simulator. + $! + $ $(CC)$(I1401_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)I1401-$(ARCH).EXE - + SCP.OBJ,$(I1401_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +I1620 : $(SIMH_LIB) $(I1620_LIB) + $! + $! Building The $(BIN_DIR)I1620-$(ARCH).EXE Simulator. + $! + $ $(CC)$(I1620_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)I1620-$(ARCH).EXE - + SCP.OBJ,$(I1620_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +IBM1130 : $(SIMH_LIB) $(IBM1130_LIB) + $! + $! Building The $(BIN_DIR)IBM1130-$(ARCH).EXE Simulator. + $! + $ $(CC)$(IBM1130_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)IBM1130-$(ARCH).EXE - + SCP.OBJ,$(IBM1130_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +ID16 : $(SIMH_LIB) $(ID16_LIB) + $! + $! Building The $(BIN_DIR)ID16-$(ARCH).EXE Simulator. + $! + $ $(CC)$(ID16_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ID16-$(ARCH).EXE - + SCP.OBJ,$(ID16_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +ID32 : $(SIMH_LIB) $(ID32_LIB) + $! + $! Building The $(BIN_DIR)ID32-$(ARCH).EXE Simulator. + $! + $ $(CC)$(ID32_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ID32-$(ARCH).EXE - + SCP.OBJ,$(ID32_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +NOVA : $(SIMH_LIB) $(NOVA_LIB) + $! + $! Building The $(BIN_DIR)NOVA-$(ARCH).EXE Simulator. + $! + $ $(CC)$(NOVA_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)NOVA-$(ARCH).EXE - + SCP.OBJ,$(NOVA_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +PDP1 : $(SIMH_LIB) $(PDP1_LIB) + $! + $! Building The $(BIN_DIR)PDP1-$(ARCH).EXE Simulator. + $! + $ $(CC)$(PDP1_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP1-$(ARCH).EXE - + SCP.OBJ,$(PDP1_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +PDP4 : $(SIMH_LIB) $(PDP4_LIB) + $! + $! Building The $(BIN_DIR)PDP4-$(ARCH).EXE Simulator. + $! + $ $(CC)$(PDP4_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP4-$(ARCH).EXE - + SCP.OBJ,$(PDP4_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +PDP7 : $(SIMH_LIB) $(PDP7_LIB) + $! + $! Building The $(BIN_DIR)PDP7-$(ARCH).EXE Simulator. + $! + $ $(CC)$(PDP7_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP7-$(ARCH).EXE - + SCP.OBJ,$(PDP7_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +PDP8 : $(SIMH_LIB) $(PDP8_LIB) + $! + $! Building The $(BIN_DIR)PDP8-$(ARCH).EXE Simulator. + $! + $ $(CC)$(PDP8_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP8-$(ARCH).EXE - + SCP.OBJ,$(PDP8_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +PDP9 : $(SIMH_LIB) $(PDP9_LIB) + $! + $! Building The $(BIN_DIR)PDP9-$(ARCH).EXE Simulator. + $! + $ $(CC)$(PDP9_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP9-$(ARCH).EXE - + SCP.OBJ,$(PDP9_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +# +# If On Alpha, Build The PDP-10 Simulator. +# +.IFDEF __ALPHA__ +PDP10 : $(SIMH_LIB) $(PDP10_LIB) + $! + $! Building The $(BIN_DIR)PDP10-$(ARCH).EXE Simulator. + $! + $ $(CC)$(PDP10_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP10-$(ARCH).EXE - + SCP.OBJ,$(PDP10_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* +.ELSE +# +# Else We Are On VAX And Tell The User We Can't Build On VAX +# Due To The Use Of INT64. +# +PDP10 : + $! + $! Sorry, Can't Build $(BIN_DIR)PDP10-$(ARCH).EXE Simulator + $! Because It Requires The Use Of INT64. + $! +.ENDIF + +PDP11 : $(SIMH_LIB) $(PDP11_LIB) + $! + $! Building The $(BIN_DIR)PDP11-$(ARCH).EXE Simulator. + $! + $ $(CC)$(PDP11_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP11-$(ARCH).EXE - + SCP.OBJ,$(PDP11_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +PDP15 : $(SIMH_LIB) $(PDP15_LIB) + $! + $! Building The $(BIN_DIR)PDP15-$(ARCH).EXE Simulator. + $! + $ $(CC)$(PDP15_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP15-$(ARCH).EXE - + SCP.OBJ,$(PDP15_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +S3 : $(SIMH_LIB) $(S3_LIB) + $! + $! Building The $(BIN_DIR)S3-$(ARCH).EXE Simulator. + $! + $ $(CC)$(S3_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)S3-$(ARCH).EXE - + SCP.OBJ,$(S3_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +SDS : $(SIMH_LIB) $(SDS_LIB) + $! + $! Building The $(BIN_DIR)SDS-$(ARCH).EXE Simulator. + $! + $ $(CC)$(SDS_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)SDS-$(ARCH).EXE - + SCP.OBJ,$(SDS_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* + +VAX : $(SIMH_LIB) $(VAX_LIB) + $! + $! Building The $(BIN_DIR)VAX-$(ARCH).EXE Simulator. + $! + $ $(CC)$(VAX_OPTIONS)/OBJECT=$(SIMH_DIR) SCP.C + $ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)VAX-$(ARCH).EXE - + SCP.OBJ,$(VAX_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY + $ DELETE/NOLOG/NOCONFIRM $(SIMH_DIR)*.OBJ;* diff --git a/makefile b/makefile index 7ca49524..22d1901c 100644 --- a/makefile +++ b/makefile @@ -78,7 +78,7 @@ PDP11 = ${PDP11D}pdp11_fp.c ${PDP11D}pdp11_cpu.c ${PDP11D}pdp11_dz.c \ ${PDP11D}pdp11_rq.c ${PDP11D}pdp11_tq.c ${PDP11D}pdp11_pclk.c \ ${PDP11D}pdp11_ry.c ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_hk.c \ ${PDP11D}pdp11_xq.c ${PDP11D}pdp11_xu.c -PDP11_OPT = -I ${PDP11D} ${NETWORK_OPT} +PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT} @@ -89,17 +89,17 @@ VAX = ${VAXD}vax_cpu1.c ${VAXD}vax_cpu.c ${VAXD}vax_fpa.c ${VAXD}vax_io.c \ ${PDP11D}pdp11_rl.c ${PDP11D}pdp11_rq.c ${PDP11D}pdp11_ts.c \ ${PDP11D}pdp11_dz.c ${PDP11D}pdp11_lp.c ${PDP11D}pdp11_tq.c \ ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_xq.c -VAX_OPT = -I ${VAXD} -I ${PDP11D} -DUSE_INT64 ${NETWORK_OPT} +VAX_OPT = -DVM_VAX -DUSE_INT64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT} PDP10D = PDP10/ -PDP10 = ${PDP10D}pdp10_fe.c ${PDP10D}pdp10_dz.c ${PDP10D}pdp10_cpu.c \ +PDP10 = ${PDP10D}pdp10_fe.c ${PDP11D}pdp11_dz.c ${PDP10D}pdp10_cpu.c \ ${PDP10D}pdp10_ksio.c ${PDP10D}pdp10_lp20.c ${PDP10D}pdp10_mdfp.c \ ${PDP10D}pdp10_pag.c ${PDP10D}pdp10_rp.c ${PDP10D}pdp10_sys.c \ ${PDP10D}pdp10_tim.c ${PDP10D}pdp10_tu.c ${PDP10D}pdp10_xtnd.c \ - ${PDP10D}pdp10_pt.c ${PDP11D}pdp11_ry.c ${PDP11D}pdp11_xu.c -PDP10_OPT = -DUSE_INT64 -I ${PDP10D} -I ${PDP11D} -I ${VAXD} + ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_ry.c ${PDP11D}pdp11_xu.c +PDP10_OPT = -DVM_PDP10 -DUSE_INT64 -I ${PDP10D} -I ${PDP11D} -I ${VAXD} diff --git a/scp.c b/scp.c index ec455222..e2db00d6 100644 --- a/scp.c +++ b/scp.c @@ -23,6 +23,11 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 15-Jun-03 RMS Added register flag REG_VMIO + 25-Apr-03 RMS Added extended address support (V3.0) + Fixed bug in SAVE (found by Peter Schorn) + Added u5, u6 fields + Added logical name support 03-Mar-03 RMS Added sim_fsize 27-Feb-03 RMS Fixed bug in multiword deposits to files 08-Feb-03 RMS Changed sim_os_sleep to void, match_ext to char* @@ -151,24 +156,24 @@ (size_map[((rp)->width + (rp)->offset + CHAR_BIT - 1) / CHAR_BIT]) #if defined (t_int64) #define SZ_LOAD(sz,v,mb,j) \ - if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + j); \ - else if (sz == sizeof (uint16)) v = *(((uint16 *) mb) + j); \ - else if (sz == sizeof (uint32)) v = *(((uint32 *) mb) + j); \ - else v = *(((t_uint64 *) mb) + j); + if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + ((uint32) j)); \ + else if (sz == sizeof (uint16)) v = *(((uint16 *) mb) + ((uint32) j)); \ + else if (sz == sizeof (uint32)) v = *(((uint32 *) mb) + ((uint32) j)); \ + else v = *(((t_uint64 *) mb) + ((uint32) j)); #define SZ_STORE(sz,v,mb,j) \ if (sz == sizeof (uint8)) *(((uint8 *) mb) + j) = (uint8) v; \ - else if (sz == sizeof (uint16)) *(((uint16 *) mb) + j) = (uint16) v; \ - else if (sz == sizeof (uint32)) *(((uint32 *) mb) + j) = (uint32) v; \ - else *(((t_uint64 *) mb) + j) = v; + else if (sz == sizeof (uint16)) *(((uint16 *) mb) + ((uint32) j)) = (uint16) v; \ + else if (sz == sizeof (uint32)) *(((uint32 *) mb) + ((uint32) j)) = (uint32) v; \ + else *(((t_uint64 *) mb) + ((uint32) j)) = v; #else #define SZ_LOAD(sz,v,mb,j) \ - if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + j); \ - else if (sz == sizeof (uint16)) v = *(((uint16 *) mb) + j); \ - else v = *(((uint32 *) mb) + j); + if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + ((uint32) j)); \ + else if (sz == sizeof (uint16)) v = *(((uint16 *) mb) + ((uint32) j)); \ + else v = *(((uint32 *) mb) + ((uint32) j)); #define SZ_STORE(sz,v,mb,j) \ - if (sz == sizeof (uint8)) *(((uint8 *) mb) + j) = (uint8) v; \ - else if (sz == sizeof (uint16)) *(((uint16 *) mb) + j) = (uint16) v; \ - else *(((uint32 *) mb) + j) = v; + if (sz == sizeof (uint8)) *(((uint8 *) mb) + ((uint32) j)) = (uint8) v; \ + else if (sz == sizeof (uint16)) *(((uint16 *) mb) + ((uint32) j)) = (uint16) v; \ + else *(((uint32 *) mb) + ((uint32) j)) = v; #endif #define GET_SWITCHES(cp) \ if ((cp = get_sim_sw (cp)) == NULL) return SCPE_INVSW @@ -178,18 +183,9 @@ else if (sim_switches & SWMASK ('H')) val = 16; \ else val = dft; -struct brktab { - t_addr addr; - int32 typ; - int32 cnt; - char *act; -}; - -typedef struct brktab BRKTAB; - #if defined(VMS) #define FOPEN(file_spec, mode) fopen (file_spec, mode, "ALQ=32", "DEQ=4096", \ - "MBF=6", "MBC=128", "FOP=cbt,tef,sqo", "ROP=rah,wbh") + "MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm") #else #define FOPEN(file_spec, mode) fopen (file_spec, mode) #endif @@ -228,15 +224,29 @@ extern uint32 sim_os_msec (void); /* Prototypes */ -t_stat sim_brk_init (void); -t_stat sim_brk_set (t_addr loc, int32 sw, int32 ncnt, char *act); -t_stat sim_brk_clr (t_addr loc, int32 sw); -t_stat sim_brk_clrall (int32 sw); -t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw); -t_stat sim_brk_showall (FILE *st, int32 sw); -char *sim_brk_getact (char *buf, int32 size); -void sim_brk_clract (void); -void sim_brk_npc (void); +/* Command processors */ + +t_stat reset_cmd (int32 flag, char *ptr); +t_stat exdep_cmd (int32 flag, char *ptr); +t_stat eval_cmd (int32 flag, char *ptr); +t_stat load_cmd (int32 flag, char *ptr); +t_stat run_cmd (int32 flag, char *ptr); +t_stat attach_cmd (int32 flag, char *ptr); +t_stat detach_cmd (int32 flag, char *ptr); +t_stat assign_cmd (int32 flag, char *ptr); +t_stat deassign_cmd (int32 flag, char *ptr); +t_stat save_cmd (int32 flag, char *ptr); +t_stat restore_cmd (int32 flag, char *ptr); +t_stat exit_cmd (int32 flag, char *ptr); +t_stat set_cmd (int32 flag, char *ptr); +t_stat show_cmd (int32 flag, char *ptr); +t_stat brk_cmd (int32 flag, char *ptr); +t_stat do_cmd (int32 flag, char *ptr); +t_stat help_cmd (int32 flag, char *ptr); +t_stat spawn_cmd (int32 flag, char *ptr); + +/* Set and show command processors */ + t_stat set_telnet (int32 flg, char *cptr); t_stat set_notelnet (int32 flg, char *cptr); t_stat set_logon (int32 flag, char *cptr); @@ -249,6 +259,7 @@ t_stat show_config (FILE *st, int32 flag, char *cptr); t_stat show_queue (FILE *st, int32 flag, char *cptr); t_stat show_time (FILE *st, int32 flag, char *cptr); t_stat show_mod_names (FILE *st, int32 flag, char *cptr); +t_stat show_log_names (FILE *st, int32 flag, char *cptr); t_stat show_log (FILE *st, int32 flag, char *cptr); t_stat show_telnet (FILE *st, int32 flag, char *cptr); t_stat show_version (FILE *st, int32 flag, char *cptr); @@ -258,58 +269,63 @@ t_stat show_unit (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag); t_stat show_all_mods (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flg); t_stat show_one_mod (FILE *st, DEVICE *dptr, UNIT *uptr, MTAB *mptr, int32 flag); t_stat sim_check_console (int32 sec); +t_stat sim_save (FILE *sfile); +t_stat sim_rest (FILE *rfile); + +/* Breakpoint package */ + +t_stat sim_brk_init (void); +t_stat sim_brk_set (t_addr loc, int32 sw, int32 ncnt, char *act); +t_stat sim_brk_clr (t_addr loc, int32 sw); +t_stat sim_brk_clrall (int32 sw); +t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw); +t_stat sim_brk_showall (FILE *st, int32 sw); +char *sim_brk_getact (char *buf, int32 size); +void sim_brk_clract (void); +void sim_brk_npc (void); +BRKTAB *sim_brk_new (t_addr loc); + +/* Commands support routines */ + +SCHTAB *get_search (char *cptr, DEVICE *dptr, SCHTAB *schptr); +int32 test_search (t_value val, SCHTAB *schptr); char *get_glyph_gen (char *iptr, char *optr, char mchar, t_bool uc); int32 get_switches (char *cptr); char *get_sim_sw (char *cptr); -t_value get_rval (REG *rptr, int32 idx); -void put_rval (REG *rptr, int32 idx, t_value val); t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr); -t_value strtotv (char *inptr, char **endptr, int32 radix); +t_value get_rval (REG *rptr, uint32 idx); +void put_rval (REG *rptr, uint32 idx, t_value val); +t_value strtotv (char *inptr, char **endptr, uint32 radix); void fprint_help (FILE *st); void fprint_stopped (FILE *st, t_stat r); void fprint_capac (FILE *st, DEVICE *dptr, UNIT *uptr); char *read_line (char *ptr, int32 size, FILE *stream); CTAB *find_ctab (CTAB *tab, char *gbuf); +C1TAB *find_c1tab (C1TAB *tab, char *gbuf); CTAB *find_cmd (char *gbuf); DEVICE *find_dev (char *ptr); DEVICE *find_unit (char *ptr, UNIT **uptr); REG *find_reg_glob (char *ptr, char **optr, DEVICE **gdptr); + +/* Forward references within commands */ + t_bool restore_skip_val (FILE *rfile); t_bool qdisable (DEVICE *dptr); t_stat attach_err (UNIT *uptr, t_stat stat); t_stat detach_all (int32 start_device, t_bool shutdown); -t_stat exdep_reg_loop (FILE *ofile, SCHTAB *schptr, int flag, char *cptr, - REG *lowr, REG *highr, t_addr lows, t_addr highs); -t_stat exdep_addr_loop (FILE *ofile, SCHTAB *schptr, int flag, char *cptr, +t_stat assign_device (DEVICE *dptr, char *cptr); +t_stat deassign_device (DEVICE *dptr); +t_stat exdep_reg_loop (FILE *ofile, SCHTAB *schptr, int32 flag, char *cptr, + REG *lowr, REG *highr, uint32 lows, uint32 highs); +t_stat ex_reg (FILE *ofile, t_value val, int32 flag, REG *rptr, uint32 idx); +t_stat dep_reg (int32 flag, char *cptr, REG *rptr, uint32 idx); +t_stat exdep_addr_loop (FILE *ofile, SCHTAB *schptr, int32 flag, char *cptr, t_addr low, t_addr high, DEVICE *dptr, UNIT *uptr); -t_stat ex_reg (FILE *ofile, t_value val, int32 flag, REG *rptr, t_addr idx); -t_stat dep_reg (int32 flag, char *cptr, REG *rptr, t_addr idx); t_stat ex_addr (FILE *ofile, int32 flag, t_addr addr, DEVICE *dptr, UNIT *uptr); t_stat dep_addr (int32 flag, char *cptr, t_addr addr, DEVICE *dptr, UNIT *uptr, int32 dfltinc); -SCHTAB *get_search (char *cptr, DEVICE *dptr, SCHTAB *schptr); -int32 test_search (t_value val, SCHTAB *schptr); t_stat step_svc (UNIT *ptr); void sub_args (char *instr, char *tmpbuf, int32 maxstr, int32 nargs, char *do_arg[]); -BRKTAB *sim_brk_fnd (t_addr loc); -BRKTAB *sim_brk_new (t_addr loc); - -t_stat reset_cmd (int32 flag, char *ptr); -t_stat exdep_cmd (int32 flag, char *ptr); -t_stat eval_cmd (int32 flag, char *ptr); -t_stat load_cmd (int32 flag, char *ptr); -t_stat run_cmd (int32 flag, char *ptr); -t_stat attach_cmd (int32 flag, char *ptr); -t_stat detach_cmd (int32 flag, char *ptr); -t_stat save_cmd (int32 flag, char *ptr); -t_stat restore_cmd (int32 flag, char *ptr); -t_stat exit_cmd (int32 flag, char *ptr); -t_stat set_cmd (int32 flag, char *ptr); -t_stat show_cmd (int32 flag, char *ptr); -t_stat brk_cmd (int32 flag, char *ptr); -t_stat do_cmd (int32 flag, char *ptr); -t_stat help_cmd (int32 flag, char *ptr); -t_stat spawn_cmd (int32 flag, char *ptr); /* Global data */ @@ -343,9 +359,9 @@ UNIT step_unit = { UDATA (&step_svc, 0, 0) }; /* Tables and strings */ -const char save_vercur[] = "V2.10"; +const char save_vercur[] = "V3.0"; +const char save_ver210[] = "V2.10"; const char save_ver26[] = "V2.6"; -const char save_ver25[] = "V2.5"; const char *scp_error_messages[] = { "Address space exceeded", "Unit not attached", @@ -451,6 +467,10 @@ static CTAB cmd_table[] = { "at{tach} attach file to simulated unit\n" }, { "DETACH", &detach_cmd, 0, "det{ach} detach file from simulated unit\n" }, + { "ASSIGN", &assign_cmd, 0, + "as{sign} assign logical name for device\n" }, + { "DEASSIGN", &deassign_cmd, 0, + "dea{ssign} deassign logical name for device\n" }, { "SAVE", &save_cmd, 0, "sa{ve} save simulator to file\n" }, { "RESTORE", &restore_cmd, 0, @@ -481,7 +501,8 @@ static CTAB cmd_table[] = { "sh{ow} c{onfiguration} show configuration\n" "sh{ow} d{evices} show devices\n" "sh{ow} l{og} show log\n" - "sh{ow} m{odifiers} show modifiers\n" + "sh{ow} m{odifiers} show modifiers\n" + "sh{ow} n{ames} show logical names\n" "sh{ow} q{ueue} show event queue\n" "sh{ow} te{lnet} show console Telnet status\n" "sh{ow} ti{me} show simulated time\n" @@ -661,6 +682,8 @@ if ((cptr == NULL) || (strlen (cptr) == 0)) cptr = getenv("ComSpec"); #if defined (VMS) if ((cptr == NULL) || (strlen (cptr) == 0)) cptr = "SPAWN/INPUT=SYS$COMMAND:"; #endif +fflush(stdout); /* flush stdout */ +if (sim_log) fflush (sim_log); /* flush log if enabled */ system (cptr); #if defined (VMS) printf ("\n"); @@ -668,11 +691,10 @@ printf ("\n"); return SCPE_OK; } - /* Do command */ -t_stat do_cmd (int flag, char *fcptr) +t_stat do_cmd (int32 flag, char *fcptr) { char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], *c, quote, *do_arg[10]; FILE *fpin; @@ -694,7 +716,7 @@ for (nargs = 0; nargs < 10; ) { /* extract arguments */ if (*c) *c++ = 0; /* term at quote/spc */ } /* end for */ if (nargs <= 0) return SCPE_2FARG; /* need at least 1 */ -if ((fpin = FOPEN (do_arg[0], "r")) == NULL) /* cmd file failed to open? */ +if ((fpin = fopen (do_arg[0], "r")) == NULL) /* cmd file failed to open? */ return SCPE_OPENERR; do { cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */ @@ -705,7 +727,7 @@ do { cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */ if (sim_log) fprintf (sim_log, "do> %s\n", cptr); cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */ sim_switches = 0; /* init switches */ - if (strcmp (gbuf, "do") == 0) { /* don't recurse */ + if (strcmp (gbuf, "DO") == 0) { /* don't recurse */ fclose (fpin); return SCPE_NEST; } if (cmdp = find_cmd (gbuf)) /* lookup command */ @@ -759,7 +781,8 @@ char gbuf[CBUFSIZE], *cvptr, *svptr; DEVICE *dptr; UNIT *uptr; MTAB *mptr; -CTAB *ctbr, *glbr; +CTAB *gcmdp; +C1TAB *ctbr, *glbr; static CTAB set_glob_tab[] = { { "TELNET", &set_telnet, 0 }, { "NOTELNET", &set_notelnet, 0 }, @@ -767,14 +790,14 @@ static CTAB set_glob_tab[] = { { "NOLOG", &set_logoff, 0 }, { "BREAK", &brk_cmd, SSH_ST }, { NULL, NULL, 0 } }; -static CTAB set_dev_tab[] = { +static C1TAB set_dev_tab[] = { { "OCTAL", &set_radix, 8 }, { "DECIMAL", &set_radix, 10 }, { "HEX", &set_radix, 16 }, { "ENABLED", &set_devenbdis, 1 }, { "DISABLED", &set_devenbdis, 0 }, { NULL, NULL, 0 } }; -static CTAB set_unit_tab[] = { +static C1TAB set_unit_tab[] = { { "ONLINE", &set_onoff, 1 }, { "OFFLINE", &set_onoff, 0 }, { NULL, NULL, 0 } }; @@ -791,8 +814,8 @@ else if (dptr = find_unit (gbuf, &uptr)) { /* unit match? */ if (uptr == NULL) return SCPE_NXUN; /* invalid unit */ ctbr = set_unit_tab; /* global table */ lvl = MTAB_VUN; } /* unit match */ -else if (glbr = find_ctab (set_glob_tab, gbuf)) /* global? */ - return glbr->action (glbr->arg, cptr); /* do the rest */ +else if (gcmdp = find_ctab (set_glob_tab, gbuf)) /* global? */ + return gcmdp->action (gcmdp->arg, cptr); /* do the rest */ else return SCPE_NXDEV; /* no match */ if (*cptr == 0) return SCPE_2FARG; /* must be more */ @@ -833,7 +856,7 @@ while (*cptr != 0) { /* do all mods */ } /* end if match */ } /* end for */ if (!mptr || (mptr->mask == 0)) { /* no match? */ - if (glbr = find_ctab (ctbr, gbuf)) { /* global match? */ + if (glbr = find_c1tab (ctbr, gbuf)) { /* global match? */ r = glbr->action (dptr, uptr, glbr->arg); /* do global */ if (r != SCPE_OK) return r; } else if (!dptr->modifiers) return SCPE_NOPARAM; /* no modifiers? */ @@ -842,7 +865,7 @@ while (*cptr != 0) { /* do all mods */ return SCPE_OK; /* done all */ } -/* Match CTAB name */ +/* Match CTAB/CTAB1 name */ CTAB *find_ctab (CTAB *tab, char *gbuf) { @@ -851,6 +874,13 @@ for (; tab->name != NULL; tab++) { return NULL; } +C1TAB *find_c1tab (C1TAB *tab, char *gbuf) +{ +for (; tab->name != NULL; tab++) { + if (MATCH_CMD (gbuf, tab->name) == 0) return tab; } +return NULL; +} + /* Log on routine */ t_stat set_logon (int32 flag, char *cptr) @@ -894,7 +924,7 @@ return SCPE_OK; t_stat set_devenbdis (DEVICE *dptr, UNIT *uptr, int32 flag) { UNIT *up; -int32 i; +uint32 i; if ((dptr->flags & DEV_DISABLE) == 0) return SCPE_NOFNC;/* allowed? */ if (flag) { /* enable? */ @@ -935,12 +965,13 @@ DEVICE *dptr; UNIT *uptr; MTAB *mptr; -static CTAB show_table[] = { +static SHTAB show_table[] = { { "CONFIGURATION", &show_config, 0 }, { "DEVICES", &show_config, 1 }, { "QUEUE", &show_queue, 0 }, { "TIME", &show_time, 0 }, { "MODIFIERS", &show_mod_names, 0 }, + { "NAMES", &show_log_names, 0 }, { "VERSION", &show_version, 0 }, { "LOG", &show_log, 0 }, { "TELNET", &show_telnet, 0 }, @@ -1000,15 +1031,15 @@ return SCPE_OK; t_stat show_device (FILE *st, DEVICE *dptr, int32 flag) { -int32 j, ucnt; +uint32 j, ucnt; UNIT *uptr; -fprintf (st, "%s", dptr->name); /* print dev name */ +fprintf (st, "%s", sim_dname (dptr)); /* print dev name */ if (qdisable (dptr)) { /* disabled? */ fprintf (st, ", disabled\n"); return SCPE_OK; } for (j = ucnt = 0; j < dptr->numunits; j++) { /* count units */ - uptr = (dptr->units) + j; + uptr = dptr->units + j; if (!(uptr->flags & UNIT_DIS)) ucnt++; } show_all_mods (st, dptr, dptr->units, MTAB_VDV); /* show dev mods */ if (dptr->numunits == 0) fprintf (st, "\n"); @@ -1017,7 +1048,7 @@ else { if (ucnt == 0) fprintf (st, ", all units disabled\n"); else if (flag) fprintf (st, "\n"); } if (flag) return SCPE_OK; /* dev only? */ for (j = 0; j < dptr->numunits; j++) { /* loop thru units */ - uptr = (dptr->units) + j; + uptr = dptr->units + j; if ((uptr->flags & UNIT_DIS) == 0) show_unit (st, dptr, uptr, ucnt); } return SCPE_OK; @@ -1027,8 +1058,8 @@ t_stat show_unit (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag) { int32 u = uptr - dptr->units; -if (flag > 1) fprintf (st, " %s%d", dptr->name, u); -else if (flag < 0) fprintf (st, "%s%d", dptr->name, u); +if (flag > 1) fprintf (st, " %s%d", sim_dname (dptr), u); +else if (flag < 0) fprintf (st, "%s%d", sim_dname (dptr), u); if (uptr->flags & UNIT_FIX) { fprintf (st, ", "); fprint_capac (st, dptr, uptr); } @@ -1045,11 +1076,21 @@ return SCPE_OK; void fprint_capac (FILE *st, DEVICE *dptr, UNIT *uptr) { t_addr kval = (uptr->flags & UNIT_BINK)? 1024: 1000; +t_addr mval = kval * kval; +t_addr psize = uptr->capac; +char scale, width; -if (uptr->capac < kval) fprintf (st, "%d%s", uptr->capac, - ((dptr->dwidth / dptr->aincr) > 8)? "W": "B"); -else fprintf (st, "%dK%s", uptr->capac / kval, - ((dptr->dwidth / dptr->aincr) > 8)? "W": "B"); +if ((dptr->dwidth / dptr->aincr) > 8) width = 'W'; +else width = 'B'; +if (uptr->capac < (kval * 10)) scale = 0; +else if (uptr->capac < (mval * 10)) { + scale = 'K'; + psize = psize / kval; } +else { scale = 'M'; + psize = psize / mval; } +fprint_val (st, (t_value) psize, 10, T_ADDR_W, PV_LEFT); +if (scale) fputc (scale, st); +fputc (width, st); return; } @@ -1076,6 +1117,17 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) return SCPE_OK; } +t_stat show_log_names (FILE *st, int32 flag, char *cptr) +{ +int32 i; +DEVICE *dptr; + +for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { + if (dptr->lname) fprintf (st, "%s -> %s\n", + dptr->lname, dptr->name); } +return SCPE_OK; +} + t_stat show_queue (FILE *st, int32 flag, char *cptr) { DEVICE *dptr; @@ -1093,7 +1145,7 @@ accum = 0; for (uptr = sim_clock_queue; uptr != NULL; uptr = uptr->next) { if (uptr == &step_unit) fprintf (st, " Step timer"); else if ((dptr = find_dev_from_unit (uptr)) != NULL) { - fprintf (st, " %s", dptr->name); + fprintf (st, " %s", sim_dname (dptr)); if (dptr->numunits > 1) fprintf (st, " unit %d", uptr - dptr->units); } else fprintf (st, " Unknown"); @@ -1145,10 +1197,10 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { if (mptr->mstring) { if (strcmp (mptr->mstring, "ENABLED") == 0) enb = 1; if (any++) fprintf (st, ", %s", mptr->mstring); - else fprintf (st, "%s\t%s", dptr->name, mptr->mstring); } } } + else fprintf (st, "%s\t%s", sim_dname (dptr), mptr->mstring); } } } if (!enb && (dptr->flags & DEV_DISABLE)) { if (any++) fprintf (st, ", ENABLED, DISABLED"); - else fprintf (st, "%s\tENABLED, DISABLED", dptr->name); } + else fprintf (st, "%s\tENABLED, DISABLED", sim_dname (dptr)); } if (any) fprintf (st, "\n"); } return SCPE_OK; } @@ -1212,9 +1264,8 @@ while (*cptr) { tptr = get_range (gbuf, &lo, &hi, dptr->aradix, max, 0); if (tptr == NULL) return SCPE_ARG; if (*tptr == '[') { - errno = 0; - cnt = strtoul (tptr + 1, &t1ptr, 10); - if (errno || (tptr == t1ptr) || (*t1ptr != ']') || + cnt = (int32) strtotv (tptr + 1, &t1ptr, 10); + if ((tptr == t1ptr) || (*t1ptr != ']') || (flg != SSH_ST)) return SCPE_ARG; tptr = t1ptr + 1; } else cnt = 0; @@ -1267,10 +1318,10 @@ else return SCPE_OK; status = error status */ -t_stat reset_all (int32 start) +t_stat reset_all (uint32 start) { DEVICE *dptr; -int32 i; +uint32 i; t_stat reason; if (start < 0) return SCPE_IERR; @@ -1350,7 +1401,7 @@ if (sim_switches & SWMASK ('R')) { /* read only? */ if (uptr->fileref == NULL) /* open fail? */ return attach_err (uptr, SCPE_OPENERR); /* yes, error */ uptr->flags = uptr->flags | UNIT_RO; /* set rd only */ - if (!sim_quiet) printf ("%s: unit is read only\n", dptr->name); } + if (!sim_quiet) printf ("%s: unit is read only\n", sim_dname (dptr)); } else { /* normal */ uptr->fileref = FOPEN (cptr, "rb+"); /* open r/w */ if (uptr->fileref == NULL) { /* open fail? */ @@ -1361,23 +1412,23 @@ else { /* normal */ if (uptr->fileref == NULL) /* open fail? */ return attach_err (uptr, SCPE_OPENERR); /* yes, error */ uptr->flags = uptr->flags | UNIT_RO; /* set rd only */ - if (!sim_quiet) printf ("%s: unit is read only\n", dptr->name); } + if (!sim_quiet) printf ("%s: unit is read only\n", sim_dname (dptr)); } else { /* doesn't exist */ if (sim_switches & SWMASK ('E')) /* must exist? */ return attach_err (uptr, SCPE_OPENERR); /* yes, error */ uptr->fileref = FOPEN (cptr, "wb+"); /* open new file */ if (uptr->fileref == NULL) /* open fail? */ return attach_err (uptr, SCPE_OPENERR); /* yes, error */ - if (!sim_quiet) printf ("%s: creating new file\n", dptr->name); } + if (!sim_quiet) printf ("%s: creating new file\n", sim_dname (dptr)); } } /* end if null */ } /* end else */ if (uptr->flags & UNIT_BUFABLE) { /* buffer? */ - int32 cap = uptr->capac / dptr->aincr; /* effective size */ + uint32 cap = ((uint32) uptr->capac) / dptr->aincr; /* effective size */ if (uptr->flags & UNIT_MUSTBUF) /* dyn alloc? */ uptr->filebuf = calloc (cap, SZ_D (dptr)); /* allocate */ if (uptr->filebuf == NULL) /* no buffer? */ return attach_err (uptr, SCPE_MEM); /* error */ - if (!sim_quiet) printf ("%s: buffering file in memory\n", dptr->name); + if (!sim_quiet) printf ("%s: buffering file in memory\n", sim_dname (dptr)); uptr->hwmark = fxread (uptr->filebuf, SZ_D (dptr), /* read file */ cap, uptr->fileref); uptr->flags = uptr->flags | UNIT_BUF; } /* set buffered */ @@ -1429,7 +1480,7 @@ return detach_unit (uptr); t_stat detach_all (int32 start, t_bool shutdown) { -int32 i, j; +uint32 i, j; t_stat reason; DEVICE *dptr; UNIT *uptr; @@ -1444,7 +1495,7 @@ for (i = start; (dptr = sim_devices[i]) != NULL; i++) { if (reason != SCPE_OK) return reason; } } } return SCPE_OK; } - + t_stat detach_unit (UNIT *uptr) { DEVICE *dptr; @@ -1453,9 +1504,9 @@ if (uptr == NULL) return SCPE_IERR; if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; if ((dptr = find_dev_from_unit (uptr)) == NULL) return SCPE_OK; if (uptr->flags & UNIT_BUF) { - int32 cap = (uptr->hwmark + dptr->aincr - 1) / dptr->aincr; + uint32 cap = (uptr->hwmark + dptr->aincr - 1) / dptr->aincr; if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { - if (!sim_quiet) printf ("%s: writing buffer to file\n", dptr->name); + if (!sim_quiet) printf ("%s: writing buffer to file\n", sim_dname (dptr)); rewind (uptr->fileref); fxwrite (uptr->filebuf, SZ_D (dptr), cap, uptr->fileref); if (ferror (uptr->fileref)) perror ("I/O error"); } @@ -1469,6 +1520,71 @@ uptr->filename = NULL; return (fclose (uptr->fileref) == EOF)? SCPE_IOERR: SCPE_OK; } +/* Assign command + + as[sign] device name assign logical name to device +*/ + +t_stat assign_cmd (int32 flag, char *cptr) +{ +char gbuf[CBUFSIZE]; +DEVICE *dptr; + +GET_SWITCHES (cptr); /* get switches */ +if (*cptr == 0) return SCPE_2FARG; /* must be more */ +cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */ +GET_SWITCHES (cptr); /* get switches */ +if (*cptr == 0) return SCPE_2FARG; /* now eol? */ +dptr = find_dev (gbuf); /* locate device */ +if (dptr == NULL) return SCPE_NXDEV; /* found dev? */ +cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */ +if (*cptr != 0) return SCPE_2MARG; /* must be eol */ +if (find_dev (gbuf)) return SCPE_ARG; /* name in use */ +deassign_device (dptr); /* release current */ +return assign_device (dptr, gbuf); +} + +t_stat assign_device (DEVICE *dptr, char *cptr) +{ +dptr->lname = calloc (CBUFSIZE, sizeof (char)); +if (dptr->lname == NULL) return SCPE_MEM; +strncpy (dptr->lname, cptr, CBUFSIZE); +return SCPE_OK; +} + +/* Deassign command + + dea[ssign] device deassign logical name +*/ + +t_stat deassign_cmd (int32 flag, char *cptr) +{ +char gbuf[CBUFSIZE]; +DEVICE *dptr; + +GET_SWITCHES (cptr); /* get switches */ +if (*cptr == 0) return SCPE_2FARG; /* must be more */ +cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */ +if (*cptr != 0) return SCPE_2MARG; /* now eol? */ +dptr = find_dev (gbuf); /* locate device */ +if (dptr == NULL) return SCPE_NXDEV; /* found dev? */ +return deassign_device (dptr); +} + +t_stat deassign_device (DEVICE *dptr) +{ +if (dptr->lname) free (dptr->lname); +dptr->lname = NULL; +return SCPE_OK; +} + +/* Get device display name */ + +char *sim_dname (DEVICE *dptr) +{ +return (dptr->lname? dptr->lname: dptr->name); +} + /* Save command sa[ve] filename save state to specified file @@ -1476,9 +1592,21 @@ return (fclose (uptr->fileref) == EOF)? SCPE_IOERR: SCPE_OK; t_stat save_cmd (int32 flag, char *cptr) { -void *mbuf; FILE *sfile; -int32 i, j, l, t; +t_stat r; +GET_SWITCHES (cptr); /* get switches */ +if (*cptr == 0) return SCPE_2FARG; /* must be more */ +if ((sfile = FOPEN (cptr, "wb")) == NULL) return SCPE_OPENERR; +r = sim_save (sfile); +fclose (sfile); +return r; +} + +t_stat sim_save (FILE *sfile) +{ +void *mbuf; +int32 l, t; +uint32 i, j; t_addr k, high; t_value val; t_stat r; @@ -1490,9 +1618,6 @@ REG *rptr; #define WRITE_I(xx) fxwrite (&(xx), sizeof (xx), 1, sfile) -GET_SWITCHES (cptr); /* get switches */ -if (*cptr == 0) return SCPE_2FARG; /* must be more */ -if ((sfile = FOPEN (cptr, "wb")) == NULL) return SCPE_OPENERR; fputs (save_vercur, sfile); /* [V2.5] save format */ fputc ('\n', sfile); fputs (sim_name, sfile); /* sim name */ @@ -1503,14 +1628,18 @@ WRITE_I (sim_rtime); /* [V2.6] sim rel time */ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devices */ fputs (dptr->name, sfile); /* device name */ fputc ('\n', sfile); + if (dptr->lname) fputs (dptr->lname, sfile); /* [V3.0] logical name */ + fputc ('\n', sfile); WRITE_I (dptr->flags); /* [V2.10] flags */ for (j = 0; j < dptr->numunits; j++) { - uptr = (dptr->units) + j; + uptr = dptr->units + j; t = sim_is_active (uptr); WRITE_I (j); /* unit number */ WRITE_I (t); /* activation time */ WRITE_I (uptr->u3); /* unit specific */ WRITE_I (uptr->u4); + WRITE_I (uptr->u5); /* [V3.0] more unit */ + WRITE_I (uptr->u6); WRITE_I (uptr->flags); /* [V2.10] flags */ if (uptr->flags & UNIT_ATT) fputs (uptr->filename, sfile); fputc ('\n', sfile); @@ -1536,7 +1665,7 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devices */ WRITE_I (l); } /* write only count */ else { WRITE_I (l); /* block count */ - fxwrite (mbuf, l, sz, sfile); } + fxwrite (mbuf, sz, l, sfile); } } /* end for k */ free (mbuf); /* dealloc buffer */ } /* end if mem */ @@ -1545,8 +1674,8 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devices */ WRITE_I (high); } /* end else mem */ } /* end unit loop */ - j = -1; /* end units */ - WRITE_I (j); /* write marker */ + t = -1; /* end units */ + WRITE_I (t); /* write marker */ for (rptr = dptr->registers; (rptr != NULL) && /* loop thru regs */ (rptr->name != NULL); rptr++) { fputs (rptr->name, sfile); /* name */ @@ -1557,9 +1686,7 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devices */ WRITE_I (val); } } /* store */ fputc ('\n', sfile); } /* end registers */ fputc ('\n', sfile); /* end devices */ -r = (ferror (sfile))? SCPE_IOERR: SCPE_OK; /* error during save? */ -fclose (sfile); -return r; +return (ferror (sfile))? SCPE_IOERR: SCPE_OK; /* error during save? */ } /* Restore command @@ -1569,49 +1696,61 @@ return r; t_stat restore_cmd (int32 flag, char *cptr) { +FILE *rfile; +t_stat r; + +GET_SWITCHES (cptr); /* get switches */ +if (*cptr == 0) return SCPE_2FARG; /* must be more */ +if ((rfile = FOPEN (cptr, "rb")) == NULL) return SCPE_OPENERR; +r = sim_rest (rfile); +fclose (rfile); +return r; +} + +t_stat sim_rest (FILE *rfile) +{ char buf[CBUFSIZE]; void *mbuf; -FILE *rfile; -int32 i, j, blkcnt, limit, unitno, time, flg, depth; +int32 j, blkcnt, limit, unitno, time, flg; +uint32 us, depth; t_addr k, high; t_value val, mask; t_stat r; size_t sz; -t_bool v210 = FALSE, v26 = FALSE; +t_bool v30 = FALSE, v210 = FALSE; DEVICE *dptr; UNIT *uptr; REG *rptr; #define READ_S(xx) if (read_line ((xx), CBUFSIZE, rfile) == NULL) \ - { fclose (rfile); return SCPE_IOERR; } + return SCPE_IOERR; #define READ_I(xx) if (fxread (&xx, sizeof (xx), 1, rfile) == 0) \ - { fclose (rfile); return SCPE_IOERR; } + return SCPE_IOERR; -GET_SWITCHES (cptr); /* get switches */ -if (*cptr == 0) return SCPE_2FARG; /* must be more */ -if ((rfile = FOPEN (cptr, "rb")) == NULL) return SCPE_OPENERR; READ_S (buf); /* [V2.5+] read version */ -if (strcmp (buf, save_vercur) == 0) v210 = v26 = TRUE; /* version 2.10? */ -else if (strcmp (buf, save_ver26) == 0) v26 = TRUE; /* version 2.6? */ -else if (strcmp (buf, save_ver25) != 0) { /* version 2.5? */ +if (strcmp (buf, save_vercur) == 0) v30 = v210 = TRUE; /* version 2.11? */ +else if (strcmp (buf, save_ver210) == 0) v210 = TRUE; /* version 2.10? */ +else if (strcmp (buf, save_ver26) != 0) { /* version 2.6? */ printf ("Invalid file version: %s\n", buf); /* no, unknown */ - fclose (rfile); return SCPE_INCOMP; } READ_S (buf); /* read sim name */ if (strcmp (buf, sim_name)) { /* name match? */ printf ("Wrong system type: %s\n", buf); - fclose (rfile); return SCPE_INCOMP; } READ_I (sim_time); /* sim time */ -if (v26) { READ_I (sim_rtime); } /* [V2.6+] sim rel time */ +READ_I (sim_rtime); /* [V2.6+] sim rel time */ for ( ;; ) { /* device loop */ READ_S (buf); /* read device name */ if (buf[0] == 0) break; /* last? */ if ((dptr = find_dev (buf)) == NULL) { /* locate device */ printf ("Invalid device name: %s\n", buf); - fclose (rfile); return SCPE_INCOMP; } + if (v30) { /* [V3.0+] */ + READ_S (buf); /* read logical name */ + deassign_device (dptr); /* delete old name */ + if ((buf[0] != 0) && + ((r = assign_device (dptr, buf)) != SCPE_OK)) return r; } if (v210) { /* [V2.10+] */ READ_I (flg); /* cont flags */ dptr->flags = (dptr->flags & ~DEV_RFLAGS) | /* restore */ @@ -1619,9 +1758,8 @@ for ( ;; ) { /* device loop */ for ( ;; ) { /* unit loop */ READ_I (unitno); /* unit number */ if (unitno < 0) break; /* end units? */ - if (unitno >= dptr->numunits) { /* too big? */ - printf ("Invalid unit number: %s%d\n", dptr->name, unitno); - fclose (rfile); + if ((uint32) unitno >= dptr->numunits) { /* too big? */ + printf ("Invalid unit number: %s%d\n", sim_dname (dptr), unitno); return SCPE_INCOMP; } READ_I (time); /* event time */ uptr = (dptr->units) + unitno; @@ -1629,49 +1767,53 @@ for ( ;; ) { /* device loop */ if (time > 0) sim_activate (uptr, time - 1); READ_I (uptr->u3); /* device specific */ READ_I (uptr->u4); + if (v30) { /* [V3.0+] */ + READ_I (uptr->u5); /* more dev specific */ + READ_I (uptr->u6); } if (v210) { /* [V2.10+] */ READ_I (flg); /* unit flags */ uptr->flags = (uptr->flags & ~UNIT_RFLAGS) | - (flg & UNIT_RFLAGS); } /* restore */ + (flg & UNIT_RFLAGS); } /* restore */ READ_S (buf); /* attached file */ - if (buf[0] != 0) { /* any file? */ - uptr->flags = uptr->flags & ~UNIT_DIS; - sim_switches = SIM_SW_REST; /* attach/rest */ - if (v210 && (flg & UNIT_RO)) /* saved flgs & RO? */ - sim_switches |= SWMASK ('R'); /* RO attach */ - if (dptr->attach != NULL) r = dptr->attach (uptr, buf); - else r = attach_unit (uptr, buf); - if (r != SCPE_OK) return r; } + if (!(dptr->flags & DEV_NET) || /* if not net dev or */ + !(uptr->flags & UNIT_ATT) || /* not currently att */ + (buf[0] == 0)) { /* or will not be att */ + if (dptr->detach) r = dptr->detach (uptr); /* detach old */ + else r = detach_unit (uptr); + if (r != SCPE_OK) return r; + if (buf[0] != 0) { /* any file? */ + uptr->flags = uptr->flags & ~UNIT_DIS; + sim_switches = SIM_SW_REST; /* attach/rest */ + if (v210 && (flg & UNIT_RO)) /* saved flgs & RO? */ + sim_switches |= SWMASK ('R'); /* RO attach */ + if (dptr->attach != NULL) r = dptr->attach (uptr, buf); + else r = attach_unit (uptr, buf); + if (r != SCPE_OK) return r; } } READ_I (high); /* memory capacity */ if (high > 0) { /* [V2.5+] any memory? */ if (((uptr->flags & (UNIT_FIX + UNIT_ATTABLE)) != UNIT_FIX) || (dptr->deposit == NULL)) { - printf ("Can't restore memory: %s%d\n", dptr->name, unitno); - fclose (rfile); + printf ("Can't restore memory: %s%d\n", sim_dname (dptr), unitno); return SCPE_INCOMP; } if (high != uptr->capac) { if ((dptr->flags & DEV_DYNM) && ((dptr->msize == NULL) || - (dptr->msize (uptr, high, NULL, NULL) != SCPE_OK))) { + (dptr->msize (uptr, (int32) high, NULL, NULL) != SCPE_OK))) { printf ("Can't change memory size: %s%d\n", - dptr->name, unitno); - fclose (rfile); + sim_dname (dptr), unitno); return SCPE_INCOMP; } uptr->capac = high; - printf ("Memory size changed: %s%d = ", dptr->name, unitno); + printf ("Memory size changed: %s%d = ", sim_dname (dptr), unitno); fprint_capac (stdout, dptr, uptr); printf ("\n"); } sz = SZ_D (dptr); /* allocate buffer */ - if ((mbuf = calloc (SRBSIZ, sz)) == NULL) { - fclose (rfile); - return SCPE_MEM; } + if ((mbuf = calloc (SRBSIZ, sz)) == NULL) + return SCPE_MEM; for (k = 0; k < high; ) { /* loop thru mem */ READ_I (blkcnt); /* block count */ if (blkcnt < 0) limit = -blkcnt; /* compressed? */ else limit = fxread (mbuf, sz, blkcnt, rfile); - if (limit <= 0) { /* invalid or err? */ - fclose (rfile); - return SCPE_IOERR; } + if (limit <= 0) return SCPE_IOERR; /* invalid or err? */ for (j = 0; j < limit; j++, k = k + (dptr->aincr)) { if (blkcnt < 0) val = 0; /* compressed? */ else SZ_LOAD (sz, val, mbuf, j);/* saved value */ @@ -1687,9 +1829,9 @@ for ( ;; ) { /* device loop */ if (buf[0] == 0) break; /* last? */ if (v210) { READ_I (depth); } /* [V2.10+] depth */ if ((rptr = find_reg (buf, NULL, dptr)) == NULL) { - printf ("Invalid register name: %s %s\n", dptr->name, buf); + printf ("Invalid register name: %s %s\n", sim_dname (dptr), buf); if (v210) { /* [V2.10]+ */ - for (i = 0; i < depth; i++) { /* skip values */ + for (us = 0; us < depth; us++) { /* skip values */ READ_I (val); } } else { READ_I (val); /* must be one val */ @@ -1698,17 +1840,16 @@ for ( ;; ) { /* device loop */ continue; } /* pray! */ if (v210 && (depth != rptr->depth)) /* [V2.10+] mismatch? */ printf ("Register depth mismatch: %s %s, file = %d, sim = %d\n", - dptr->name, buf, depth, rptr->depth); + sim_dname (dptr), buf, depth, rptr->depth); else depth = rptr->depth; /* depth validated */ mask = width_mask[rptr->width]; /* get mask */ - for (i = 0; i < depth; i++) { /* loop thru values */ + for (us = 0; us < depth; us++) { /* loop thru values */ READ_I (val); /* read value */ if (val > mask) /* value ok? */ - printf ("Invalid register value: %s %s\n", dptr->name, buf); - else if (i < rptr->depth) /* in range? */ - put_rval (rptr, i, val); } } + printf ("Invalid register value: %s %s\n", sim_dname (dptr), buf); + else if (us < rptr->depth) /* in range? */ + put_rval (rptr, us, val); } } } /* end device loop */ -fclose (rfile); return SCPE_OK; } @@ -1752,7 +1893,8 @@ return FALSE; /* error */ t_stat run_cmd (int32 flag, char *cptr) { char gbuf[CBUFSIZE]; -int32 i, j, step, unitno; +uint32 i, j; +int32 step, unitno; t_stat r; DEVICE *dptr; UNIT *uptr; @@ -1794,10 +1936,10 @@ if ((flag == RU_RUN) || (flag == RU_BOOT)) { /* run or boot */ if ((r = reset_all (0)) != SCPE_OK) return r; } for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { for (j = 0; j < dptr->numunits; j++) { - uptr = (dptr->units) + j; + uptr = dptr->units + j; if ((uptr->flags & (UNIT_ATT + UNIT_SEQ)) == (UNIT_ATT + UNIT_SEQ)) - fseek (uptr->fileref, uptr->pos, SEEK_SET); } } + fseek_ext (uptr->fileref, uptr->pos, SEEK_SET); } } stop_cpu = 0; if (signal (SIGINT, int_handler) == SIG_ERR) { /* set WRU */ return SCPE_SIGERR; } @@ -1911,10 +2053,6 @@ UNIT *uptr, *tuptr; REG *lowr, *highr; SCHTAB stab, *schptr; FILE *ofile; -t_stat exdep_addr_loop (FILE *ofile, SCHTAB *schptr, int32 flag, char *ptr, - t_addr low, t_addr high, DEVICE *dptr, UNIT *uptr); -t_stat exdep_reg_loop (FILE *ofile, SCHTAB *schptr, int32 flag, char *ptr, - REG *lowr, REG *highr, t_addr lows, t_addr highs); ofile = NULL; /* no output file */ exd2f = FALSE; @@ -1980,7 +2118,7 @@ for (gptr = gbuf, reason = SCPE_OK; if (tptr == NULL) return SCPE_ARG; } } if (*tptr && (*tptr++ != ',')) return SCPE_ARG; reason = exdep_reg_loop (ofile, schptr, flag, cptr, - lowr, highr, low, high); + lowr, highr, (uint32) low, (uint32) high); continue; } tptr = get_range (gptr, &low, &high, dptr->aradix, @@ -2002,10 +2140,10 @@ return reason; */ t_stat exdep_reg_loop (FILE *ofile, SCHTAB *schptr, int32 flag, char *cptr, - REG *lowr, REG *highr, t_addr lows, t_addr highs) + REG *lowr, REG *highr, uint32 lows, uint32 highs) { t_stat reason; -t_addr idx; +uint32 idx; t_value val; REG *rptr; @@ -2015,7 +2153,7 @@ for (rptr = lowr; rptr <= highr; rptr++) { if ((sim_switches & SIM_SW_HIDE) && (rptr->flags & REG_HIDDEN)) continue; for (idx = lows; idx <= highs; idx++) { - if (idx >= (t_addr) rptr->depth) return SCPE_SUB; + if (idx >= rptr->depth) return SCPE_SUB; val = get_rval (rptr, idx); if (schptr && !test_search (val, schptr)) continue; if (flag != EX_D) { @@ -2050,7 +2188,7 @@ for (i = low; i <= high; i = i + (dptr->aincr)) { if (flag != EX_E) { reason = dep_addr (flag, cptr, i, dptr, uptr, reason); if (reason > SCPE_OK) return reason; } - if (reason < SCPE_OK) i = i - (reason * dptr->aincr); } + if (reason < SCPE_OK) i = i + ((-reason) * dptr->aincr); } return SCPE_OK; } @@ -2066,7 +2204,7 @@ return SCPE_OK; return = error status */ -t_stat ex_reg (FILE *ofile, t_value val, int32 flag, REG *rptr, t_addr idx) +t_stat ex_reg (FILE *ofile, t_value val, int32 flag, REG *rptr, uint32 idx) { int32 rdx; @@ -2075,7 +2213,9 @@ if (rptr->depth > 1) fprintf (ofile, "%s[%d]: ", rptr->name, idx); else fprintf (ofile, "%s: ", rptr->name); if (!(flag & EX_E)) return SCPE_OK; GET_RADIX (rdx, rptr->radix); -fprint_val (ofile, val, rdx, rptr->width, rptr->flags & REG_FMT); +if (rptr->flags & REG_VMIO) + fprint_sym (ofile, rdx, &val, NULL, REG_VMIO); +else fprint_val (ofile, val, rdx, rptr->width, rptr->flags & REG_FMT); if (flag & EX_I) fprintf (ofile, " "); else fprintf (ofile, "\n"); return SCPE_OK; @@ -2090,7 +2230,7 @@ return SCPE_OK; return = register value */ -t_value get_rval (REG *rptr, int32 idx) +t_value get_rval (REG *rptr, uint32 idx) { size_t sz; t_value val; @@ -2102,17 +2242,22 @@ if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) { if (idx >= rptr->depth) idx = idx - rptr->depth; } if ((rptr->depth > 1) && (rptr->flags & REG_UNIT)) { uptr = ((UNIT *) rptr->loc) + idx; +#if defined (t_int64) + if (sz <= sizeof (uint32)) val = *((uint32 *) uptr); + else val = *((t_uint64 *) uptr); } +#else val = *((uint32 *) uptr); } +#endif else if ((rptr->depth > 1) && (sz == sizeof (uint8))) val = *(((uint8 *) rptr->loc) + idx); else if ((rptr->depth > 1) && (sz == sizeof (uint16))) val = *(((uint16 *) rptr->loc) + idx); -#if !defined (t_int64) -else val = *(((uint32 *) rptr->loc) + idx); -#else +#if defined (t_int64) else if (sz <= sizeof (uint32)) val = *(((uint32 *) rptr->loc) + idx); else val = *(((t_uint64 *) rptr->loc) + idx); +#else +else val = *(((uint32 *) rptr->loc) + idx); #endif val = (val >> rptr->offset) & width_mask[rptr->width]; return val; @@ -2129,7 +2274,7 @@ return val; return = error status */ -t_stat dep_reg (int32 flag, char *cptr, REG *rptr, t_addr idx) +t_stat dep_reg (int32 flag, char *cptr, REG *rptr, uint32 idx) { t_stat r; t_value val, mask; @@ -2145,7 +2290,9 @@ if (flag & EX_I) { if (*cptr == 0) return SCPE_OK; } /* success */ mask = width_mask[rptr->width]; GET_RADIX (rdx, rptr->radix); -val = get_uint (cptr, rdx, mask, &r); +if (rptr->flags & REG_VMIO) + r = parse_sym (cptr, rdx, NULL, &val, REG_VMIO); +else val = get_uint (cptr, rdx, mask, &r); if (r != SCPE_OK) return SCPE_ARG; if ((rptr->flags & REG_NZ) && (val == 0)) return SCPE_ARG; put_rval (rptr, idx, val); @@ -2163,7 +2310,7 @@ return SCPE_OK; none */ -void put_rval (REG *rptr, int32 idx, t_value val) +void put_rval (REG *rptr, uint32 idx, t_value val) { size_t sz; t_value mask; @@ -2182,20 +2329,28 @@ if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) { if (idx >= rptr->depth) idx = idx - rptr->depth; } if ((rptr->depth > 1) && (rptr->flags & REG_UNIT)) { uptr = ((UNIT *) rptr->loc) + idx; - *((uint32 *) uptr) = - (*((uint32 *) uptr) & - ~(((uint32) mask) << rptr->offset)) | - (((uint32) val) << rptr->offset); } +#if defined (t_int64) + if (sz <= sizeof (uint32)) + *((uint32 *) uptr) = (*((uint32 *) uptr) & + ~(((uint32) mask) << rptr->offset)) | + (((uint32) val) << rptr->offset); + else *((t_uint64 *) uptr) = (*((t_uint64 *) uptr) + & ~(mask << rptr->offset)) | (val << rptr->offset); } +#else + *((uint32 *) uptr) = (*((uint32 *) uptr) & + ~(((uint32) mask) << rptr->offset)) | + (((uint32) val) << rptr->offset); } +#endif else if ((rptr->depth > 1) && (sz == sizeof (uint8))) PUT_RVAL (uint8, rptr, idx, (uint32) val, (uint32) mask); else if ((rptr->depth > 1) && (sz == sizeof (uint16))) PUT_RVAL (uint16, rptr, idx, (uint32) val, (uint32) mask); -#if !defined (t_int64) -else PUT_RVAL (uint32, rptr, idx, val, mask); -#else +#if defined (t_int64) else if (sz <= sizeof (uint32)) PUT_RVAL (uint32, rptr, idx, (int32) val, (uint32) mask); else PUT_RVAL (t_uint64, rptr, idx, val, mask); +#else +else PUT_RVAL (uint32, rptr, idx, val, mask); #endif return; } @@ -2266,7 +2421,7 @@ for (i = 0, j = addr; i < sim_emax; i++, j = j + dptr->aincr) { if (uptr->flags & UNIT_BUF) { SZ_LOAD (sz, sim_eval[i], uptr->filebuf, loc); } else { - fseek (uptr->fileref, sz * loc, SEEK_SET); + fseek_ext (uptr->fileref, sz * loc, SEEK_SET); fxread (&sim_eval[i], sz, 1, uptr->fileref); if ((feof (uptr->fileref)) && !(uptr->flags & UNIT_FIX)) { @@ -2333,9 +2488,9 @@ for (i = 0, j = addr; i < count; i++, j = j + dptr->aincr) { loc = j / dptr->aincr; if (uptr->flags & UNIT_BUF) { SZ_STORE (sz, sim_eval[i], uptr->filebuf, loc); - if (loc >= uptr->hwmark) uptr->hwmark = loc + 1; } + if (loc >= uptr->hwmark) uptr->hwmark = (uint32) loc + 1; } else { - fseek (uptr->fileref, sz * loc, SEEK_SET); + fseek_ext (uptr->fileref, sz * loc, SEEK_SET); fxwrite (&sim_eval[i], sz, 1, uptr->fileref); if (ferror (uptr->fileref)) { clearerr (uptr->fileref); @@ -2470,7 +2625,7 @@ return FALSE; val = value */ -t_value get_uint (char *cptr, int32 radix, t_value max, t_stat *status) +t_value get_uint (char *cptr, uint32 radix, t_value max, t_stat *status) { t_value val; char *tptr; @@ -2495,7 +2650,7 @@ return val; NULL if error */ -char *get_range (char *cptr, t_addr *lo, t_addr *hi, int32 rdx, +char *get_range (char *cptr, t_addr *lo, t_addr *hi, uint32 rdx, t_addr max, char term) { char *tptr; @@ -2505,15 +2660,13 @@ t_addr hb; if (max && strncmp (cptr, "ALL", strlen ("ALL")) == 0) { /* ALL? */ tptr = cptr + strlen ("ALL"); *hi = max; } -else { errno = 0; - *lo = strtoul (cptr, &tptr, rdx); /* get low */ - if (errno || (cptr == tptr)) return NULL; /* error? */ +else { *lo = (t_addr) strtotv (cptr, &tptr, rdx); /* get low */ + if (cptr == tptr) return NULL; /* error? */ if ((*tptr == '-') || (*tptr == ':') || (*tptr == '/')) { if (*tptr == '/') hb = *lo; /* relative? */ cptr = tptr + 1; - errno = 0; - *hi = hb + strtoul (cptr, &tptr, rdx); /* get high */ - if (errno || (cptr == tptr)) return NULL; + *hi = hb + (t_addr) strtotv (cptr, &tptr, rdx); /* get high */ + if (cptr == tptr) return NULL; if (*lo > *hi) return NULL; } else *hi = *lo; } if (term && (*tptr++ != term)) return NULL; @@ -2580,7 +2733,9 @@ int32 i; DEVICE *dptr; for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { - if (strcmp (cptr, dptr->name) == 0) return dptr; } + if ((strcmp (cptr, dptr->name) == 0) || + (dptr->lname && + (strcmp (cptr, dptr->lname) == 0))) return dptr; } return NULL; } @@ -2596,8 +2751,8 @@ return NULL; DEVICE *find_unit (char *cptr, UNIT **uptr) { -int32 i, u; -char *tptr; +uint32 i, u; +char *nptr, *tptr; t_stat r; DEVICE *dptr; @@ -2608,15 +2763,18 @@ if (dptr = find_dev (cptr)) { /* exact match? */ return dptr; } for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* base + unit#? */ - if ((dptr->numunits == 0) || /* no units? */ - (strncmp (cptr, dptr->name, strlen (dptr->name)) != 0)) continue; - tptr = cptr + strlen (dptr->name); /* skip devname */ - if (!isdigit (*tptr)) continue; /* number next? */ - if (qdisable (dptr)) return NULL; /* disabled? */ - u = (int32) get_uint (tptr, 10, dptr->numunits - 1, &r); - if (r != SCPE_OK) *uptr = NULL; /* error? */ - else *uptr = dptr->units + u; - return dptr; } + if (dptr->numunits && /* any units? */ + (((nptr = dptr->name) && + (strncmp (cptr, nptr, strlen (nptr)) == 0)) || + ((nptr = dptr->lname) && + (strncmp (cptr, nptr, strlen (nptr)) == 0)))) { + tptr = cptr + strlen (nptr); + if (isdigit (*tptr)) { + if (qdisable (dptr)) return NULL; /* disabled? */ + u = (uint32) get_uint (tptr, 10, dptr->numunits - 1, &r); + if (r != SCPE_OK) *uptr = NULL; /* error? */ + else *uptr = dptr->units + u; + return dptr; } } } return NULL; } @@ -2631,7 +2789,7 @@ return NULL; DEVICE *find_dev_from_unit (UNIT *uptr) { DEVICE *dptr; -int32 i, j; +uint32 i, j; if (uptr == NULL) return NULL; for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { @@ -2864,11 +3022,11 @@ return 0; On an error, the endptr will equal the inptr. */ -t_value strtotv (char *inptr, char **endptr, int32 radix) +t_value strtotv (char *inptr, char **endptr, uint32 radix) { int32 nodigit; t_value val; -int32 c, digit; +uint32 c, digit; *endptr = inptr; /* assume fails */ if ((radix < 2) || (radix > 36)) return 0; @@ -2877,8 +3035,8 @@ val = 0; nodigit = 1; for (c = *inptr; isalnum(c); c = *++inptr) { /* loop through char */ if (islower (c)) c = toupper (c); - if (isdigit (c)) digit = c - (int) '0'; /* digit? */ - else digit = c + 10 - (int) 'A'; /* no, letter */ + if (isdigit (c)) digit = c - (uint32) '0'; /* digit? */ + else digit = c + 10 - (uint32) 'A'; /* no, letter */ if (digit >= radix) return 0; /* valid in radix? */ val = (val * radix) + digit; /* add to value */ nodigit = 0; } @@ -2899,8 +3057,8 @@ return val; status = error status */ -t_stat fprint_val (FILE *stream, t_value val, int32 radix, - int32 width, int32 format) +t_stat fprint_val (FILE *stream, t_value val, uint32 radix, + uint32 width, uint32 format) { #define MAX_WIDTH ((int) (CHAR_BIT * sizeof (t_value))) t_value owtest, wtest; @@ -2911,8 +3069,8 @@ for (d = 0; d < MAX_WIDTH; d++) dbuf[d] = (format == PV_RZRO)? '0': ' '; dbuf[MAX_WIDTH] = 0; d = MAX_WIDTH; do { d = d - 1; - digit = (int32) (val % (unsigned) radix); - val = val / (unsigned) radix; + digit = (int32) (val % radix); + val = val / radix; dbuf[d] = (digit <= 9)? '0' + digit: 'A' + (digit - 10); } while ((d > 0) && (val != 0)); @@ -3180,10 +3338,10 @@ return total; /* Get file size */ -t_addr sim_fsize (char *cptr) +uint32 sim_fsize (char *cptr) { FILE *fp; -t_addr sz; +uint32 sz; fp = fopen (cptr, "rb"); if (fp == NULL) return 0; @@ -3247,6 +3405,7 @@ else if (delta_vtime < -SIM_TMAX) delta_vtime = -SIM_TMAX; rtc_nxintv[tmr] = 1000 + delta_vtime; /* next wtime */ rtc_currd[tmr] = (int32) (((double) rtc_based[tmr] * (double) rtc_nxintv[tmr]) / 1000.0); /* next delay */ +if (rtc_currd[tmr] <= 0) rtc_currd[tmr] = 1; /* never negative or zero! */ return rtc_currd[tmr]; } diff --git a/scp_tty.c b/scp_tty.c index c86b3204..b5afd7c6 100644 --- a/scp_tty.c +++ b/scp_tty.c @@ -1,6 +1,6 @@ /* scp_tty.c: operating system-dependent I/O routines - Copyright (c) 1993-2002, Robert M Supnik + Copyright (c) 1993-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,8 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 25-Apr-03 RMS Added long seek support from Mark Pizzolato + Added Unix priority control from Mark Pizzolato 24-Sep-02 RMS Removed VT support, added Telnet console support Added CGI support (from Brian Knittel) Added MacOS sleep (from Peter Schorn) @@ -66,7 +68,7 @@ extern FILE *sim_log; /* VMS routines, from Ben Thomas, with fixes from Robert Alan Byer */ #if defined (VMS) -#define __TTYROUTINES 0 +#define _SIM_IO_TTY_ 0 #if defined(__VAX) #define sys$assign SYS$ASSIGN #define sys$qiow SYS$QIOW @@ -211,8 +213,9 @@ return; /* Win32 routines */ #if defined (_WIN32) -#define __TTYROUTINES 0 +#define _SIM_IO_TTY_ 0 #include +#include #include #include static volatile int sim_win_ctlc = 0; @@ -287,7 +290,7 @@ return; /* OS/2 routines, from Bruce Ray */ #if defined (__OS2__) -#define __TTYROUTINES 0 +#define _SIM_IO_TTY_ 0 #include t_stat ttinit (void) @@ -344,7 +347,7 @@ return 0; */ #if defined (__MWERKS__) && defined (macintosh) -#define __TTYROUTINES 0 +#define _SIM_IO_TTY_ 0 #include #include @@ -357,6 +360,7 @@ return 0; #include /* function prototypes */ + Boolean SIOUXIsAppWindow(WindowPtr window); void SIOUXDoMenuChoice(long menuValue); void SIOUXUpdateMenuItems(void); @@ -543,7 +547,7 @@ return; /* BSD UNIX routines */ #if defined (BSDTTY) -#define __TTYROUTINES 0 +#define _SIM_IO_TTY_ 0 #include #include #include @@ -585,11 +589,13 @@ fcntl (0, F_SETFL, runfl); /* non-block mode */ if (ioctl (0, TIOCSETP, &runtty) < 0) return SCPE_TTIERR; if (ioctl (0, TIOCSETC, &runtchars) < 0) return SCPE_TTIERR; if (ioctl (0, TIOCSLTC, &runltchars) < 0) return SCPE_TTIERR; +nice (10); /* lower priority */ return SCPE_OK; } t_stat ttcmdstate (void) { +nice (-10); /* restore priority */ fcntl (0, F_SETFL, cmdfl); /* block mode */ if (ioctl (0, TIOCSETP, &cmdtty) < 0) return SCPE_TTIERR; if (ioctl (0, TIOCSETC, &cmdtchars) < 0) return SCPE_TTIERR; @@ -645,12 +651,13 @@ return; /* POSIX UNIX routines, from Leendert Van Doorn */ -#if !defined (__TTYROUTINES) +#if !defined (_SIM_IO_TTY_) #include #include #include struct termios cmdtty, runtty; +static int prior_norm = 1; t_stat ttinit (void) { @@ -697,12 +704,20 @@ t_stat ttrunstate (void) if (!isatty (fileno (stdin))) return SCPE_OK; /* skip if !tty */ runtty.c_cc[VINTR] = sim_int_char; /* in case changed */ if (tcsetattr (0, TCSAFLUSH, &runtty) < 0) return SCPE_TTIERR; +if (prior_norm) { /* at normal pri? */ + errno = 0; + nice (10); /* try to lower pri */ + prior_norm = errno; } /* if no error, done */ return SCPE_OK; } t_stat ttcmdstate (void) { if (!isatty (fileno (stdin))) return SCPE_OK; /* skip if !tty */ +if (!prior_norm) { /* priority down? */ + errno = 0; + nice (-10); /* try to raise pri*/ + prior_norm = (errno == 0); } /* if no error, done */ if (tcsetattr (0, TCSAFLUSH, &cmdtty) < 0) return SCPE_TTIERR; return SCPE_OK; } @@ -751,3 +766,119 @@ return; } #endif + +/* Long seek routines */ + +#if defined (USE_INT64) && defined (USE_ADDR64) + +/* Alpha VMS */ + +#if defined (__ALPHA) && defined (VMS) /* Alpha VMS */ +#define _SIM_IO_FSEEK_EXT_ 0 + +static t_int64 fpos_t_to_int64 (fpos_t *pos) +{ +unsigned short *w = (unsigned short *) pos; /* endian dep! */ +t_int64 result; + +result = w[1]; +result <<= 16; +result += w[0]; +result <<= 9; +result += w[2]; +return result; +} + +static void int64_to_fpos_t (t_int64 ipos, fpos_t *pos, size_t mbc) +{ +unsigned short *w = (unsigned short *) pos; +int bufsize = mbc << 9; + +w[3] = 0; +w[2] = (unsigned short) (ipos % bufsize); +ipos -= w[2]; +ipos >>= 9; +w[0] = (unsigned short) ipos; +ipos >>= 16; +w[1] = (unsigned short) ipos; +if ((w[2] == 0) && (w[0] || w[1])) { + w[2] = bufsize; + w[0] -= mbc; } +} + +int fseek_ext (FILE *st, t_addr offset, int whence) +{ +t_addr fileaddr; +fpos_t filepos; + +switch (whence) { + case SEEK_SET: + fileaddr = offset; + break; + case SEEK_CUR: + if (fgetpos (st, &filepos)) return (-1); + fileaddr = fpos_t_to_int64 (&filepos); + fileaddr = fileaddr + offset; + break; + default: + errno = EINVAL; + return (-1); } +int64_to_fpos_t (fileaddr, &filepos, 127); +return fsetpos (st, &filepos); +} + +#endif + +/* Alpha UNIX - natively 64b */ + +#if defined (__ALPHA) && defined (__unix__) /* Alpha UNIX */ +#define _SIM_IO_FSEEK_EXT_ 0 + +int fseek_ext (FILE *st, t_addr offset, int whence) +{ +return fseek (st, offset, whence); +} + +#endif + +/* Windows */ + +#if defined (_WIN32) +#define _SIM_IO_FSEEK_EXT_ 0 + +int fseek_ext (FILE *st, t_addr offset, int whence) +{ +fpos_t fileaddr; + +switch (whence) { + case SEEK_SET: + fileaddr = offset; + break; + case SEEK_CUR: + if (fgetpos (st, &fileaddr)) return (-1); + fileaddr = fileaddr + offset; + break; + default: + errno = EINVAL; + return (-1); } +return fsetpos (st, &fileaddr); +} + +#endif /* end Windows */ + +#endif /* end 64b seek defs */ + +/* Default: no OS-specific routine has been defined */ + +#if !defined (_SIM_IO_FSEEK_EXT_) +#define _SIM_IO_FSEEK_EXT_ 0 + +int fseek_ext (FILE *st, t_addr xpos, int origin) +{ +return fseek (st, (int32) xpos, origin); +} + +uint32 sim_taddr_64 = 0; +#else +uint32 sim_taddr_64 = 1; +#endif diff --git a/sim_defs.h b/sim_defs.h index e38904d5..7bdbbd62 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -23,6 +23,13 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 15-Jun-03 RMS Added register flag REG_VMIO + 23-Apr-03 RMS Revised for 32b/64b t_addr + 14-Mar-03 RMS Lengthened default serial output wait + 31-Mar-03 RMS Added u5, u6 fields + 18-Mar-03 RMS Added logical name support + Moved magtape definitions to sim_tape.h + Moved breakpoint definitions from scp.c 03-Mar-03 RMS Added sim_fsize 08-Feb-03 RMS Changed sim_os_sleep to void, added match_ext 05-Jan-03 RMS Added hidden switch definitions, device dyn memory support, @@ -98,9 +105,10 @@ typedef int t_stat; /* status */ typedef int t_bool; /* boolean */ typedef unsigned int8 uint8; typedef unsigned int16 uint16; -typedef unsigned int32 uint32, t_addr; /* address */ -#if defined (USE_INT64) /* 64b */ -#if defined (WIN32) /* Windows */ +typedef unsigned int32 uint32; + +#if defined (USE_INT64) /* 64b data */ +#if defined (_WIN32) /* Windows */ #define t_int64 __int64 #elif defined (__ALPHA) && defined (VMS) /* Alpha VMS */ #define t_int64 __int64 @@ -111,23 +119,21 @@ typedef unsigned int32 uint32, t_addr; /* address */ #endif /* end OS's */ typedef unsigned t_int64 t_uint64, t_value; /* value */ typedef t_int64 t_svalue; /* signed value */ -#else /* 32b */ +#else /* 32b data */ typedef unsigned int32 t_value; typedef int32 t_svalue; -#endif /* end else 64b */ +#endif /* end 64b data */ + +#if defined (USE_INT64) && defined (USE_ADDR64) /* 64b address */ +typedef unsigned t_int64 t_addr; +#define T_ADDR_W 64 +#else /* 32b address */ +typedef unsigned int32 t_addr; +#define T_ADDR_W 32 +#endif /* end 64b address */ /* System independent definitions */ -typedef uint32 t_mtrlnt; /* magtape rec lnt */ -#define MTR_TMK 0x00000000 /* tape mark */ -#define MTR_EOM 0xFFFFFFFF /* end of medium */ -#define MTR_ERF 0x80000000 /* error flag */ -#define MTRF(x) ((x) & MTR_ERF) /* record error flg */ -#define MTRL(x) ((x) & ~MTR_ERF) /* record length */ -#define MT_SET_PNU(u) (u)->flags = (u)->flags | UNIT_PNU -#define MT_CLR_PNU(u) (u)->flags = (u)->flags & ~UNIT_PNU -#define MT_TST_PNU(u) ((u)->flags & UNIT_PNU) - #define FLIP_SIZE (1 << 16) /* flip buf size */ #if !defined (PATH_MAX) /* usually in limits */ #define PATH_MAX 512 @@ -138,6 +144,7 @@ typedef uint32 t_mtrlnt; /* magtape rec lnt */ #define SIM_SW_HIDE (1u << 26) /* enable hiding */ #define SIM_SW_REST (1u << 27) /* attach/restore */ +#define SIM_SW_REG (1u << 28) /* register value */ /* Simulator status codes @@ -202,7 +209,7 @@ typedef uint32 t_mtrlnt; /* magtape rec lnt */ #define KBD_POLL_WAIT 5000 /* keyboard poll */ #define SERIAL_IN_WAIT 100 /* serial in time */ -#define SERIAL_OUT_WAIT 10 /* serial output */ +#define SERIAL_OUT_WAIT 100 /* serial output */ #define NOQUEUE_WAIT 10000 /* min check time */ /* Convert switch letter to bit mask */ @@ -215,31 +222,32 @@ typedef uint32 t_mtrlnt; /* magtape rec lnt */ /* Device data structure */ -struct device { +struct sim_device { char *name; /* name */ - struct unit *units; /* units */ - struct reg *registers; /* registers */ - struct mtab *modifiers; /* modifiers */ - int32 numunits; /* #units */ - int32 aradix; /* address radix */ - int32 awidth; /* address width */ - int32 aincr; /* addr increment */ - int32 dradix; /* data radix */ - int32 dwidth; /* data width */ - t_stat (*examine)(t_value *v, t_addr a, struct unit *up, + struct sim_unit *units; /* units */ + struct sim_reg *registers; /* registers */ + struct sim_mtab *modifiers; /* modifiers */ + uint32 numunits; /* #units */ + uint32 aradix; /* address radix */ + uint32 awidth; /* address width */ + uint32 aincr; /* addr increment */ + uint32 dradix; /* data radix */ + uint32 dwidth; /* data width */ + t_stat (*examine)(t_value *v, t_addr a, struct sim_unit *up, int32 sw); /* examine routine */ - t_stat (*deposit)(t_value v, t_addr a, struct unit *up, + t_stat (*deposit)(t_value v, t_addr a, struct sim_unit *up, int32 sw); /* deposit routine */ - t_stat (*reset)(struct device *dp); /* reset routine */ - t_stat (*boot)(int32 u, struct device *dp); + t_stat (*reset)(struct sim_device *dp);/* reset routine */ + t_stat (*boot)(int32 u, struct sim_device *dp); /* boot routine */ - t_stat (*attach)(struct unit *up, char *cp); + t_stat (*attach)(struct sim_unit *up, char *cp); /* attach routine */ - t_stat (*detach)(struct unit *up); /* detach routine */ + t_stat (*detach)(struct sim_unit *up); /* detach routine */ void *ctxt; /* context */ - int32 flags; /* flags */ - t_stat (*msize)(struct unit *up, int32 v, char *cp, void *dp); + uint32 flags; /* flags */ + t_stat (*msize)(struct sim_unit *up, int32 v, char *cp, void *dp); /* mem size routine */ + char *lname; /* logical name */ }; /* Device flags */ @@ -247,12 +255,14 @@ struct device { #define DEV_V_DIS 0 /* dev enabled */ #define DEV_V_DISABLE 1 /* dev disable-able */ #define DEV_V_DYNM 2 /* mem size dynamic */ +#define DEV_V_NET 3 /* network attach */ #define DEV_V_UF 12 /* user flags */ #define DEV_V_RSV 31 /* reserved */ #define DEV_DIS (1 << DEV_V_DIS) #define DEV_DISABLE (1 << DEV_V_DISABLE) #define DEV_DYNM (1 << DEV_V_DYNM) +#define DEV_NET (1 << DEV_V_NET) #define DEV_UFMASK (((1u << DEV_V_RSV) - 1) & ~((1u << DEV_V_UF) - 1)) #define DEV_RFLAGS (DEV_UFMASK|DEV_DIS) /* restored flags */ @@ -266,21 +276,23 @@ struct device { are for a typical sequential device. */ -struct unit { - struct unit *next; /* next active */ - t_stat (*action)(struct unit *up); /* action routine */ +struct sim_unit { + struct sim_unit *next; /* next active */ + t_stat (*action)(struct sim_unit *up); /* action routine */ char *filename; /* open file name */ FILE *fileref; /* file reference */ void *filebuf; /* memory buffer */ - t_addr hwmark; /* high water mark */ + uint32 hwmark; /* high water mark */ int32 time; /* time out */ - int32 flags; /* flags */ + uint32 flags; /* flags */ t_addr capac; /* capacity */ t_addr pos; /* file position */ int32 buf; /* buffer */ int32 wait; /* wait */ int32 u3; /* device specific */ int32 u4; /* device specific */ + int32 u5; /* device specific */ + int32 u6; /* device specific */ }; /* Unit flags */ @@ -306,15 +318,15 @@ struct unit { /* Register data structure */ -struct reg { +struct sim_reg { char *name; /* name */ void *loc; /* location */ - int32 radix; /* radix */ - int32 width; /* width */ - int32 offset; /* starting bit */ - int32 depth; /* save depth */ - int32 flags; /* flags */ - int32 qptr; /* circ q ptr */ + uint32 radix; /* radix */ + uint32 width; /* width */ + uint32 offset; /* starting bit */ + uint32 depth; /* save depth */ + uint32 flags; /* flags */ + uint32 qptr; /* circ q ptr */ }; #define REG_FMT 0003 /* see PV_x */ @@ -323,27 +335,44 @@ struct reg { #define REG_NZ 0020 /* must be non-zero */ #define REG_UNIT 0040 /* in unit struct */ #define REG_CIRC 0100 /* circular array */ +#define REG_VMIO 0200 /* use VM print/parse */ #define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */ -/* Command table */ +/* Command tables, base and alternate formats */ -struct ctab { +struct sim_ctab { char *name; /* name */ - t_stat (*action)(); /* action routine */ + t_stat (*action)(int32 flag, char *cptr); + /* action routine */ + int32 arg; /* argument */ + char *help; /* help string */ +}; + +struct sim_c1tab { + char *name; /* name */ + t_stat (*action)(struct sim_device *dptr, struct sim_unit *uptr, + int32 flag); /* action routine */ + int32 arg; /* argument */ + char *help; /* help string */ +}; + +struct sim_shtab { + char *name; /* name */ + t_stat (*action)(FILE *st, int32 flag, char *cptr); int32 arg; /* argument */ char *help; /* help string */ }; /* Modifier table - only extended entries have disp, reg, or flags */ -struct mtab { - int32 mask; /* mask or radix */ - int32 match; /* match or max */ +struct sim_mtab { + uint32 mask; /* mask */ + uint32 match; /* match */ char *pstring; /* print string */ char *mstring; /* match string */ - t_stat (*valid)(struct unit *up, int32 v, char *cp, void *dp); + t_stat (*valid)(struct sim_unit *up, int32 v, char *cp, void *dp); /* validation routine */ - t_stat (*disp)(FILE *st, struct unit *up, int32 v, void *dp); + t_stat (*disp)(FILE *st, struct sim_unit *up, int32 v, void *dp); /* display routine */ void *desc; /* value descriptor */ /* REG * if MTAB_VAL */ @@ -359,12 +388,21 @@ struct mtab { /* Search table */ -struct schtab { +struct sim_schtab { int32 logic; /* logical operator */ int32 bool; /* boolean operator */ t_value mask; /* mask for logical */ t_value comp; /* comparison for boolean */ }; + +/* Breakpoint table */ + +struct sim_brktab { + t_addr addr; /* address */ + int32 typ; /* mask of types */ + int32 cnt; /* proceed count */ + char *act; /* action string */ +}; /* The following macros define structure contents */ @@ -392,12 +430,15 @@ struct schtab { /* Typedefs for principal structures */ -typedef struct device DEVICE; -typedef struct unit UNIT; -typedef struct reg REG; -typedef struct ctab CTAB; -typedef struct mtab MTAB; -typedef struct schtab SCHTAB; +typedef struct sim_device DEVICE; +typedef struct sim_unit UNIT; +typedef struct sim_reg REG; +typedef struct sim_ctab CTAB; +typedef struct sim_c1tab C1TAB; +typedef struct sim_shtab SHTAB; +typedef struct sim_mtab MTAB; +typedef struct sim_schtab SCHTAB; +typedef struct sim_brktab BRKTAB; /* Function prototypes */ @@ -410,19 +451,21 @@ uint32 sim_grtime (void); int32 sim_qcount (void); t_stat attach_unit (UNIT *uptr, char *cptr); t_stat detach_unit (UNIT *uptr); -t_stat reset_all (int start_device); +t_stat reset_all (uint32 start_device); size_t fxread (void *bptr, size_t size, size_t count, FILE *fptr); size_t fxwrite (void *bptr, size_t size, size_t count, FILE *fptr); -t_addr sim_fsize (char *cptr); +int fseek_ext (FILE *st, t_addr xpos, int origin); +uint32 sim_fsize (char *cptr); +char *sim_dname (DEVICE *dptr); t_stat get_yn (char *ques, t_stat deflt); char *get_glyph (char *iptr, char *optr, char mchar); char *get_glyph_nc (char *iptr, char *optr, char mchar); -t_value get_uint (char *cptr, int radix, t_value max, t_stat *status); -char *get_range (char *cptr, t_addr *lo, t_addr *hi, int32 rdx, +t_value get_uint (char *cptr, uint32 radix, t_value max, t_stat *status); +char *get_range (char *cptr, t_addr *lo, t_addr *hi, uint32 rdx, t_addr max, char term); t_stat get_ipaddr (char *cptr, uint32 *ipa, uint32 *ipp); -t_value strtotv (char *cptr, char **endptr, int radix); -t_stat fprint_val (FILE *stream, t_value val, int32 rdx, int32 wid, int32 fmt); +t_value strtotv (char *cptr, char **endptr, uint32 radix); +t_stat fprint_val (FILE *stream, t_value val, uint32 rdx, uint32 wid, uint32 fmt); DEVICE *find_dev_from_unit (UNIT *uptr); REG *find_reg (char *ptr, char **optr, DEVICE *dptr); int32 sim_rtc_init (int32 time); @@ -431,6 +474,7 @@ int32 sim_rtcn_init (int32 time, int32 tmr); int32 sim_rtcn_calb (int32 time, int32 tmr); t_stat sim_poll_kbd (void); t_stat sim_putchar (int32 out); +BRKTAB *sim_brk_fnd (t_addr loc); t_bool sim_brk_test (t_addr bloc, int32 btyp); void sim_os_sleep (unsigned int sec); char *match_ext (char *fnam, char *ext); diff --git a/sim_ether.c b/sim_ether.c index c5c3978f..48a4280f 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -1,7 +1,7 @@ /* sim_ether.c: OS-dependent network routines ------------------------------------------------------------------------------ - Copyright (c) 2002, David T. Hittner + Copyright (c) 2002-2003, David T. Hittner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -53,6 +53,14 @@ Modification history: + 30-May-03 DTH Changed WIN32 to _WIN32 for consistency + 07-Mar-03 MP Fixed Linux implementation of PacketGetAdapterNames to also + work on Red Hat 6.2-sparc and Debian 3.0r1-sparc. + 03-Mar-03 MP Changed logging to be consistent on stdout and sim_log + 01-Feb-03 MP Changed type of local variables in eth_packet_trace to + conform to the interface needs of eth_mac_fmt wich produces + char data instead of unsigned char data. Suggested by the + DECC compiler. 15-Jan-03 DTH Corrected PacketGetAdapterNames parameter2 datatype 26-Dec-02 DTH Merged Mark Pizzolato's enhancements with main source Added networking documentation @@ -178,8 +186,8 @@ uint32 eth_crc32(uint32 crc, const void* vbuf, size_t len) void eth_packet_trace(ETH_PACK* packet, char* msg) { - unsigned char src[20]; - unsigned char dst[20]; + char src[20]; + char dst[20]; unsigned short* proto = (unsigned short*) &packet->msg[12]; uint32 crc = eth_crc32(0, packet->msg, packet->len); eth_mac_fmt((ETH_MAC*)&packet->msg[0], dst); @@ -209,7 +217,7 @@ void eth_zero(ETH_DEV* dev) /* Non-implemented versions */ /*============================================================================*/ -#if !defined (WIN32) && !defined(linux) && !defined(__NetBSD__) && \ +#if !defined (_WIN32) && !defined(linux) && !defined(__NetBSD__) && \ !defined (__OpenBSD__) || !defined (USE_NETWORK) t_stat eth_open (ETH_DEV* dev, char* name) {return SCPE_NOFNC;} @@ -233,9 +241,9 @@ int eth_devices (int max, ETH_LIST* dev) #include #include -#ifdef WIN32 +#ifdef _WIN32 #include -#endif /* WIN32 */ +#endif /* _WIN32 */ #if defined (__NetBSD__) || defined (__OpenBSD__) #include #include @@ -270,9 +278,11 @@ t_stat eth_open(ETH_DEV* dev, char* name) memset(errbuf, 0, sizeof(errbuf)); dev->handle = (void*) pcap_open_live(savname, bufsz, ETH_PROMISC, -1, errbuf); if (!dev->handle) { /* can't open device */ + printf ("Eth: pcap_open_live error - %s\n", errbuf); if (sim_log) fprintf (sim_log, "Eth: pcap_open_live error - %s\n", errbuf); return SCPE_OPENERR; } else { + printf ("Eth: opened %s\n", savname); if (sim_log) fprintf (sim_log, "Eth: opened %s\n", savname); } @@ -350,7 +360,7 @@ void eth_callback(u_char* info, const struct pcap_pkthdr* header, const u_char* int i; for (i = 0; i < ETH_FILTER_MAX; i++) { if (memcmp(data, dev->filter_address[i], 6) == 0) to_me = 1; -#ifdef WIN32 +#ifdef _WIN32 /* WinPcap has a known bug/feature that whenever a packet is transmitted, it is looped back into the receive buffers. This is not consistant with the @@ -363,7 +373,7 @@ void eth_callback(u_char* info, const struct pcap_pkthdr* header, const u_char* the network has the same DECNET address and refuses to start, giving an "Invalid media address" error. - This code section was ifdef'd for WIN32 only to allow other OS's a chance to + This code section was ifdef'd for _WIN32 only to allow other OS's a chance to properly implement the above behavior. If it breaks the ethernet simulator on other platforms, remove the ifdef so that it will affect your platform, and then notify the author so that he can fix the ifdef. :-) @@ -497,7 +507,7 @@ int eth_devices(int max, ETH_LIST* list) return index; /* count of devices */ } -#endif /* (WIN32 || linux || __NetBSD__ || __OpenBSD__) && USE_NETWORK */ +#endif /* (_WIN32 || linux || __NetBSD__ || __OpenBSD__) && USE_NETWORK */ /*============================================================================*/ /* linux-specific code */ @@ -534,13 +544,27 @@ int PacketGetAdapterNames(char* buffer, unsigned long* size) while (ioctl(sock, SIOCGIFNAME, &ifr) == 0) { /* Only use ethernet interfaces */ - ioctl(sock, SIOCGIFHWADDR, &ifr); - if (ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER) { + if ((0 == ioctl(sock, SIOCGIFHWADDR, &ifr)) && + (ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER)) { strcpy(buffer+ptr, ifr.ifr_name); - ptr += strlen(buffer)+1; + ptr += strlen(buffer+ptr)+1; } ifr.ifr_ifindex = ++iindex; } + if (ptr == 0) { /* Found any Ethernet Interfaces? */ + /* No, so try some good guesses since the SIOCGIFNAME ioctl + doesn't always return the ethernet interfaces, at least not + Debian or Red Hat running on sparc boxes. */ + + for (iindex=0; iindex < 10; ++iindex) { + sprintf(ifr.ifr_name, "eth%d", iindex); + if ((0 == ioctl(sock, SIOCGIFHWADDR, &ifr)) && + (ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER)) { + strcpy(buffer+ptr, ifr.ifr_name); + ptr += strlen(buffer+ptr)+1; + } + } + } close(sock); diff --git a/sim_ether.h b/sim_ether.h index 809530b0..b0471f57 100644 --- a/sim_ether.h +++ b/sim_ether.h @@ -1,7 +1,7 @@ /* sim_ether.h: OS-dependent network information ------------------------------------------------------------------------------ - Copyright (c) 2002, David T. Hittner + Copyright (c) 2002-2003, David T. Hittner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,6 +28,8 @@ Modification history: + 05-Jun-03 DTH Added used to struct eth_packet + 01-Feb-03 MP Changed some uint8 strings to char* to reflect usage 22-Oct-02 DTH Added all_multicast and promiscuous support 21-Oct-02 DTH Corrected copyright again 16-Oct-02 DTH Fixed copyright @@ -57,6 +59,7 @@ struct eth_packet { uint8 msg[1518]; int len; + int used; }; struct eth_message { @@ -75,8 +78,8 @@ struct eth_queue { struct eth_list { int num; - uint8 name[ETH_DEV_NAME_MAX]; - uint8 desc[ETH_DEV_DESC_MAX]; + char name[ETH_DEV_NAME_MAX]; + char desc[ETH_DEV_DESC_MAX]; }; typedef int ETH_BOOL; @@ -86,7 +89,7 @@ typedef void (*ETH_PCALLBACK)(int status); typedef struct eth_list ETH_LIST; struct eth_device { - uint8* name; /* name of ethernet device */ + char* name; /* name of ethernet device */ void* handle; /* handle of implementation-specific device */ ETH_PCALLBACK read_callback; /* read callback function */ ETH_PCALLBACK write_callback; /* write callback function */ diff --git a/sim_rev.h b/sim_rev.h index 88c3473e..a06c0fae 100644 --- a/sim_rev.h +++ b/sim_rev.h @@ -27,15 +27,106 @@ #ifndef _SIM_REV_H_ #define _SIM_REV_H_ 0 -#define SIM_MAJOR 2 -#define SIM_MINOR 10 -#define SIM_PATCH 4 +#define SIM_MAJOR 3 +#define SIM_MINOR 0 +#define SIM_PATCH 0 -/* V2.10 revision history +/* V3.0 revision history patch date module(s) and fix(es) - 4 22-Feb-03 scp.c + 0 15-Jun-03 scp.c: + -- added ASSIGN/DEASSIGN + -- changed RESTORE to detach files + -- added u5, u6 unit fields + -- added USE_ADDR64 support + -- changed some structure fields to unsigned + + scp_tty.c: added extended file seek + + sim_sock.c: fixed calling sequence in stubs + + sim_tape.c: + -- added E11 and TPC format support + -- added extended file support + + sim_tmxr.c: fixed bug in SHOW CONNECTIONS + + all magtapes: + -- added multiformat support + -- added extended file support + + i1401_cpu.c: + -- fixed mnemonic, instruction lengths, and reverse + scan length check bug for MCS + -- fixed MCE bug, BS off by 1 if zero suppress + -- fixed chaining bug, D lost if return to SCP + -- fixed H branch, branch occurs after continue + -- added check for invalid 8 character MCW, LCA + + i1401_mt.c: fixed load-mode end of record response + + nova_dsk.c: fixed variable size interaction with restore + + pdp1_dt.c: fixed variable size interaction with restore + + pdp10_rp.c: fixed ordering bug in attach + + pdp11_cpu.c: + -- fixed bug in MMR1 update (found by Tim Stark) + -- fixed bug in memory size table + + pdp11_lp.c, pdp11_rq.c: added extended file support + + pdp11_rl.c, pdp11_rp.c, pdp11_ry.c: fixed ordering bug in attach + + pdp11_tc.c: fixed variable size interaction with restore + + pdp11_xq.c: + -- corrected interrupts on IE state transition (code by Tom Evans) + -- added interrupt clear on soft reset (first noted by Bob Supnik) + -- removed interrupt when setting XL or RL (multiple people) + -- added SET/SHOW XQ STATS + -- added SHOW XQ FILTERS + -- added ability to split received packet into multiple buffers + -- added explicit runt & giant packet processing + + vax_fpa.c: + -- fixed integer overflow bug in CVTfi + -- fixed multiple bugs in EMODf + + vax_io.c: optimized byte and word DMA routines + + vax_sysdev.c: + -- added calibrated delay to ROM reads (from Mark Pizzolato) + -- fixed calibration problems in interval timer (from Mark Pizzolato) + + pdp1_dt.c: fixed variable size interaction with restore + + pdp18b_dt.c: fixed variable size interaction with restore + + pdp18b_mt.c: fixed bug in MTTR + + pdp18b_rf.c: fixed variable size interaction with restore + + pdp8_df.c, pdp8_rf.c: fixed variable size interaction + with restore + + pdp8_dt.c: fixed variable size interaction with restore + + pdp8_mt.c: fixed bug in SKTR + + hp2100_dp.c,hp2100_dq.c: + -- fixed bug in read status (13210A controller) + -- fixed bug in seek completion + + id_pt.c: fixed type declaration (found by Mark Pizzolato) + + gri_cpu.c: fixed bug in SC queue pointer management + +/* V2.10 revision history + + 4 03-Mar-03 scp.c -- added .ini startup file capability -- added multiple breakpoint actions -- added multiple switch evaluation points @@ -69,6 +160,8 @@ patch date module(s) and fix(es) pdp10_tu.c: revised to use magtape library + pdp11_cpu.c: fixed bug in MMR1 update (found by Tim Stark) + pdp11_stddev.c -- added set line frequency command -- added set ctrl-c command @@ -95,7 +188,9 @@ patch date module(s) and fix(es) -- fixed bugs in BOT error handling, interrupt handling -- revised to use magtape library - pdp18b_rf.c: removed 22nd bit from disk address + pdp18b_rf.c: + -- removed 22nd bit from disk address + -- fixed autosizing algorithm pdp18b_stddev.c: -- added set line frequency command diff --git a/sim_sock.c b/sim_sock.c index 094a9d96..e79380b3 100644 --- a/sim_sock.c +++ b/sim_sock.c @@ -1,6 +1,6 @@ -/* scp_sock.c: OS-dependent socket routines +/* sim_sock.c: OS-dependent socket routines - Copyright (c) 2001, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,8 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 17-Apr-03 RMS Fixed non-implemented version of sim_close_sock + (found by Mark Pizzolato) 17-Dec-02 RMS Added sim_connect_socket, sim_create_socket 08-Oct-02 RMS Revised for .NET compatibility 22-Aug-02 RMS Changed calling sequence for sim_accept_conn @@ -78,7 +80,7 @@ int32 sim_write_sock (SOCKET sock, char *msg, int32 nbytes) return 0; } -void sim_close_sock (SOCKET sock) +void sim_close_sock (SOCKET sock, t_bool master) { return; } @@ -106,7 +108,7 @@ SOCKET sim_create_sock (void) SOCKET newsock; int32 err; -#if defined (WIN32) +#if defined (_WIN32) WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD (1, 1); @@ -180,7 +182,7 @@ SOCKET sim_accept_conn (SOCKET master, uint32 *ipaddr) int32 sta, err; #if defined (macintosh) socklen_t size; -#elif defined (WIN32) || defined (__EMX__) +#elif defined (_WIN32) || defined (__EMX__) int size; #else size_t size; @@ -244,7 +246,7 @@ return send (sock, msg, nbytes, 0); void sim_close_sock (SOCKET sock, t_bool master) { -#if defined (WIN32) +#if defined (_WIN32) closesocket (sock); if (master) { sim_sock_cnt = sim_sock_cnt - 1; @@ -257,7 +259,7 @@ close (sock); return; } -#if defined (WIN32) /* Windows */ +#if defined (_WIN32) /* Windows */ SOCKET sim_setnonblock (SOCKET sock) { unsigned long non_block = 1; diff --git a/sim_sock.h b/sim_sock.h index fdf8459e..c31ac676 100644 --- a/sim_sock.h +++ b/sim_sock.h @@ -23,6 +23,8 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 20-Mar-03 RMS Added missing timerclear definition for VMS (from + Robert Alan Byer) 15-Feb-03 RMS Added time.h for EMX (from Holger Veit) 17-Dec-02 RMS Added sim_connect_sock 08-Oct-02 RMS Revised for .NET compatibility @@ -35,7 +37,7 @@ #ifndef _SIM_SOCK_H_ #define _SIM_SOCK_H_ 0 -#if defined (WIN32) /* Windows */ +#if defined (_WIN32) /* Windows */ #undef INT_PTR /* hack, hack */ #include @@ -56,6 +58,9 @@ #if defined (VMS) /* VMS unique */ #include /* for ioctl */ +#if !defined (timerclear) +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#endif #endif SOCKET sim_master_sock (int32 port); diff --git a/sim_tape.c b/sim_tape.c index 221325a4..bdb5c13a 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -1,4 +1,4 @@ -/* sim_tape.h: simulator tape support library +/* sim_tape.c: simulator tape support library Copyright (c) 1993-2003, Robert M Supnik @@ -26,6 +26,9 @@ Ultimately, this will be a place to hide processing of various tape formats, as well as OS-specific direct hardware access. + 25-Apr-03 RMS Added extended file support + 28-Mar-03 RMS Added E11 and TPC format support + Public routines: sim_tape_attach attach tape unit @@ -42,31 +45,91 @@ sim_tape_bot TRUE if at beginning of tape sim_tape_eot TRUE if at or beyond end of tape sim_tape_wrp TRUE if write protected + sim_tape_set_fmt set tape format + sim_tape_show_fmt show tape format */ #include "sim_defs.h" #include "sim_tape.h" +struct sim_tape_fmt { + char *name; /* name */ + int32 uflags; /* unit flags */ + t_addr bot; /* bot test */ +}; + +static struct sim_tape_fmt fmts[MTUF_N_FMT] = { + { "SIMH", 0, sizeof (t_mtrlnt) - 1 }, + { "E11", 0, sizeof (t_mtrlnt) - 1 }, + { "TPC", UNIT_RO, sizeof (t_tpclnt) - 1 }, +/* { "TPF", UNIT_RO, 0 }, */ + { NULL, 0, 0 } +}; + +extern int32 sim_switches; + t_stat sim_tape_ioerr (UNIT *uptr); t_stat sim_tape_wrdata (UNIT *uptr, uint32 dat); +uint32 sim_tape_tpc_map (UNIT *uptr, t_addr *map); +t_addr sim_tape_tpc_fnd (UNIT *uptr, t_addr *map); /* Attach tape unit */ t_stat sim_tape_attach (UNIT *uptr, char *cptr) { -t_stat r = attach_unit (uptr, cptr); -if (r != SCPE_OK) return r; -return sim_tape_rewind (uptr); +uint32 objc; +char gbuf[CBUFSIZE]; +t_stat r; + +if (sim_switches & SWMASK ('F')) { /* format spec? */ + cptr = get_glyph (cptr, gbuf, 0); /* get spec */ + if (*cptr == 0) return SCPE_2FARG; /* must be more */ + if (sim_tape_set_fmt (uptr, 0, gbuf, NULL) != SCPE_OK) + return SCPE_ARG; } +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) return r; /* error? */ + +switch (MT_GET_FMT (uptr)) { /* case on format */ +case MTUF_F_TPC: /* TPC */ + objc = sim_tape_tpc_map (uptr, NULL); /* get # objects */ + if (objc == 0) { /* tape empty? */ + sim_tape_detach (uptr); + return SCPE_FMT; } /* yes, complain */ + uptr->filebuf = calloc (objc + 1, sizeof (t_mtrlnt)); + if (uptr->filebuf == NULL) { /* map allocated? */ + sim_tape_detach (uptr); + return SCPE_MEM; } /* no, complain */ + uptr->hwmark = objc + 1; /* save map size */ + sim_tape_tpc_map (uptr, uptr->filebuf); /* fill map */ + break; +default: + break; } + +sim_tape_rewind (uptr); +return SCPE_OK; } /* Detach tape unit */ t_stat sim_tape_detach (UNIT *uptr) { -t_stat r = detach_unit (uptr); +uint32 f = MT_GET_FMT (uptr); +t_stat r; +r = detach_unit (uptr); /* detach unit */ if (r != SCPE_OK) return r; -return sim_tape_rewind (uptr); + +switch (f) { /* case on format */ +case MTUF_F_TPC: /* TPC */ + if (uptr->filebuf) free (uptr->filebuf); /* free map */ + uptr->filebuf = NULL; + uptr->hwmark = 0; + break; +default: + break; } + +sim_tape_rewind (uptr); +return SCPE_OK; } /* Read record length forward (internal routine) @@ -83,24 +146,52 @@ return sim_tape_rewind (uptr); read error unchanged, PNU set end of file/medium unchanged, PNU set tape mark updated - data record unchanged + data record updated, fxread will read record forward */ t_stat sim_tape_rdlntf (UNIT *uptr, t_mtrlnt *bc) { +uint32 f = MT_GET_FMT (uptr); +t_mtrlnt sbc; +t_tpclnt tpcbc; + MT_CLR_PNU (uptr); if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */ -fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set tape pos */ -fxread (bc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */ -if (ferror (uptr->fileref)) { /* error? */ - MT_SET_PNU (uptr); /* pos not upd */ - return sim_tape_ioerr (uptr); } -if (feof (uptr->fileref) || (*bc == MTR_EOM)) { /* eof or eom? */ - MT_SET_PNU (uptr); /* pos not upd */ - return MTSE_EOM; } -if (*bc == MTR_TMK) { /* tape mark? */ - uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* spc over tmk */ - return MTSE_TMK; } +fseek_ext (uptr->fileref, uptr->pos, SEEK_SET); /* set tape pos */ + +switch (f) { /* switch on fmt */ +case MTUF_F_STD: case MTUF_F_E11: + fxread (bc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */ + sbc = MTR_L (*bc); /* save rec lnt */ + if (ferror (uptr->fileref)) { /* error? */ + MT_SET_PNU (uptr); /* pos not upd */ + return sim_tape_ioerr (uptr); } + if (feof (uptr->fileref) || (*bc == MTR_EOM)) { /* eof or eom? */ + MT_SET_PNU (uptr); /* pos not upd */ + return MTSE_EOM; } + uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* spc over rec lnt */ + if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */ + uptr->pos = uptr->pos + sizeof (t_mtrlnt) + /* spc over record */ + ((f == MTUF_F_STD)? ((sbc + 1) & ~1): sbc); + break; + +case MTUF_F_TPC: + fxread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref); + *bc = tpcbc; /* save rec lnt */ + if (ferror (uptr->fileref)) { /* error? */ + MT_SET_PNU (uptr); /* pos not upd */ + return sim_tape_ioerr (uptr); } + if (feof (uptr->fileref)) { /* eof? */ + MT_SET_PNU (uptr); /* pos not upd */ + return MTSE_EOM; } + uptr->pos = uptr->pos + sizeof (t_tpclnt); /* spc over reclnt */ + if (tpcbc == TPC_TMK) return MTSE_TMK; /* tape mark? */ + uptr->pos = uptr->pos + ((tpcbc + 1) & ~1); /* spc over record */ + break; + +default: + return MTSE_FMT; } + return MTSE_OK; } @@ -120,26 +211,51 @@ return MTSE_OK; end of file unchanged end of medium updated tape mark updated - data record unchanged + data record updated, fxread will read record forward */ t_stat sim_tape_rdlntr (UNIT *uptr, t_mtrlnt *bc) { +uint32 f = MT_GET_FMT (uptr); +t_addr ppos; +t_mtrlnt sbc; +t_tpclnt tpcbc; + MT_CLR_PNU (uptr); if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */ -if (uptr->pos < sizeof (t_mtrlnt)) return MTSE_BOT; /* at BOT? */ -fseek (uptr->fileref, uptr->pos - sizeof (t_mtrlnt), SEEK_SET); -fxread (bc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */ -if (ferror (uptr->fileref)) /* error? */ - return sim_tape_ioerr (uptr); -if (feof (uptr->fileref)) return MTSE_EOM; /* eof? */ -if (*bc == MTR_EOM) { /* eom? */ - uptr->pos = uptr->pos - sizeof (t_mtrlnt); /* spc over eom */ - return MTSE_EOM; } -if (*bc == MTR_TMK) { /* tape mark? */ - uptr->pos = uptr->pos - sizeof (t_mtrlnt); /* spc over tmk */ - return MTSE_TMK; } -return SCPE_OK; +if (sim_tape_bot (uptr)) return MTSE_BOT; /* at BOT? */ + +switch (f) { /* switch on fmt */ +case MTUF_F_STD: case MTUF_F_E11: + fseek_ext (uptr->fileref, uptr->pos - sizeof (t_mtrlnt), SEEK_SET); + fxread (bc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */ + sbc = MTR_L (*bc); + if (ferror (uptr->fileref)) /* error? */ + return sim_tape_ioerr (uptr); + if (feof (uptr->fileref)) return MTSE_EOM; /* eof? */ + uptr->pos = uptr->pos - sizeof (t_mtrlnt); /* spc over rec lnt */ + if (*bc == MTR_EOM) return MTSE_EOM; /* eom? */ + if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */ + uptr->pos = uptr->pos - sizeof (t_mtrlnt) - /* spc over record */ + ((f == MTUF_F_STD)? ((sbc + 1) & ~1): sbc); + fseek_ext (uptr->fileref, uptr->pos + sizeof (t_mtrlnt), SEEK_SET); + break; + +case MTUF_F_TPC: + ppos = sim_tape_tpc_fnd (uptr, uptr->filebuf); /* find prev rec */ + fseek_ext (uptr->fileref, ppos, SEEK_SET); /* position */ + fxread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref); + *bc = tpcbc; /* save rec lnt */ + if (ferror (uptr->fileref)) /* error? */ + return sim_tape_ioerr (uptr); + if (feof (uptr->fileref)) return MTSE_EOM; /* eof? */ + uptr->pos = ppos; /* spc over record */ + if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */ + fseek_ext (uptr->fileref, uptr->pos + sizeof (t_tpclnt), SEEK_SET); + break; +default: + return MTSE_FMT; } +return MTSE_OK; } /* Read record forward @@ -165,21 +281,23 @@ return SCPE_OK; t_stat sim_tape_rdrecf (UNIT *uptr, uint8 *buf, t_mtrlnt *bc, t_mtrlnt max) { -t_mtrlnt i, tbc, rbc, ebc; +t_mtrlnt i, tbc, rbc; +t_addr opos; t_stat st; +opos = uptr->pos; /* old position */ if (st = sim_tape_rdlntf (uptr, &tbc)) return st; /* read rec lnt */ *bc = rbc = MTR_L (tbc); /* strip error flag */ -ebc = (rbc + 1) & ~1; if (rbc > max) { /* rec out of range? */ MT_SET_PNU (uptr); + uptr->pos = opos; return MTSE_INVRL; } i = fxread (buf, sizeof (uint8), rbc, uptr->fileref); /* read record */ if (ferror (uptr->fileref)) { /* error? */ MT_SET_PNU (uptr); + uptr->pos = opos; return sim_tape_ioerr (uptr); } for ( ; i < rbc; i++) buf[i] = 0; /* fill with 0's */ -uptr->pos = uptr->pos + ebc + (2 * sizeof (t_mtrlnt)); /* move tape */ return (MTR_F (tbc)? MTSE_RECE: MTSE_OK); } @@ -207,19 +325,16 @@ return (MTR_F (tbc)? MTSE_RECE: MTSE_OK); t_stat sim_tape_rdrecr (UNIT *uptr, uint8 *buf, t_mtrlnt *bc, t_mtrlnt max) { -t_mtrlnt i, rbc, tbc, ebc; +t_mtrlnt i, rbc, tbc; t_stat st; if (st = sim_tape_rdlntr (uptr, &tbc)) return st; /* read rec lnt */ *bc = rbc = MTR_L (tbc); /* strip error flag */ -ebc = (rbc + 1) & ~1; if (rbc > max) return MTSE_INVRL; /* rec out of range? */ -fseek (uptr->fileref, uptr->pos - sizeof (t_mtrlnt) - ebc, SEEK_SET); i = fxread (buf, sizeof (uint8), rbc, uptr->fileref); /* read record */ if (ferror (uptr->fileref)) /* error? */ return sim_tape_ioerr (uptr); for ( ; i < rbc; i++) buf[i] = 0; /* fill with 0's */ -uptr->pos = uptr->pos - ebc - (2 * sizeof (t_mtrlnt)); /* move tape */ return (MTR_F (tbc)? MTSE_RECE: MTSE_OK); } @@ -242,19 +357,22 @@ return (MTR_F (tbc)? MTSE_RECE: MTSE_OK); t_stat sim_tape_wrrecf (UNIT *uptr, uint8 *buf, t_mtrlnt bc) { -t_mtrlnt ebc = (MTR_L (bc) + 1) & ~1; +uint32 f = MT_GET_FMT (uptr); +t_mtrlnt sbc; MT_CLR_PNU (uptr); +if (f == MTUF_F_STD) sbc = (bc + 1) & ~1; +else sbc = bc; if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */ if (uptr->flags & MTUF_WRP) return MTSE_WRP; /* write prot? */ -fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */ +fseek_ext (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */ fxwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref); -fxwrite (buf, sizeof (uint8), ebc, uptr->fileref); +fxwrite (buf, sizeof (uint8), sbc, uptr->fileref); fxwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref); if (ferror (uptr->fileref)) { /* error? */ MT_SET_PNU (uptr); return sim_tape_ioerr (uptr); } -uptr->pos = uptr->pos + ebc + (2 * sizeof (t_mtrlnt)); /* move tape */ +uptr->pos = uptr->pos + sbc + (2 * sizeof (t_mtrlnt)); /* move tape */ return MTSE_OK; } @@ -265,7 +383,7 @@ t_stat sim_tape_wrdata (UNIT *uptr, uint32 dat) MT_CLR_PNU (uptr); if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */ if (uptr-> flags & MTUF_WRP) return MTSE_WRP; /* write prot? */ -fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */ +fseek_ext (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */ fxwrite (&dat, sizeof (t_mtrlnt), 1, uptr->fileref); if (ferror (uptr->fileref)) { /* error? */ MT_SET_PNU (uptr); @@ -292,31 +410,26 @@ return sim_tape_wrdata (uptr, MTR_EOM); t_stat sim_tape_sprecf (UNIT *uptr, t_mtrlnt *bc) { -t_mtrlnt ebc; t_stat st; -if (st = sim_tape_rdlntf (uptr, bc)) return st; /* get record length */ +st = sim_tape_rdlntf (uptr, bc); /* get record length */ *bc = MTR_L (*bc); -ebc = (*bc + 1) & ~1; -uptr->pos = uptr->pos + ebc + (2 * sizeof (t_mtrlnt)); /* update position */ -return MTSE_OK; +return st; } /* Space record reverse */ t_stat sim_tape_sprecr (UNIT *uptr, t_mtrlnt *bc) { -t_mtrlnt ebc; t_stat st; if (MT_TST_PNU (uptr)) { MT_CLR_PNU (uptr); + *bc = 0; return SCPE_OK; } -if (st = sim_tape_rdlntr (uptr, bc)) return st; /* get record length */ +st = sim_tape_rdlntr (uptr, bc); /* get record length */ *bc = MTR_L (*bc); -ebc = (*bc + 1) & ~1; -uptr->pos = uptr->pos - ebc - (2 * sizeof (t_mtrlnt)); /* update position */ -return MTSE_OK; +return st; } /* Rewind tape */ @@ -340,7 +453,9 @@ return SCPE_OK; t_bool sim_tape_bot (UNIT *uptr) { -return (uptr->pos < sizeof (t_mtrlnt))? TRUE: FALSE; +uint32 f = MT_GET_FMT (uptr); + +return (uptr->pos <= fmts[f].bot)? TRUE: FALSE; } /* Test for end of tape */ @@ -365,3 +480,69 @@ perror ("Magtape library I/O error"); clearerr (uptr->fileref); return SCPE_IOERR; } + +/* Set tape format */ + +t_stat sim_tape_set_fmt (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +int32 f; + +if (uptr == NULL) return SCPE_IERR; +if (cptr == NULL) return SCPE_ARG; +for (f = 0; f < MTUF_N_FMT; f++) { + if (fmts[f].name && (strcmp (cptr, fmts[f].name) == 0)) { + uptr->flags = (uptr->flags & ~MTUF_FMT) | + (f << MTUF_V_FMT) | fmts[f].uflags; + return SCPE_OK; } } +return SCPE_ARG; +} + +/* Show tape format */ + +t_stat sim_tape_show_fmt (FILE *st, UNIT *uptr, int32 val, void *desc) +{ +int32 f = MT_GET_FMT (uptr); + +if (fmts[f].name) fprintf (st, "%s format", fmts[f].name); +else fprintf (st, "invalid format"); +return SCPE_OK; +} + +/* Map a TPC format tape image */ + +uint32 sim_tape_tpc_map (UNIT *uptr, t_addr *map) +{ +t_addr tpos; +t_tpclnt bc; +uint32 i, objc; + +if ((uptr == NULL) || (uptr->fileref == NULL)) return 0; +for (objc = 0, tpos = 0;; ) { + fseek_ext (uptr->fileref, tpos, SEEK_SET); + i = fxread (&bc, sizeof (t_tpclnt), 1, uptr->fileref); + if (i == 0) break; + if (map) map[objc] = tpos; + objc++; + tpos = tpos + ((bc + 1) & ~1) + sizeof (t_tpclnt); } +if (map) map[objc] = tpos; +return objc; +} + +/* Find the preceding record length in a TPC file */ + +t_addr sim_tape_tpc_fnd (UNIT *uptr, t_addr *map) +{ +uint32 lo, hi, p; + + +if (map == NULL) return 0; +lo = 0; +hi = uptr->hwmark - 1; +do { p = (lo + hi) >> 1; + if (uptr->pos == map[p]) + return ((p == 0)? map[p]: map[p - 1]); + else if (uptr->pos < map[p]) hi = p - 1; + else lo = p + 1; } +while (lo <= hi); +return ((p == 0)? map[p]: map[p - 1]); +} diff --git a/sim_tape.h b/sim_tape.h index 302fd8ec..74d3f363 100644 --- a/sim_tape.h +++ b/sim_tape.h @@ -27,18 +27,9 @@ #ifndef _SIM_TAPE_H_ #define _SIM_TAPE_H_ 0 -/* Temporary for use with old sim_defs.h */ +/* SIMH/E11 tape format */ -#undef MTR_TMK -#undef MTR_EOM -#undef MTR_ERF -#undef MT_SET_PNU -#undef MT_CLR_PNU -#undef MT_TST_PNU - -/* Default tape format */ - -/* typedef uint32 t_mtrlnt; /* magtape rec lnt */ +typedef uint32 t_mtrlnt; /* magtape rec lnt */ #define MTR_TMK 0x00000000 /* tape mark */ #define MTR_EOM 0xFFFFFFFF /* end of medium */ @@ -46,6 +37,12 @@ #define MTR_F(x) ((x) & MTR_ERF) /* record error flg */ #define MTR_L(x) ((x) & ~MTR_ERF) /* record length */ +/* TPC tape format */ + +typedef uint16 t_tpclnt; /* magtape rec lnt */ + +#define TPC_TMK 0x0000 /* tape mark */ + /* Unit flags */ #define MTUF_V_PNU (UNIT_V_UF + 0) /* position not upd */ @@ -61,6 +58,7 @@ #define MTUF_V_UF (MTUF_V_FMT + MTUF_W_FMT) #define MTUF_PNU (1u << MTUF_V_PNU) #define MTUF_WLK (1u << MTUF_V_WLK) +#define MTUF_FMT (MTUF_M_FMT << MTUF_V_FMT) #define MTUF_WRP (MTUF_WLK | UNIT_RO) #define MT_SET_PNU(u) (u)->flags = (u)->flags | MTUF_PNU @@ -97,5 +95,7 @@ t_stat sim_tape_reset (UNIT *uptr); t_bool sim_tape_bot (UNIT *uptr); t_bool sim_tape_wrp (UNIT *uptr); t_bool sim_tape_eot (UNIT *uptr, t_addr cap); +t_stat sim_tape_set_fmt (UNIT *uptr, int32 val, char *cptr, void *desc); +t_stat sim_tape_show_fmt (FILE *st, UNIT *uptr, int32 val, void *desc); #endif diff --git a/sim_tmxr.c b/sim_tmxr.c index 5fbcbae0..e3f0f6a8 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -1,6 +1,6 @@ /* sim_tmxr.c: Telnet terminal multiplexor library - Copyright (c) 2001, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,7 @@ Based on the original DZ11 simulator by Thord Nilson, as updated by Arthur Krewat. + 09-Mar-03 RMS Fixed bug in SHOW CONN 22-Dec-02 RMS Fixed bugs in IAC+IAC receive and transmit sequences Added support for received break (all from by Mark Pizzolato) Fixed bug in attach @@ -40,6 +41,7 @@ #include "sim_defs.h" #include "sim_sock.h" #include "sim_tmxr.h" +#include /* Telnet protocol constants - negatives are for init'ing signed char data */ @@ -446,7 +448,7 @@ if (lp->conn) { ctime = (sim_os_msec () - lp->cnms) / 1000; hr = ctime / 3600; mn = (ctime / 60) % 60; - sc = ctime % 3600; + sc = ctime % 60; fprintf (st, "IP address %d.%d.%d.%d", o1, o2, o3, o4); if (ctime) fprintf (st, ", connected %02d:%02d:%02d\n", hr, mn, sc); } else fprintf (st, "line disconnected\n"); diff --git a/sim_tmxr.h b/sim_tmxr.h index 2091920a..45ffa415 100644 --- a/sim_tmxr.h +++ b/sim_tmxr.h @@ -1,6 +1,6 @@ /* sim_tmxr.h: terminal multiplexor definitions - Copyright (c) 2001, Robert M Supnik + Copyright (c) 2001-2003, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/simh_doc.txt b/simh_doc.txt index b63ee516..85f21956 100644 --- a/simh_doc.txt +++ b/simh_doc.txt @@ -1,7 +1,7 @@ To: Users From: Bob Supnik -Subj: Simulator Usage, V2.10-3 -Date: 15-Feb-2003 +Subj: Simulator Usage, V3.0 +Date: 15-May-2004 COPYRIGHT NOTICE @@ -73,6 +73,11 @@ The simulators recognize or require a few compile-time #defines: default is GNU C (long long). If your compiler uses a different convention, you will have to modify sim_defs.h. +- The PDP-10, PDP-11, and VAX simulators share common peripherals. + To distinguish the target system, one of three variables must be + defined on the command line: VM_PDP10 for the PDP-10; VM_PDP11 + for the PDP-11; or VM_VAX for the VAX. + - The PDP-11 and VAX simulators optionally support Ethernet. To include Ethernet emulation, USE_NETWORK must be defined as part of the compilation command line. At present, Ethernet support is @@ -134,7 +139,7 @@ Examples: - PDP-11 under TERMIOS UNIX: - % cc pdp11_*.c scp*.c sim_*.c -lm -o pdp11 + % cc -DVM_PDP11 pdp11_*.c scp*.c sim_*.c -lm -o pdp11 - PDP-9 under TERMIOS UNIX: @@ -142,7 +147,7 @@ Examples: - PDP-10 under BSD terminal UNIX: - % cc -DUSE_INT64 -DBSDTTY pdp10_*.c scp*.c sim_*.c -lm -o pdp10 + % cc -DVM_PDP10 -DUSE_INT64 -DBSDTTY pdp10_*.c scp*.c sim_*.c -lm -o pdp10 1.2 Compiling Under Windows @@ -329,6 +334,26 @@ switches, such as disks and tapes, support read only operation; other devices do not. If a file is ATTACHed read only, its contents can be examined but not modified. +For simulated magnetic tapes, the ATTACH command can specify the +format of the attached tape image file: + + sim> ATTACH -f (cr) + +The currently supported tape image file formats are: + + SIMH SIMH simulator format + E11 E11 simulator format + TPC TPC format + +The tape format can also be set with the SET command prior to ATTACH: + + sim> SET FORMAT=(cr) + sim> ATT (cr) + +The format of an attached file can be displayed with the SHOW command: + + sim> SHOW FORMAT(cr) + For Telnet-based terminal emulators, the ATTACH command associates the master unit with a TCP/IP port: @@ -600,6 +625,21 @@ emulation of the Telnet client. sim> SET NOTELNET -- disable console Telnet sim> SHOW TELNET -- show console Telnet status +The standard device names can be supplemented with logical names. +Logical names must be unique within a simulator (that is, they cannot +be the same as an existing device name). To assign a logical name +to a device: + + sim> ASSIGN device log-name -- assign log-name to device + +To remove a logical name: + + sim> DEASSIGN device -- remove logical name + +To show all logical names: + + sim> SHOW NAMES + 3.11 Logging Console Output Output to the console can be logged simultaneously to a file. Logging @@ -690,6 +730,15 @@ Magnetic tapes are endian independent and consistent across simulator families. A magtape produced by the Nova simulator will appear to have its 16b words byte swapped if read by the PDP-11 simulator. +SIMH can read and write E11-format magtape images. E11 format differs +from SIMH format only for odd-length records; the data portion of E11 +records is not padded with an extra byte. + +SIMH can read TPC-format magtape images. TPC format uses a 16b record +header, with 0x0000 denoting file mark. The record header is not +repeated at the end of the record. Odd-length records are padded with +an extra byte. + 4. Line Printers Line printer output is represented by an ASCII file of lines separated @@ -743,48 +792,48 @@ card reader - - - - - line printer y y y h y clock y y y - y extra terminal y y y - y -hard disk y y y - h -fixed disk y - h - h +hard disk y y y - y +fixed disk y - h - y floppy disk y y y - - -drum - - - - h +drum - - - h h DECtape y y - h y -mag tape h y y - h +mag tape y y y - h system 1401 2100 PDP-10 H316 VAX device CPU y y y h y -FPU - d y - y -EIS/CIS - d y - - +FPU - y y - y +EIS/CIS - y y - - console h y y h y -paper tape - d h h y +paper tape - y h h y card reader y - - - - -line printer y d y h y -clock - d y h y -extra terminal - h y - y -hard disk - d y - y +line printer y y y h y +clock - y y h y +extra terminal - y y - y +hard disk - y y - y fixed disk - n - - - floppy disk - - h - - drum - n - - - DECtape - - - - - -mag tape y d y - y +mag tape y y y - y system GRI-909 1620 i16 i32 SDS940 device -CPU h h d d d -FPU - - d d - +CPU h h d y d +FPU - - d y - CIS - - - - - -console h h d d h -paper tape h h d d h +console h h d y h +paper tape h h d y h card reader - h - - - -line printer - h d d h -clock h - d d n -extra terminal - - h h h -hard disk - h d d h +line printer - h d y h +clock h - d y n +extra terminal - - h y h +hard disk - h d y h fixed disk - - - - h floppy disk - - d d - drum - - - - h DECtape - - - - - -mag tape - - d d h +mag tape - - d y h legend: y = runs operating system or sample program d = runs diagnostics @@ -797,300 +846,308 @@ Revision History (covering Rev 2.0 to present) Starting with Rev 2.7, detailed revision histories can be found in file sim_rev.c. +Rev 3.0, May, 03 + Added logical name support + Added multiple tape format support + Added 64b address support + Rev 2.10, Nov, 02 - Added Telnet console capability, removed VT emulation - Added DO with substitutable arguments (from Brian Knittel) - Added quiet mode (from Brian Knittel) - Added ! command (from Mark Pizzolato) - Added Telnet BREAK support (from Mark Pizzolato) - Added device enable/disable support - Added optional simulator hooks for input, output, commands - Added PDP-11 KW11P programmable clock - Added PDP-11 RK611/RK06/RK07 disk - Added PDP-11/VAX TMSCP tape - Added PDP-11/VAX DELQA Ethernet support (from David Hittner) - Added PDP-11/PDP-10 RX211/RX02 floppy disk - Added PDP-11/VAX autoconfiguration support - Added PDP-10/PDP-11/VAX variable vector support - Added PDP-1 DECtape - Added PDP-1, PDP-4 Type 24 serial drum support - Added PDP-8 RX28 support - Added PDP-9 RB09 fixed head disk, LP09 line printer - Added HP2100 12845A line printer - Added HP2100 13183 magtape support - Added HP2100 boot ROM support - Added HP2100 interprocessor link support - Added IBM 1620 - Added SDS 940 - Added Interdata 16b and 32b systems - Added 16b DECtape file format support - Added support for statically buffered devices - Added magtape end of medium support - Added 7B/8B support to terminals and multiplexors - Added BREAK support to terminals and multiplexors + Added Telnet console capability, removed VT emulation + Added DO with substitutable arguments (from Brian Knittel) + Added .ini initialization file (from Hans Pufal) + Added quiet mode (from Brian Knittel) + Added ! command (from Mark Pizzolato) + Added Telnet BREAK support (from Mark Pizzolato) + Added device enable/disable support + Added optional simulator hooks for input, output, commands + Added breakpoint actions + Added magtape simulation library + Added PDP-11 KW11P programmable clock + Added PDP-11 RK611/RK06/RK07 disk + Added PDP-11/VAX TMSCP tape + Added PDP-11/VAX DELQA Ethernet support (from David Hittner) + Added PDP-11/PDP-10 RX211/RX02 floppy disk + Added PDP-11/VAX autoconfiguration support + Added PDP-10/PDP-11/VAX variable vector support + Added PDP-1 DECtape + Added PDP-1, PDP-4 Type 24 serial drum support + Added PDP-8 RX28 support + Added PDP-9 RB09 fixed head disk, LP09 line printer + Added HP2100 12845A line printer + Added HP2100 13183 magtape support + Added HP2100 boot ROM support + Added HP2100 interprocessor link support + Added IBM 1620 + Added SDS 940 + Added Interdata 16b and 32b systems + Added 16b DECtape file format support + Added support for statically buffered devices + Added magtape end of medium support + Added 50/60Hz support to line frequency clocks + Added 7B/8B support to terminals and multiplexors + Added BREAK support to terminals and multiplexors Rev 2.9, Jan, 02 - Added circular register arrays - Replaced ENABLE/DISABLE with SET ENABLED/DISABLED - Replaced LOG/NOLOG with SET LOG/NOLOG - Generalized the timer calibration package - Added additional routines to the multiplexor library - Added SET DISCONNECT, SHOW STATISTICS commands to multiplexors - Reimplemented PDP-8 TTX as a unified multiplexor - Implemented a PC queue in most simulators - Added VAX simulator - Added GRI-909 simulator - Added Peter Schorn's MITS 8080/Z80 simulator - Added Brian Knittel's IBM 1130 simulator - Added HP2100 DQ, DR, MS, MUX devices - Added SET VT/NOVT commands + Added circular register arrays + Replaced ENABLE/DISABLE with SET ENABLED/DISABLED + Replaced LOG/NOLOG with SET LOG/NOLOG + Generalized the timer calibration package + Added additional routines to the multiplexor library + Added SET DISCONNECT, SHOW STATISTICS commands to multiplexors + Reimplemented PDP-8 TTX as a unified multiplexor + Implemented a PC queue in most simulators + Added VAX simulator + Added GRI-909 simulator + Added Peter Schorn's MITS 8080/Z80 simulator + Added Brian Knittel's IBM 1130 simulator + Added HP2100 DQ, DR, MS, MUX devices + Added SET VT/NOVT commands Rev 2.8, Dec, 01 - Added DO command - Added general breakpoint facility - Added extended SET/SHOW capability - Replaced ADD/REMOVE with SET ONLINE/OFFLINE - Added global register name recognition - Added unit-based register arrays - Added Charles Owen's System 3 simulator - Added PDP-11 I/O bus map - Added PDP-11/VAX RQDX3 - Added PDP-8 RL8A - Revised 18b PDP interrupt structure - Revised directory and documentation structure - Added support for MINGW environment + Added DO command + Added general breakpoint facility + Added extended SET/SHOW capability + Replaced ADD/REMOVE with SET ONLINE/OFFLINE + Added global register name recognition + Added unit-based register arrays + Added Charles Owen's System 3 simulator + Added PDP-11 I/O bus map + Added PDP-11/VAX RQDX3 + Added PDP-8 RL8A + Revised 18b PDP interrupt structure + Revised directory and documentation structure + Added support for MINGW environment Rev 2.7, Sep, 01 - Added DZ11 (from Thord Nilson and Art Krewat) - to PDP-11, PDP-10 - Added additional terminals to PDP-8 - Added TSS/8 packed character format to PDP-8 - Added sim_sock and sim_tmxr libraries - Added sim_qcount and simulator exit detach all facilities - Added Macintosh sim_sock support (from Peter Schorn) - Added simulator revision level, SHOW version - Changed int64/uint64 to t_int64/t_uint64 for Windoze - Fixed bug in PDP-11 interrupt acknowledge - Fixed bugs in PDP-11 TS NXM check, boot code, error status; - added extended characteristics and status - Fixed bug in PDP-11 TC stop, stop all functions - Fixed receive interrupt while disconnected bug in DZ11 - Fixed multi-unit operation bugs, interrupt bugs in - PDP-11 RP, PDP-10 RP, PDP-10 TU - Fixed carrier detect bug in PDP-11, PDP-10 DZ - Fixed bug in PDP-8 reset routine - Fixed conditional in PDP-18b CPU - Fixed SC = 0 bug in PDP-18b EAE - Fixed bug in PDP-7 LPT - Upgraded Nova second terminal to use sim_tmxr - Upgraded PDP-18b second terminal to use sim_tmxr - Upgraded PDP-11 LTC to full KW11-L - Removed hack multiple console support + Added DZ11 (from Thord Nilson and Art Krewat) to PDP-11, + PDP-10 + Added additional terminals to PDP-8 + Added TSS/8 packed character format to PDP-8 + Added sim_sock and sim_tmxr libraries + Added sim_qcount and simulator exit detach all facilities + Added Macintosh sim_sock support (from Peter Schorn) + Added simulator revision level, SHOW version + Changed int64/uint64 to t_int64/t_uint64 for Windoze + Fixed bug in PDP-11 interrupt acknowledge + Fixed bugs in PDP-11 TS NXM check, boot code, error status; + added extended characteristics and status + Fixed bug in PDP-11 TC stop, stop all functions + Fixed receive interrupt while disconnected bug in DZ11 + Fixed multi-unit operation bugs, interrupt bugs in PDP-11 + RP, PDP-10 RP, PDP-10 TU + Fixed carrier detect bug in PDP-11, PDP-10 DZ + Fixed bug in PDP-8 reset routine + Fixed conditional in PDP-18b CPU + Fixed SC = 0 bug in PDP-18b EAE + Fixed bug in PDP-7 LPT + Upgraded Nova second terminal to use sim_tmxr + Upgraded PDP-18b second terminal to use sim_tmxr + Upgraded PDP-11 LTC to full KW11-L + Removed hack multiple console support Rev 2.6b, Aug, 01 - Added H316/516 simulator - Added Macintosh support from Louis Chrétien, Peter Schorn, - and Ben Supnik - Added bad block table option to PDP-11 RL, RP - Removed register in declarations - Fixed bugs found by Peter Schorn - -- endian error in PDP-10, PDP-11 RP - -- space reverse error in PDP-11 TS - -- symbolic input in 1401 - Fixed bug in PDP-1 RIM loader found by Derek Peschel - Fixed bug in Nova fixed head disk + Added H316/516 simulator + Added Macintosh support from Louis Chrétien, Peter Schorn, + and Ben Supnik + Added bad block table option to PDP-11 RL, RP + Removed register in declarations + Fixed bugs found by Peter Schorn + -- endian error in PDP-10, PDP-11 RP + -- space reverse error in PDP-11 TS + -- symbolic input in 1401 + Fixed bug in PDP-1 RIM loader found by Derek Peschel + Fixed bug in Nova fixed head disk Rev 2.6a, Jun, 01 - Added PDP-9, PDP-15 API option - Added PDP-9, PDP-15 second terminal - Added PDP-10 option for TOPS-20 V4.1 bug fix - Added PDP-10 FE CTRL-C option for Windoze - Added console logging - Added multiple console support - Added comment recognition - Increased size of string buffers for long path names - Fixed bug in big-endian I/O found by Dave Conroy - Fixed DECtape reset in PDP-8, PDP-11, PDP-9/15 - Fixed RIM loader PC handling in PDP-9/15 - Fixed indirect pointers in PDP-10 paging - Fixed SSC handling in PDP-10 TM02/TU45 - Fixed JMS to non-existent memory in PDP-8 - Fixed error handling on command file + Added PDP-9, PDP-15 API option + Added PDP-9, PDP-15 second terminal + Added PDP-10 option for TOPS-20 V4.1 bug fix + Added PDP-10 FE CTRL-C option for Windoze + Added console logging + Added multiple console support + Added comment recognition + Increased size of string buffers for long path names + Fixed bug in big-endian I/O found by Dave Conroy + Fixed DECtape reset in PDP-8, PDP-11, PDP-9/15 + Fixed RIM loader PC handling in PDP-9/15 + Fixed indirect pointers in PDP-10 paging + Fixed SSC handling in PDP-10 TM02/TU45 + Fixed JMS to non-existent memory in PDP-8 + Fixed error handling on command file Rev 2.6, May, 01 - Added ENABLE/DISABLE devices - Added SHOW DEVICES - Added examination/modification of register arrays - Added PDP-10 simulator - Added clock autocalibration to SCP, Nova, PDP-8, PDP-11, - PDP-18b - Added PDP-8, PDP-11, PDP-9/15 DECtape - Added PDP-8 DF32 - Added 4k Disk Monitor boot to PDP-8 RF08 and DF32 - Added PDP-4/7 funny format loader support - Added extension handling to the PDP-8 and -9/15 loaders - Added PDP-11 TS11/TSV05 - Added integer interval timer to SCP - Added filename argument to LOAD/DUMP - Revised magtape and DECtape bootstraps to rewind - before first instruction - Fixed 3 cycle data break sequence in PDP-8 RF - Fixed 3 cycle data break sequence in 18b PDP LP, MT, RF - Fixed CS1.TRE write, CS2.MXF,UPE write, and CS2.UAI in - PDP-11 RP - Fixed 4M memory size definition in PDP-11 - Fixed attach bug in RESTORE - Fixed detach bug for buffered devices - Updated copyright notices, fixed comments + Added ENABLE/DISABLE devices + Added SHOW DEVICES + Added examination/modification of register arrays + Added PDP-10 simulator + Added clock autocalibration to SCP, Nova, PDP-8, PDP-11, + PDP-18b + Added PDP-8, PDP-11, PDP-9/15 DECtape + Added PDP-8 DF32 + Added 4k Disk Monitor boot to PDP-8 RF08 and DF32 + Added PDP-4/7 funny format loader support + Added extension handling to the PDP-8 and -9/15 loaders + Added PDP-11 TS11/TSV05 + Added integer interval timer to SCP + Added filename argument to LOAD/DUMP + Revised magtape and DECtape bootstraps to rewind before + first instruction + Fixed 3 cycle data break sequence in PDP-8 RF + Fixed 3 cycle data break sequence in 18b PDP LP, MT, RF + Fixed CS1.TRE write, CS2.MXF,UPE write, and CS2.UAI in + PDP-11 RP + Fixed 4M memory size definition in PDP-11 + Fixed attach bug in RESTORE + Fixed detach bug for buffered devices + Updated copyright notices, fixed comments Rev 2.5a, Dec, 00 - Added CMD flop to HP paper tape and line printer - Added status input for HP paper tape punch and TTY - Added Dutch Owens' 1401 mag tape boot routine - Added Bruce Ray's Nova plotter and second terminal modules - Added Charles Owen's Eclipse CPU support - Added PDP-9/PDP-15 RIM/BIN loader support - Added PDP-9/PDP-15 extend/bank initial state registers - Added PDP-9/PDP-15 half/full duplex support - Moved software documentation to a separate file - Fixed SCP handling of devices without units - Fixed FLG, FBF initialization in many HP peripherals - Fixed 1401 bugs found by Dutch Owens - -- 4, 7 char NOPs are legal - -- 1 char B is chained BCE - -- MCE moves whole character, not digit, after first - Fixed Nova bugs found by Bruce Ray - -- traps implemented on Nova 3 as well as Nova 4 - -- DIV and DIVS 0/0 set carry - -- RETN sets SP from FP at outset - -- IORST does not clear carry - -- Nova 4 implements two undocumented instructions - Fixed bugs in 18b PDP's - -- XCT indirect address calculation - -- missing index instructions in PDP-15 - -- bank mode handling in PDP-15 + Added CMD flop to HP paper tape and line printer + Added status input for HP paper tape punch and TTY + Added Charles Owen's 1401 mag tape boot routine + Added Bruce Ray's Nova plotter and second terminal modules + Added Charles Owen's Eclipse CPU support + Added PDP-9/PDP-15 RIM/BIN loader support + Added PDP-9/PDP-15 extend/bank initial state registers + Added PDP-9/PDP-15 half/full duplex support + Moved software documentation to a separate file + Fixed SCP handling of devices without units + Fixed FLG, FBF initialization in many HP peripherals + Fixed 1401 bugs found by Charles Owen + -- 4, 7 char NOPs are legal + -- 1 char B is chained BCE + -- MCE moves whole character, not digit, after first + Fixed Nova bugs found by Bruce Ray + -- traps implemented on Nova 3 as well as Nova 4 + -- DIV and DIVS 0/0 set carry + -- RETN sets SP from FP at outset + -- IORST does not clear carry + -- Nova 4 implements two undocumented instructions + Fixed bugs in 18b PDP's + -- XCT indirect address calculation + -- missing index instructions in PDP-15 + -- bank mode handling in PDP-15 Rev 2.5, Nov, 00 - Removed Digital and Compaq from copyrights, as - authorized by Compaq Sr VP Bill Strecker - Revised save/restore format for 64b simulators - Added examine to file - Added unsigned integer data types to sim_defs - Added Nova 3 and Nova 4 instructions to Nova CPU - Added HP2100 - Added Interdata 4 - Fixed indirect loop through autoinc/dec in Nova CPU - Fixed MDV enabled test in Nova CPU + Removed Digital and Compaq from copyrights, as authorized + by Compaq Sr VP Bill Strecker + Revised save/restore format for 64b simulators + Added examine to file + Added unsigned integer data types to sim_defs + Added Nova 3 and Nova 4 instructions to Nova CPU + Added HP2100 + Fixed indirect loop through autoinc/dec in Nova CPU + Fixed MDV enabled test in Nova CPU Rev 2.4, Jan, 99 - Placed all sources under X11-like open source license - Added DUMP command, revised sim_load interface - Added SHOW MODIFIERS command - Revised magtape format to include record error flag - Fixed 64b problems in SCP - Fixed big endian problem in PDP-11 bad block routine - Fixed interrupt on error bug in PDP-11 RP/RM disks - Fixed ROL/ROR inversion in PDP-11 symbolic routines + Placed all sources under X11-like open source license + Added DUMP command, revised sim_load interface + Added SHOW MODIFIERS command + Revised magtape format to include record error flag + Fixed 64b problems in SCP + Fixed big endian problem in PDP-11 bad block routine + Fixed interrupt on error bug in PDP-11 RP/RM disks + Fixed ROL/ROR inversion in PDP-11 symbolic routines Rev 2.3d, Sep, 98 - Added BeOS support - Added radix commands and switches - Added PDP-11 CIS support - Added RT11 V5.3 to distribution kits - Fixed "shift 32" bugs in SCP, PDP-11 floating point - Fixed bug in PDP-11 paper tape reader - Fixed bug in ^D handling + Added BeOS support + Added radix commands and switches + Added PDP-11 CIS support + Added RT11 V5.3 to distribution kits + Fixed "shift 32" bugs in SCP, PDP-11 floating point + Fixed bug in PDP-11 paper tape reader + Fixed bug in ^D handling Rev 2.3c, May, 98 - Fixed bug in PDP-11 DIV overflow check - Fixed bugs in PDP-11 magtape bootstrap - Fixed bug in PDP-11 magtape unit select - Replaced UNIX V7 disk images + Fixed bug in PDP-11 DIV overflow check + Fixed bugs in PDP-11 magtape bootstrap + Fixed bug in PDP-11 magtape unit select + Replaced UNIX V7 disk images Rev 2.3b, May, 98 - Added switch recognition to all simulator commands - Added RIM loader to PDP-8 paper tape reader and loader - Added second block bootstrap to PDP-11 magtape - Fixed bug in PDP-8 RF bootstrap - Fixed bug in PDP-11 symbolic display - Fixed bugs in PDP-11 floating point (LDEXP, STEXP, - MODf, STCfi, overflow handling) + Added switch recognition to all simulator commands + Added RIM loader to PDP-8 paper tape reader and loader + Added second block bootstrap to PDP-11 magtape + Fixed bug in PDP-8 RF bootstrap + Fixed bug in PDP-11 symbolic display + Fixed bugs in PDP-11 floating point (LDEXP, STEXP, + MODf, STCfi, overflow handling) Rev 2.3a, Nov, 97 - Added search capability - Added bad block table command to PDP-11 disks - Added bootstrap to PDP-11 magtape - Added additional Nova moving head disks - Added RT-11 sample software - Fixed bugs in PDP-11 RM/RP disks - Fixed bugs in Nova moving head disks - Fixed endian dependence in 18b PDP RIM loader + Added search capability + Added bad block table command to PDP-11 disks + Added bootstrap to PDP-11 magtape + Added additional Nova moving head disks + Added RT-11 sample software + Fixed bugs in PDP-11 RM/RP disks + Fixed bugs in Nova moving head disks + Fixed endian dependence in 18b PDP RIM loader Rev 2.3, Mar, 97 - Added PDP-11 RP - Added PDP-1 - Changed UNIX terminal I/O to TERMIOS - Changed magtape format to double ended - Changed PDP-8 current page mnemonic from T to C - Added endian independent I/O routines - Added precise integer data types - Fixed bug in sim_poll_kbd - Fixed bug in PDP-8 binary loader - Fixed bugs in TM11 magtape - Fixed bug in RX11 bootstrap - Fixed bug in 18b PDP ADD - Fixed bug in 18b PDP paper tape reader - Fixed bug in PDP-4 console - Fixed bug in PDP-4,7 line printer + Added PDP-11 RP + Added PDP-1 + Changed UNIX terminal I/O to TERMIOS + Changed magtape format to double ended + Changed PDP-8 current page mnemonic from T to C + Added endian independent I/O routines + Added precise integer data types + Fixed bug in sim_poll_kbd + Fixed bug in PDP-8 binary loader + Fixed bugs in TM11 magtape + Fixed bug in RX11 bootstrap + Fixed bug in 18b PDP ADD + Fixed bug in 18b PDP paper tape reader + Fixed bug in PDP-4 console + Fixed bug in PDP-4,7 line printer Rev 2.2d, Dec, 96 - Added ADD/REMOVE commands - Added unit enable/disable support to device simulators - Added features for IBM 1401 project - Added switch recognition for symbolic input - Fixed bug in variable length IEXAMINE - Fixed LCD bug in RX8E - Initial changes for Win32 - Added IBM 1401 + Added ADD/REMOVE commands + Added unit enable/disable support to device simulators + Added features for IBM 1401 project + Added switch recognition for symbolic input + Fixed bug in variable length IEXAMINE + Fixed LCD bug in RX8E + Initial changes for Win32 + Added IBM 1401 Rev 2.2b, Apr, 96 - Added PDP-11 dynamic memory size support + Added PDP-11 dynamic memory size support Rev 2.2a, Feb, 96 - New endian independent magtape format + New endian independent magtape format Rev 2.2 Jan, 96 - Added register buffers for save/restore - Added 18b PDP's - Guaranteed TTI, CLK times are non-zero - Fixed breakpoint/RUN interaction bug - Fixed magnetic tape backspace to EOF bug - Fixed ISZ/DCA inversion in PDP-8 symbol table - Fixed sixbit conversion in PDP-8 examine/deposit - Fixed origin increment bug in PDP-11 binary loader - Fixed GCC longjmp optimization bug in PDP-11 CPU - Fixed unit number calculation bug in SCP and in - Nova, PDP-11, 18b PDP moving head disks + Added register buffers for save/restore + Added 18b PDP's + Guaranteed TTI, CLK times are non-zero + Fixed breakpoint/RUN interaction bug + Fixed magnetic tape backspace to EOF bug + Fixed ISZ/DCA inversion in PDP-8 symbol table + Fixed sixbit conversion in PDP-8 examine/deposit + Fixed origin increment bug in PDP-11 binary loader + Fixed GCC longjmp optimization bug in PDP-11 CPU + Fixed unit number calculation bug in SCP and in Nova, + Nova, PDP-11, 18b PDP moving head disks Rev 2.1 Dec, 95 - Fixed PTR bug (setting done on EOF) in PDP-8, Nova - Fixed RX bug (setting error on INIT if drive 1 is - not attached) in PDP-8, PDP-11 - Fixed RF treatment of photocell flag in PDP-8 - Fixed autosize bug (always chose smallest disk if new - file) in PDP-11, Nova - Fixed not attached bug (reported as not attachable) in - most mass storage devices - Fixed Nova boot ROMs - Fixed bug in RESTORE (didn't requeue if delay = 0) - Fixed bug in RESTORE (clobbered device position) - Declared static constant arrays as static const - Added PDP-8, Nova magnetic tape simulators - Added Dasher mode to Nova terminal simulator - Added LINUX support + Fixed PTR bug (setting done on EOF) in PDP-8, Nova + Fixed RX bug (setting error on INIT if drive 1 is + not attached) in PDP-8, PDP-11 + Fixed RF treatment of photocell flag in PDP-8 + Fixed autosize bug (always chose smallest disk if new + file) in PDP-11, Nova + Fixed not attached bug (reported as not attachable) in + most mass storage devices + Fixed Nova boot ROMs + Fixed bug in RESTORE (didn't requeue if delay = 0) + Fixed bug in RESTORE (clobbered device position) + Declared static constant arrays as static const + Added PDP-8, Nova magnetic tape simulators + Added Dasher mode to Nova terminal simulator + Added LINUX support Rev 2.0 May, 95 - Added symbolic assembly/disassembly + Added symbolic assembly/disassembly Acknowledgements @@ -1110,12 +1167,12 @@ Louis Chr Dave Conroy HP 21xx documentation, PDP-10, PDP-18b debugging L Peter Deutsch PDP-1 LISP software Ethan Dicks PDP-11 2.9 BSD debugging -John Dundas PDP-11 CPU and clock debugging +John Dundas PDP-11 CPU debugging, programmable clock simulator Jonathan Engdahl PDP-11 device debugging Carl Friend Nova and Interdata documentation, and RDOS software -Megan Gentry PDP-11 integer debugging, make file -Dave Gesswein PDP-8 and PDP-9.15 documentation, PDP-8 DECtape and - paper tape images, PDP-9/15 DECtape images +Megan Gentry PDP-11 integer debugging +Dave Gesswein PDP-8 and PDP-9.15 documentation, PDP-8 DECtape, disk, + and paper tape images, PDP-9/15 DECtape images Dick Greeley PDP-8 OS/8 and PDP-10 TOPS-10/20 legal permissions Gordon Greene PDP-1 LISP machine readable source Lynne Grettum PDP-11 RT-11, RSTS/E, RSX-11M legal permissions @@ -1126,14 +1183,14 @@ Ken Harrenstein KLH PDP-10 simulator Bill Haygood PDP-8 information, simulator, and software Wolfgang Helbig DZ11 implementation Mark Hittinger PDP-10 debugging -Dave Hittner SCP debugging, Ethernet emulation +Dave Hittner SCP debugging, DEQNA emulator and Ethernet library Sellam Ismail GRI-909 documentation -Jay Jaeger IBM 1401 information +Jay Jaeger IBM 1401 consulting Doug Jones PDP-8 information, simulator, and software -Brian Knittel IBM 1130 simulator +Brian Knittel IBM 1130 simulator, SCP extensions for GUI support Al Kossow HP 21xx, Varian 620, TI 990, Interdata, DEC documentation and software -Arthur Krewat DZ11 update for the PDP-10 +Arthur Krewat DZ11 changes for the PDP-10 Mirian Crzig Lennox ITS and DZ11 debugging Don Lewine Nova documentation and legal permissions Tim Litt PDP-10 hardware documentation and schematics, @@ -1151,8 +1208,9 @@ Charles Owen Nova moving head disk debugging, Altair simulator, Sergio Pedraja MINGW environment debugging Derek Peschel PDP-10 debugging Paul Pierce IBM 1401 diagnostics, media recovery -Mark Pizzolato VAX simulator improvements -Hans Pufal PDP-10 debugging, PDP-15 bootstrap +Mark Pizzolato SCP, Ethernet, and VAX simulator improvements +Hans Pufal PDP-10 debugging, PDP-15 bootstrap, DOS-15 recovery, + DOS-15 documentation, PDP-9 restoration Bruce Ray Software, documentation, bug fixes, and new devices for the Nova, OS/2 porting Craig St Clair DEC documentation @@ -1163,7 +1221,7 @@ Olaf Seibert NetBSD port testing Brian & Barry Silverman PDP-1 simulator and software Tim Shoppa Nova documentation, RDOS software, PDP-10 and PDP-11 software archive, hosting for SIMH site -Van Snyder IBM 1401 bootstraps +Van Snyder IBM 1401 zero footprint bootstraps Michael Somos PDP-1 debugging Hans-Michael Stahl OS/2 port testing, TERMIOS implementation Tim Stark TS10 PDP-10 simulator @@ -1171,11 +1229,14 @@ Larry Stewart Initial suggestion for the project Bill Strecker Permission to revert copyrights Chris Suddick PDP-11 floating point debugging Ben Supnik Macintosh timing routine +Bob Supnik SIMH simulators Ben Thomas VMS character-by-character I/O routines Warren Toomey PDP-11 UNIX software Deb Toivonen DEC documentation Mike Umbricht DEC documentation, H316 documentation and schematics Leendert Van Doorn PDP-11 UNIX V6 debugging, TERMIOS implementation +Fred Van Kempen Ethernet code, RK611 emulator, PDP-11 debugging, + VAX/Ultrix debugging Holger Veit OS/2 socket support David Waks PDP-8 ESI-X and PDP-7 SIM8 software Tom West Nova documentation @@ -1192,4 +1253,6 @@ Compaq Computer Corporation Mentec Corporation The Santa Cruz Operation Caldera Corporation +Hewlett-Packard Corporation + diff --git a/simh_faq.txt b/simh_faq.txt new file mode 100644 index 00000000..70f4c8f2 --- /dev/null +++ b/simh_faq.txt @@ -0,0 +1,603 @@ +SIMH FAQ, 15-Apr-2003 + +1 General + +1.1 What is SIMH? +1.2 Why was SIMH written? +1.3 What is the history of SIMH? +1.4 Who writes and maintains SIMH? +1.5 How is SIMH licensed? +1.6 How is SIMH distributed? +1.7 Which computer systems can SIMH simulate? +1.8 Which host systems does SIMH run on? +1.9 What software packages are available for use with the SIMH simulators? +1.10 Where can I get more information about SIMH? + +-------------------------------------------------------------------------------- + +2 Operational + +2.1 How do I install SIMH on Windows? +2.2 How do I install SIMH with Ethernet support on Windows? +2.3 How do I install SIMH on Unix? +2.4 How do I install SIMH on VMS? +2.5 How do I transcribe a real CD for use with SIMH? +2.6 How do I transcribe other archival media for use with SIMH? +2.7 How can I get text files in and out of SIMH? +2.8 How can I get binary files in and out of SIMH? +2.9 Can I connect real devices on the host computer to SIMH? +2.10 My Windows host can't communicate with the PDP-11 or VAX over Ethernet; why? + +-------------------------------------------------------------------------------- + +3 Writing and Debugging New Code + +3.1 What resources are available for writing new simulators? +3.2 What debugging facilities are available in SIMH? +3.3 When do I need to use the host debugger for debugging a simulator? +3.4 What is the release process for SIMH? + +-------------------------------------------------------------------------------- + +4 VAX + +4.1 Where can I get software and hobbyist licenses for the VAX? +4.2 How do I install VMS? +4.3 How do I install NetBSD? +4.4 How do I install Ultrix? +4.5 What's the CPU serial number for my hobbyist license PAK? +4.6 How do I change the simulator from a VAXserver 3900 to a + MicroVAX 3900? +4.7 Is there an example of the simulator running VMS? +4.8 How can I import files into a simulated VMS environment? +4.9 How can I export files from a simulated VMS environment? + +================================================================================ +1. General Questions +================================================================================ + +1.1 What is SIMH? + +SIMH is the Computer History Simulation system. It consists of simulators +for approximately 20 different computers, all written around a common user +interface package and set of supporting libraries. SIMH can be used to +simulate any computer system for which sufficient detail is available, but +the focus to date has been on simulating computer systems of historic interest. + +-------------------------------------------------------------------------------- + +1.2 Why was SIMH written? + +Significant portions of the computing past are being irretrievably lost, as +old systems are scrapped, documentation and software is thrown out, media +become obsolete or unreadable, and inventors and pioneers die. SIMH was +written as a vehicle to allow the computing past to be made accessible to +a wider audience, for recreational and educational purposes. SIMH preserves +historic computers as portable software, that can be run on any modern +system. SIMH also preserves representative software packages for these +systems. With SIMH, anyone with a desktop computer can call up and run +significant samples from the computing past, at any time. + +-------------------------------------------------------------------------------- + +1.3 What is the history of SIMH? + +The SIMH project started in 1993, at the suggestion of Larry Stewart of DEC. +Its immediate purpose was to preserve the fading hardware and software +record of early minicomputers. Since then, the project has been expanded +to include other important systems, spanning the history of computing from +the late 50's to the late 80's. + +SIMH's core design is based on an earlier simulation system called MIMIC. +MIMIC was written in the late 1960's at Applied Data Research, by Mike +McCarthy, Len Feshkens, and Bob Supnik. MIMIC was a mini-computer simulator +that ran on the PDP-10. Its purpose was to facilitate the development and +debugging of real-time embedded systems by using the the PDP-10 timesharing +environment for program development, instead of the limited facilities of +the native minicomputer environments. Ironically, given SIMH's mission to +preserve the computing record, all machine-readable copies of MIMIC have +been lost. + +-------------------------------------------------------------------------------- + +1.4 Who writes and maintains SIMH? + +Many people have contributed, and continue to contribute, to SIMH. The full +list of contributors can be found on the SIMH web site. Bob Supnik coordinates +SIMH development. + +-------------------------------------------------------------------------------- + +1.5 How is SIMH licensed? + +SIMH is licensed under a modified X-Windows license. This license allows more +or less unrestricted use of the sources and binaries. The license is included +with the documentation and is also included in every source module. The +software packages are available under various terms and conditions; see the +documentation included with each software package. + +-------------------------------------------------------------------------------- + +1.6 How is SIMH distributed? + +SIMH is distributed in source form from the SIMH web site, in the form of a +Zip archive. For Windows users, pre-compiled binaries are also available. + +-------------------------------------------------------------------------------- + +1.7 Which computer systems does SIMH simulate? + +SIMH simulates the following computer systems: + + Manufacturer Model + + Digital Equipment Corporation PDP-1, PDP-4, PDP-7, PDP-8, PDP-9, + PDP-10, PDP-11, PDP-15, VAX + Data General Corporation Nova, Eclipse + IBM Corporation 1130, 1401, 1620, System 3 + GRI Corporation GRI-909 + Honeywell Corporation H316/516 + Hewlett Packard Corporation HP2116, HP2100, HP21MX + Interdata Corporation 16b systems, 7/32, 8/32 + Scientific Data Systems SDS-940 + MITS Altair 8080, Altair Z80 + +The documentation contains more details on supported models and peripherals. + +-------------------------------------------------------------------------------- + +1.8 Which host systems does SIMH run on? + + Host System Compiler comments + + OpenVMS/VAX DEC C no 64b support; no Ethernet support + OpenVMS/Alpha DEC C no Ethernet support + + Windows 9x or Mingw/gcc or requires WinPcap for Ethernet support + Windows 2000 or Visual C++ or + Windows XP Borland C++ + + Mac OS/X no Ethernet support + + Linux gcc + Tru64 UNIX DEC C no Ethernet support + AIX no Ethernet support + Solaris no Ethernet support + HP/UX no Ethernet support + NetBSD gcc + OpenBSD gcc + FreeBSD gcc no Ethernet support + + OS/2 EMX no Ethernet support + +-------------------------------------------------------------------------------- + +1.9 What software packages are available to run on SIMH? + +The list of available software packages can be found on the SIMH web site. + +-------------------------------------------------------------------------------- + +1.10 Where can I get more information on SIMH? + +The SIMH web site is http://simh.trailing-edge.com. + +================================================================================ +2 Operational Questions +================================================================================ + +2.1 How do I install SIMH on Windows? + +The simplest way is to download the pre-compiled binaries. Unzip these into the +directory where you want to run SIMH. You can then run whichever binary that you +want. + +If you want to run the VAX emulator, you will also need the KA655.bin file from +the source kit. + +-------------------------------------------------------------------------------- + +2.2 How do I install SIMH with Ethernet support on Windows? + +First, you must download download and install the WinPCAP AutoInstaller and +developer's kit from + + http://winpcap.polito.it + +This creates a network packet driver in Windows for SIMH to attach to. + +Second, you must download the Gnu C compiler. You can get a Windows compatible +GNU C compiler from: + + http://www.mingw.org + +Third, place the include (.h) files from the developer's kit in the C +compiler's include folder, and the libraries from the developer's kit in C +compiler's library folder. + +Then, the batch file build_mingw_ether.bat can be used to build all the +simulators, with Ethernet suport where appropriate. + +To use network support, you must either be an administrator on the Windows +machine (implied in Windows 9X), or you must set the windows packet driver to +autostart when the system boots; see the WinPCAP FAQ page for detailed +information on how to do this. + +-------------------------------------------------------------------------------- + +2.3 How do I install SIMH on Unix? + +- Unzip the archive of sources to a new directory. You must specify the + -a switch to unzip for proper conversion of Windows cr-lf sequences + to UNIX newline sequences. + +- If your system supports gmake, you can compile the simulators with + the command: + + % gmake all + +- If you want Ethernet support in the PDP-11 and VAX, you should compile + the simulators with the command: + + % gmake USE_NETWORK=1 all + + Note that Ethernet support is available ONLY on Linux, NetBSD, and + OpenBSD. + +-------------------------------------------------------------------------------- + +2.4 How do I install SIMH on VMS? + +Download the SIMH source kit, and UNZIP it using the /TEXT=AUTO qualifier to +the directory that you want SIMH to reside in. Use MMK or MMS and the +descrip.mms file to build the binaries. + +UNZIP can be found on the VMS freeware CDs, or from www.info-zip.org +MMK can be found on the VMS freeware CDs, or from www.madgoat.com +MMS can be licensed from HP/Compaq/Digital. + +Note that the VAX and PDP-10 emulators cannot be built and used on VAX/VMS, +since the DEC C compiler for that operating system does not support 64-bit +integers. DEC C on Alpha VMS has the required 64-bit capability to build +and run all of the emulators. + +-------------------------------------------------------------------------------- + +2.5 How do I transcribe a real CD for use with SIMH? + +- On UNIX, you can copy a CD to an ISO file with the dd command: + + % dd /if=/dev/raw_cd_device /out=/path/cdimage.iso + + Linux, and many Unix variants, support direct access to the CD ROM + from SIMH: + + sim> set rq1 cdrom + sim> att rq1 /dev/cdrom_drive + +- On Windows, there a quite a few products that can do this. The two most + common products are detailed below. Make sure to disable any antivirus + software before proceeding. Antivirus software tends to interfere with + the smooth flow of data from the CD, and will occasionally transform the + data in strange and unexpected ways to 'protect' you. + + 1) Roxio EZ-CD Creator 5.x + Go to the the Disc menu and select Disc Info (there will be a delay). + Select the track shown, then click the Read Track button. + Enter the Save file name, then OK. + + 2) Nero 5.5 + Select Recorder|Save Track + Select the track, set the output filename + In Options, you may need to set the Read Speed down; + the VMS Hobbyist CD didn't work after a 52x read, but worked fine at 8x + Click GO + +-------------------------------------------------------------------------------- + +2.6 How do I transcribe other archival media for use with SIMH? + +You must have access to a real system that can read the media to be +transcribed (e.g., a system with a working DECtape drive to read a +DECtape). Most systems have utilities to copy raw data to a disk +file; that file can then be transferred over the console serial +line to a system with an Internet link. Utility programs are +available to convert raw data streams to SIMH format. + +-------------------------------------------------------------------------------- + +2.7 How can I get text files in and out of SIMH? + +Since SIMH supports the universal serial interface using TELNET, text can +be transferred using one of the serial line transfer protocols (X/Y/Zmodem, +Kermit) or using standard cut and paste techniques, if the host's TELNET +program supports it. + +To use the TELNET feature, connect to the SIMH machine using TELNET, and +set the target environment into a 'receive' mode. This is usually something +like running a text editor. Then tell the TELNET program to 'send', 'transfer', +or 'paste' the text that you want sent into the SIMH system. + +To get text out of the system, have the TELNET program either log the output, +or if the TELNET program supports a backscroll region you can use that. Tell +the SIMH system to 'type' or 'cat' the text file, sending the output to the +TELNET device, where you can edit it into a text file. + +Many TELNET programs also support transferring large files via X/Y/ZModem or +Kermit, which you can use as long as the SIMH system has the appropriate +matching program. + +C-Kermit from Columbia University (http://www.columbia.edu/kermit) is probably +the most universal way to transfer files in and out of SIMH systems. + +If the SIMH system supports Ethernet connectivity (PDP-11, VAX), you can also +use the various network copy programs (FTP, DECNET) to transfer files. + +Finally, you can "print" text files to the simulated line printer. Printer +output is automatically formatted as an ASCII text file. + +-------------------------------------------------------------------------------- + +2.8 How can I get binary files in and out of SIMH? + +Since SIMH supports the universal serial interface using TELNET, binary +files can be transferred using one of the serial line transfer protocols +(X/Y/ZModem, Kermit) or by converting the binary to a text-encoded file +(HEXify, UUENCODE, VMShare, etc.) and transferred in text mode (see section +2.7). + +Many TELNET programs also support transferring large files via X/Y/ZModem or +Kermit, which you can use as long as the SIMH system has the appropriate +matching program. + +C-Kermit from Columbia University (http://www.columbia.edu/kermit) is probably +the most universal way to transfer files in and out of SIMH systems. + +If the SIMH system supports Ethernet connectivity (PDP-11, VAX), you can also +use the various network copy programs (FTP, DECNET) to transfer files. + +-------------------------------------------------------------------------------- + +2.9 Can I connect real devices on the host computer to SIMH? + +No. + +-------------------------------------------------------------------------------- + +2.10 My Windows host can't communicate with the PDP-11 or VAX over Ethernet; why? + +Due to the inherent limitations of WinPCAP, the SIMH system _CANNOT_ communicate +with the host on the primary interface. To establish communications between SIMH +and a PC host, add a second Ethernet controller, attach both controllers to the +same hub, and attach SIMH to the second controller. The host and SIMH will now +be able to communicate across the physical network connection. + +================================================================================ +3 Writing and Debugging New Code +================================================================================ + +3.1 What resources are available for writing new simulators? + +The SIMH web site contains documentation on the internals of SIMH, as well +as specific help for writing new peripherals for several of the popular +simulators. + +-------------------------------------------------------------------------------- + +3.2 What debugging facilities are available in SIMH? + +Most simulators provide the following debugging capabilities: + +- Symbolic assembly and disassembly of memory contents. +- Numeric examination and modification of the data store of any simulated + device. +- Numeric search on both memory and device data. +- Visibility to simulator internal structures, such as the event queue. +- An unlimited number of instruction breakpoints. +- Proceed counts on breakpoints. +- Automatic execution of simulator commands on a breakpoint. +- Stepped execution (from single step to 'n' steps). +- A PC change queue, usually 64 instructions deep. + +Specific simulators may provide additional features, such as an instruction +history buffer, CPU and/or device logging, and breakpoints on memory reads +and writes. + +-------------------------------------------------------------------------------- + +3.3 When do I need to use the host debugger for debugging a simulator? + +While a simulator is being debugged, its execution of instructions +or debugging support code may be unreliable. During this process, +the programmer may need to use the host debugger to stop in the +middle of an instruction execution, or to trap an error condition. +Host debugger breakpoints should be invisible to the simulator; with +the exception of clock calibration, all simulator events are driven +off the event queue rather than real-world events. + +If the programmer needs to force a simulator stop from the host +debugger, most simulators provide an "address stop" global variable. +Setting this variable to 1 will cause the simulator to stop after +completing the current instruction. + +-------------------------------------------------------------------------------- + +3.4 What is the release process for SIMH? + +SIMH is released whenever a significant number of new features, or +important bug fixes, has accumulated. This has averaged every 4-8 +weeks. The major version number has not been changed since the +addition of symbolic debugging and won't be changed unless the +internals of SCP change dramatically. The minor version number +is changed when the format of the save/restore file must be updated. + +================================================================================ +4 VAX +================================================================================ + +4.1 Where can I get software and hobbyist licenses for the VAX? + +HP (formerly Compaq formerly DEC) provides licenses to OpenVMS for +hobbyist use. A description of the hobbyist license program can be +found on http://www.montagar.com/hobbyist/. + +-------------------------------------------------------------------------------- + +4.2 How do I install VMS? + +To install VMS, you will need a distribution CD ROM. Any version +after VMS 5.5-2 should run on the simulator. + +- Transcribe the distribution CD ROM to an ISO-format CD image file. + (See question 2.5 for information on how to do this.) +- Set drive RQ1 to be a CD ROM. +- Attach the CD ROM image file to simulated drive RQ1. +- Set drive RQ0 to be the type of disk you want. Be sure that the + disk is large enough to hold VMS. +- Attach a blank disk image file to simulated drive RQ0. +- Boot the CPU. +- When the self-test code completes, boot the CD ROM. +- Use standalone backup to restore the CD ROM contents to the simulated + disk. + + sim> set rq0 rd54 + sim> set rq1 cdrom + sim> att rq0 new_vms.dsk + sim> att rq1 cd_rom_image.iso + sim> boot cpu + : + >>> boot rq1 + + $ (prompt from standalone backup) + +A writeup on the procedure can be found on the VMS hobbyist site. + +-------------------------------------------------------------------------------- + +4.3 How do I install NetBSD? + +Directions for installing NetBSD on the NetBSD web site, at +http://www.netbsd.org/Ports/vax/emulator-howto.html. + +-------------------------------------------------------------------------------- + +4.4 How do I install Ultrix? + +Ultrix is not presently licensed for hobbyist use. If you have a +valid license for Ultrix, and distribution tapes for a version that +supports the MicroVAX 3900 series (V4 or later), then you should +be able to install Ultrix on the simulator. + +- Transcribe the distribution tapes to SIMH-format tape image files. + (See question 2.6 for information on how to do this.) +- Mount the installation tape image on simulated drive TQ0. +- Set drive RQ0 to be the type of disk you want. Be sure that the + disk is large enough to hold Ultrix. +- Mount a blank disk image file on simulated drive RQ0. +- Boot the CPU. +- When the self-test code completes, boot the installation tape. +- The installation tape will guide you through the installation of + Ultrix. + + sim> set rq0 rd54 + sim> att rq0 new_vms.dsk + sim> att tq0 ultrix_install.tap + sim> boot cpu + : + >>> boot mua0 + + (Ultrix installation dialog) + +--------------------------------------------------------------------------------- + +4.5 What's the CPU serial number for my hobbyist license PAK? + +On a MicroVAX 3900, the CPU serial number is not readable and can +be an arbitrary value. 12345 will work fine. + +--------------------------------------------------------------------------------- + +4.6 How do I change the simulator from a VAXserver 3900 to a MicroVAX 3900? + +The system type is controlled by a "magic byte" in the CPU's boot ROM. +By default, the system type is a VAXserver 3900. To change the type +to a MicroVAX 3900, patch the boot ROM as follows: + + sim> set ptr ena + sim> att ptr ka655.bin + sim> ie ptr 4 + 4: 2 1 + sim> det ptr + +and reboot the simulated VAX. + +--------------------------------------------------------------------------------- + +4.7 Is there an example of the simulator running VMS? + +This example assumes you are trying to emulate a MicroVAX 3900 with 64MB of +memory, with a single 1GB disk drive, a CDROM, and an Ethernet controller. + +The host OS is Windows NT/2000/XP, and you have previously dumped the contents +of the VMS Hobbyist CD to a disk file as detailed in 2.5, and have loaded +WinPCAP on the system for Ethernet support. Other host OS's will look +similar but will have different file name syntax. + +c:\simh> vax ; run VAX emulator +sim> set cpu 64m ; set memory size to 64MB +sim> load -r vax\ka655.bin ; load the MicroVAX 3900 console ROM +sim> attach NVR vax\ka655.nvr ; create/load a Non-Volatile RAM file +sim> set LPT disable ; disable devices we don't want/need +sim> set TQ disable ; " +sim> set rq0 ra90 ; set disk 0 to 1GB (RA90 size) +sim> attach rq0 vax\vaxsys.dsk ; create/use disk file +sim> set rq1 rrd40 ; set disk 1 as a cdrom +sim> attach -r rq1 vax\hobbyist.dsk ; attach cdrom dump file as read-only +sim> set rq2 offline ; turn off disk rq2 +sim> set rq3 offline ; turn off disk rq3 +sim> attach xq eth0 ; attach to host ethernet controller +sim> b cpu ; start (boot) VAX console + +KA655-B V5.3, VMB 2.7 + 1) Dansk ; will not appear if the controlling + .. ; keyboard doesn't support multi- +15) Svenska ; national characters! + (1..15): 5 +Performing normal system tests. +40..39..38..37..36..35..34..33..32..31..30..29..28..27..26..25.. +24..23..22..21..20..19..18..17..16..15..14..13..12..11..10..9.. +8..7..6..5..4..3.. +Tests completed. +>>> show device ; tell console to show all devices +UQSSP Disk Controller 0 (772150) +-DUA0 (RA90) +-DUA1 (RRD40) + +Ethernet Adapter 0 (774440) +-XQA0 (08-00-2B-AA-BB-CC) +>>> b dua1 ; tell console to boot cdrom +(BOOT/R5:1 DUA1) + +2..1..0 + +--------------------------------------------------------------------------------- + +4.8 How can I import files to a simulated VMS environment? + +- Use a CD burner program, like Easy CD Creator or Nero, to create an ISO 9660 + CD image containing the files you want to import. Note that file names are + limite to DOS '8.3' conventions. +- Attach the simulated CD image to a simulated CD drive. +- Mount the simulated CD as an ISO 9660 file system under VMS. +- Copy the files you need from the simulated CD to the simulated disk. + +(Thanks to Tim Stark for this suggestion.) + +--------------------------------------------------------------------------------- + +4.9 How can I export files from a simulated VMS environment? + +- Utility ODS2 (available on the Web) can read an ODS-2 disk image and copy files + from that image to the host file system. +- Text files can be printed to the simulated line printer, as described above. + diff --git a/simh_swre.txt b/simh_swre.txt index 55698325..d2b025e9 100644 --- a/simh_swre.txt +++ b/simh_swre.txt @@ -1,7 +1,7 @@ To: Users From: Bob Supnik Subj: Sample Software Packages -Date: 15-Feb-2003 +Date: 15-Jun-2003 This memorandum documents the sample software packages available to run with the SIMH simulators. Many of these packages are available under @@ -99,8 +99,8 @@ the disk image and the initialization tape source. Loading TSS/8 ------------- -Note: your environment must have a functioning second Teletype; that is, you cannot -at present run Foreground/Background if your host system does not support the SIMH +Note: your environment must have a functioning second Teletype; that is, you +cannot at present run TSS if your host system does not support the SIMH sockets library. - Load the paper-tape bootstrap: @@ -427,7 +427,8 @@ does not support the SIMH sockets library. sim> run -- The DECtape will boot and print out +- The DECtape will boot, and the Foreground/Background Monitor will print + on the second terminal F9/15 V4A $ @@ -449,11 +450,11 @@ does not support the SIMH sockets library. B9/15 V4A $ - and is now ready for commands. + and is now ready for commands. 6.4 DOS-15 -DOS-15 was a more polished version of ADSS-15 using the RF15 or RP15 +DOS-15 is a more polished version of ADSS-15 using the RF15 or RP15 as its system device. To load and run DOS-15: - Load the DOS-15 paper tape bootstrap into upper memory: @@ -470,8 +471,8 @@ as its system device. To load and run DOS-15: - The RF disk will boot and print out -DOS-15 V2A - ENTER DATE (MM/DD/YY) - + DOS-15 V2A + ENTER DATE (MM/DD/YY) - Enter the date (the year must be between 70 and 99). DOS-15 will print its prompt and is now ready for commands. Recognized commands