diff --git a/Makefile b/Makefile index b72606ee..32f65ab8 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 489 2013-02-17 10:58:02Z mueller $ +# $Id: Makefile 513 2013-05-01 14:02:06Z mueller $ # # 'Meta Makefile' for whole retro project # allows to make all synthesis targets @@ -6,6 +6,7 @@ # # Revision History: # Date Rev Version Comment +# 2013-05-01 513 1.0.6 add clean_sim_tmp and clean_syn_tmp targets # 2012-12-29 466 1.0.5 add tst_rlink_cuff # 2011-12-26 445 1.0.4 add tst_fx2loop # 2011-12-23 444 1.0.3 enforce -j 1 in sub-makes @@ -15,6 +16,8 @@ # SYN_all += rtl/sys_gen/tst_fx2loop/nexys2/ic SYN_all += rtl/sys_gen/tst_fx2loop/nexys2/ic3 +SYN_all += rtl/sys_gen/tst_fx2loop/nexys3/ic +SYN_all += rtl/sys_gen/tst_fx2loop/nexys3/ic3 SYN_all += rtl/sys_gen/tst_rlink/nexys2 SYN_all += rtl/sys_gen/tst_rlink/nexys3 SYN_all += rtl/sys_gen/tst_rlink/s3board @@ -38,6 +41,7 @@ SIM_all += rtl/sys_gen/tst_rlink/nexys2/tb SIM_all += rtl/sys_gen/tst_rlink/nexys3/tb SIM_all += rtl/sys_gen/tst_rlink/s3board/tb SIM_all += rtl/sys_gen/tst_rlink_cuff/nexys2/ic/tb +SIM_all += rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb SIM_all += rtl/sys_gen/tst_serloop/nexys2/tb SIM_all += rtl/sys_gen/tst_serloop/nexys3/tb SIM_all += rtl/sys_gen/tst_serloop/s3board/tb @@ -48,7 +52,8 @@ SIM_all += rtl/vlib/rlink/tb SIM_all += rtl/vlib/serport/tb SIM_all += rtl/w11a/tb # -.PHONY : all clean clean_sim clean_sym all_sim all_syn +.PHONY : all all_sim all_syn +.PHONY : clean clean_sim clean_sim_tmp clean_sym clean_sym_tmp .PHONY : $(SYN_all) $(SIM_all) # all : @@ -59,6 +64,8 @@ all : @echo " make clean" @echo " make clean_sim" @echo " make clean_syn" + @echo " make clean_sim_tmp" + @echo " make clean_syn_tmp" @echo " for tool/documentation generation use:" @echo " make -j 4 all_lib" @echo " make clean_lib" @@ -73,6 +80,11 @@ clean_sim : clean_syn : for dir in $(SYN_all); do $(MAKE) -C $$dir clean; done # +clean_sim_tmp : + for dir in $(SIM_all); do $(MAKE) -C $$dir ghdl_tmp_clean; done +clean_syn_tmp : + for dir in $(SYN_all); do $(MAKE) -C $$dir ise_tmp_clean; done +# all_sim : $(SIM_all) # all_syn : $(SYN_all) diff --git a/doc/INSTALL.txt b/doc/INSTALL.txt index ac733313..e52fc59c 100644 --- a/doc/INSTALL.txt +++ b/doc/INSTALL.txt @@ -1,4 +1,4 @@ -# $Id: INSTALL.txt 511 2013-04-27 13:51:46Z mueller $ +# $Id: INSTALL.txt 512 2013-04-28 07:44:02Z mueller $ Guide to install and build w11a systems, test benches and support software @@ -374,6 +374,11 @@ Guide to install and build w11a systems, test benches and support software cd $RETROBASE/rtl/sys_gen/tst_rlink_cuff/nexys2/ic make sys_tst_rlink_cuff_ic_n2.bit + b. for Digilent Nexys3 board + + cd $RETROBASE/rtl/sys_gen/tst_rlink_cuff/nexys3/ic + make sys_tst_rlink_cuff_ic_n3.bit + 3. w11a systems a. for Digilent S3BOARD diff --git a/doc/README.txt b/doc/README.txt index b082f91e..729074cc 100644 --- a/doc/README.txt +++ b/doc/README.txt @@ -1,4 +1,4 @@ -# $Id: README.txt 511 2013-04-27 13:51:46Z mueller $ +# $Id: README.txt 518 2013-05-12 16:45:02Z mueller $ Release notes for w11a @@ -35,7 +35,7 @@ Release notes for w11a rtl/ibus - ibus devices (UNIBUS peripherals) rtl/sys_gen - top level designs rtl/sys_gen/tst_fx2loop - top level designs for Cypress FX2 tester - nexys2 - systems for Nexsy2 + nexys2,nexys3 - systems for Nexsy2,Nexsy3 rtl/sys_gen/tst_rlink - top level designs for an rlink tester nexys2,nexys3,s3board - systems for Nexsy2,Nexsy3,S3BOARD rtl/sys_gen/tst_rlink_cuff - top level designs for rlink over FX2 tester @@ -67,6 +67,8 @@ Release notes for w11a tools/fx2/bin - pre-build firmware images in .ihx format tools/fx2/src - C and asm sources tools/fx2/sys - udev rules for USB on fpga eval boards + tools/oskit - setup files for Operation System kits + tools/oskit/... - several PDP-11 system kits available tools/src - C++ sources for rlink backend software tools/src/librlink - basic rlink interface tools/src/librlinktpp - C++ to tcl binding for rlink interface @@ -80,6 +82,39 @@ Release notes for w11a 3. Change Log ---------------------------------------------------------------- +- trunk (2013-05-12: svn rev 21(oc) 518(wfjm); untagged w11a_V0.58) +++++++++ + + - Summary + - C++ and Tcl based backend server now fully functional, supports with + DL11, RK11, LP11 and PC11 all devices available in w11a designs + - the old perl based backend server (pi_rri) is obsolete and removed + - operating system kits reorganized + + - New features + - new directory trees for + - tools/oskit - operating system kits + - new modules + - tools/src/librw11 + - Rw11*LP11 - classes for LP11 printer handling + - Rw11*PC11 - classes for PC11 paper tape handling + - Rw11*Stream* - classes for Virtual stream handling + - tools/src/librwxxtpp + - RtclRw11*LP11 - tcl iface for LP11 printer handling + - RtclRw11*PC11 - tcl iface for PC11 paper tape handling + - RtclRw11*Stream* - tcl iface for Virtual Stream handling + + - Changes + - renames + - the w11 backend quick starter now named ti_w11 and under tools/bin + (was rtl/sys_gen/w11a/tb/torri) + - all operating system image related material now under + tools/oskit (was under rtl/sys_gen/w11a/tb) + + - Bug fixes + - rtl/ibus/ibdr_lp11 - err flag logic fixed, was cleared in ibus racc read + - rtl/ibus/ibdr_pc11 - rbuf logic fixed. Was broken since ibus V2 update + in V0.51! Went untested because pc11 rarely used. + - trunk (2013-04-27: svn rev 20(oc) 511(wfjm); untagged w11a_V0.57) +++++++++ - Summary diff --git a/doc/w11a_known_issues.txt b/doc/w11a_known_issues.txt index f739098d..27843d67 100644 --- a/doc/w11a_known_issues.txt +++ b/doc/w11a_known_issues.txt @@ -1,4 +1,4 @@ -# $Id: w11a_known_issues.txt 317 2010-07-22 19:36:56Z mueller $ +# $Id: w11a_known_issues.txt 516 2013-05-05 21:24:52Z mueller $ Summary of known issues for w11a CPU and systems @@ -34,7 +34,7 @@ Summary of known issues for w11a CPU and systems device would see it. The w11a doesn't implement this remapping, an access in the range 17000000:17757777 causes a NXM fault. - All four points relate to very 11/70 specific behaviour, not operating system + All four points relate to very 11/70 specific behaviour, no operating system depends on them, therefore they are considered acceptable implementation differences diff --git a/doc/w11a_os_guide.txt b/doc/w11a_os_guide.txt index 397339ba..0e255ad5 100644 --- a/doc/w11a_os_guide.txt +++ b/doc/w11a_os_guide.txt @@ -1,14 +1,16 @@ -# $Id: w11a_os_guide.txt 511 2013-04-27 13:51:46Z mueller $ +# $Id: w11a_os_guide.txt 518 2013-05-12 16:45:02Z mueller $ Guide to run operating system images on w11a systems Table of content: - 1. I/O emulation setup - 2. FPGA Board setup - 3. Unix V5 system - 4. 2.11BSD system - + 1. I/O emulation setup + 2. FPGA Board setup + 3. Rlink and Backend Server setup + 4. simh simulator setup + 5. oskits + a. Unix systems + b. DEC operating systems 1. I/O emulation setup ---------------------------------------------------- @@ -16,6 +18,11 @@ Guide to run operating system images on w11a systems are currently emulated via a backend process. The communication between FPGA board and backend server can be via + - Direct USB connection using a Cypress FX2 USB controller + - is supported on the nexys2 and nexys3 FPGA boards + - much faster than serial port connections (see below) + - also allows to configure the FPGA over the same USB connection + - Serial port - via direct (/dev/ttySx) or via a USB-RS232 adapter. A direct connection is limited to 115k Baud on most PCs, while a connection via a USB-RS232 @@ -24,208 +31,164 @@ Guide to run operating system images on w11a systems - via integrated USB-RS232 adapter, like on nexys3 board. This is much faster, allows bitrates up to 2 M Baud. - Notes: - A USB-RS232 cable with a Prolific Technology PL2303 chip simply + Notes: - A USB-RS232 cable with a FTDI FT232R chip, like the cable offered + by FTDI as US232R-100 works fine. + - A USB-RS232 cable with a Prolific Technology PL2303 chip simply never gave reliable connections for higher Baud rates. - - A USB-RS232 cable with a FTDI FT232R chip, like the cable offered - by FTDI as US232R-100 worked fine. - - On older linux kernels (prior 2.6.32) it is essential to set the - latency timer for the FTDI USB-RS232 cable to 1 ms (from the - power up default of 16 ms), e.g. with - sudo $RETROBASE/tools/bin/set_ftdi_lat USB0 1 - For linux kernel 2.6.32 or newer the default is 1 ms already. - The rest assumes that a USB-RS232 cable with FTDI chip is used - A 460k Baud connection gives in practice a disk throughput of about 20 kB/s. This allows to test the system but is a bit slow to real usage. In an OS with good disk caching like 2.11BSD the impact of such a 'slow disk' is actually smaller than the bare numbers suggest. - - - Direct USB connection using a Cypress FX2 USB controller - - is supported on the nexys2 and nexys3 FPGA boards - - clearly much faster than serial port connections - - also allows to configure the FPGA over the same USB connection + - On older linux kernels (prior 2.6.32) it is essential to set the + latency timer for the FTDI USB-RS232 cable to 1 ms (from the + power up default of 16 ms), e.g. with + sudo $RETROBASE/tools/bin/set_ftdi_lat USB0 1 + For linux kernel 2.6.32 or newer the default is 1 ms already. 2. FPGA Board setup ------------------------------------------------------- - - Using serial port - - for s3board and nexys2 - - connect the USB-RS232 cable to the RS232 port of the s3board or nexys2 - - for kernel < 2.6.32: set the latency timer of the USB-RS232, e.g. with - sudo $RETROBASE/tools/bin/set_ftdi_lat USB0 1 - - ensure that all 8 switches are in the indicated positions (SWI=...) - - load the w11a design into the FPGA, e.g. via impact - - for nexys3 - - connect USB cable to the 'usb uart' port (next to the 5 buttons) - - ensure that all 8 switches are in the indicated positions (SWI=...) - - load the w11a design into the FPGA, e.g. via impact - - - Using Cypress FX2 USB controller + - Using Cypress FX2 USB controller for configuration and rlink communication - for nexys2 - connect USB cable to mini-USB connector (between RS232 and PS/2 port) - ! Must be connected to a USB port able to deliver 500 mA ! + - for nexys3 + - connect USB cable to micro-USB connector labeled 'USB PROG' -3. Unix V5 system --------------------------------------------------------- + - Using serial port for rlink communication + - for s3board and nexys2 + - connect the USB-RS232 cable to the RS232 port + - for nexys3 + - connect USB cable to the micro-USB connector 'UART' + (next to the 5 buttons) + - connect a JTAG programmer (e.g. Xilinx USB Cable II) to JTAG pins - - A disk set is available from - http://www.retro11.de/data/oc_w11/unix_v5_rkset.tgz - Download, unpack and copy the disk images (*.dsk) to - $RETROBASE/rtl/sys_gen/w11a/tb + - Configure the FPGA + - if Cypress FX2 port is connected load design with + make .jconfig + - otherwise use impact with + make .iconfig - - Using old (pi_rri) backend server (serial port only) +3. Rlink and Backend Server setup ----------------------------------------- - cd $RETROBASE/rtl/sys_gen/w11a/tb - telnet_starter -d DL0 & + All examples below use the same basic setup - [for s3,n2:] - SWI = 00000010 - dorri -u0,460,1,2 @uv5_boot.pcmd - [for n3:] - SWI = 00000010 - dorri -u0,2000,1,2 @uv5_boot.pcmd + - setup vt100 emulator windows - - Using new (ti_rri) backend server (serial and fx2 supported) - - cd $RETROBASE/rtl/sys_gen/w11a/tb - telnet_starter -d DL0 & - - [for s3,n2 over serial:] - SWI = 00000010 - torri -tu0,460k,break,xon @uv5_boot.tcl - [for n3 over serial:] - SWI = 00000010 - torri -tu0,2M,break,xon @uv5_boot.tcl - - [for n2,n3 over fx2:] - SWI = 00000100 - torri -u @uv5_boot.tcl - - - the boot dialog in the console xterm window will look like - (required input is in {..}, with {} denoting a carriage return: - - @{unix} - - login: {root} - - Now you are at the shell prompt and can excercise the system, e.g. - - # {ls -al} - total 62 - drwxr-xr-x 9 bin 160 Jan 29 16:14 . - drwxr-xr-x 9 bin 160 Jan 29 16:14 .. - drwxr-xr-x 2 bin 944 Nov 26 18:13 bin - drwxr-xr-x 2 bin 80 Nov 26 18:13 dev - drwxr-xr-x 2 bin 240 Mar 21 12:07 etc - drwxr-xr-x 2 bin 224 Nov 26 18:13 lib - drwxr-xr-x 2 bin 32 Nov 26 18:13 mnt - drwxrwxrwx 2 bin 32 Nov 26 18:13 tmp - -rwxrwxrwx 1 bin 25802 Mar 21 12:07 unix - drwxr-xr-x 14 bin 224 Nov 26 18:13 usr - - There is no 'halt' or 'shutdown' command, just ^D out of the server - session. The disks aren't cached, so no need to sync either. - -4. 2.11BSD system --------------------------------------------------------- - - A disk set is available from - http://www.retro11.de/data/oc_w11/211bsd_rkset.tgz - Download, unpack and copy the disk images (*.dsk) to - $RETROBASE/rtl/sys_gen/w11a/tb - - - Using old (pi_rri) backend server (serial port only) - - cd $RETROBASE/rtl/sys_gen/w11a/tb - sudo $RETROBASE/tools/bin/set_ftdi_lat USB0 1 + cd $RETROBASE/tools/oskit/ telnet_starter -d DL0 & telnet_starter -d DL1 & - [for s3,n2:] - SWI = 00000010 - dorri -u0,460,1,2 @211bsd_rk_boot.pcmd - [for n3:] - SWI = 00000010 - dorri -u0,2000,1,2 @211bsd_rk_boot.pcmd - - - Using new (ti_rri) backend server (serial and fx2 supported) - - cd $RETROBASE/rtl/sys_gen/w11a/tb - telnet_starter -d DL0 & - - [for s3,n2 over serial:] - SWI = 00000010 - torri -tu0,460k,break,xon @211bsd_rk_boot.tcl - [for n3 over serial:] - SWI = 00000010 - torri -tu0,2M,break,xon @211bsd_rk_boot.tcl + - setup rlink connection using ti_rri backend server via the ti_w11 + quick start wrapper script. Ensure that all 8 switches on the board + are in the indicated positions (SWI=...). The concrete boot script + name is given in the following sections [for n2,n3 over fx2:] SWI = 00000100 - torri -u @211bsd_rk_boot.tcl + ti_w11 -u @_boot.tcl - - the boot dialog in the console xterm window will look like - (required input is in {..}, with {} denoting a carriage return: + [for s3,n2 over serial:] + SWI = 00000010 + ti_w11 -tu0,460k,break,xon @_boot.tcl + [for n3 over serial:] + SWI = 00000010 + ti_w11 -tu0,2M,break,xon @_boot.tcl + +4. simh simulator setup --------------------------------------------------- - 70Boot from rk(0,0,0) at 0177404 - : {} - : rk(0,0,0)unix - Boot: bootdev=03000 bootcsr=0177404 - - 2.11 BSD UNIX #26: Thu Jan 1 19:49:13 PST 2009 - root@curly.2bsd.com:/usr/src/sys/RETRONFPRK - - phys mem = 3932160 - avail mem = 3577856 - user mem = 307200 - - January 4 16:45:33 init: configure system - - dz ? csr 160100 vector 310 skipped: No CSR. - lp 0 csr 177514 vector 200 attached - rk ? csr 177400 vector 220 didn't interrupt. - rl ? csr 174400 vector 160 skipped: No CSR. - tm ? csr 172520 vector 224 skipped: No CSR. - xp ? csr 176700 vector 254 skipped: No CSR. - cn 1 csr 176500 vector 300 attached - erase, kill ^U, intr ^C + Sometimes it is good to compare the w11a behaviour with the PDP-11 software + emulator from the simh project (see http://simh.trailing-edge.com/). - In first '#' prompt the system is in single-user mode. Just enter a ^D - to continue the system startup to multi-user mode: + Under $RETROBASE/tools/simh two setup files are provided with configure + simh to reflect the w11a setup as close as possible: + - setup_w11a_min.scmd + Very close the current w11a state when it runs on an S3BOARD + - processor: 11/70, no FPP, 1 Mbyte + - periphery: 2 DL11, LP11, RK11, PC11 + - setup_w11a_max.scmd + Planned configuration for the w11a, in addition + - processor: 4 Mbyte memory (as on Nexys2, Nexys3,...) + - periphery: DZ11, RL11/RL02, RK70/RP06, TM11/TU10 - #^D - checking quotas: done. - Assuming non-networking system ... - checking for core dump... - preserving editor files - clearing /tmp - standard daemons: update cron accounting. - starting lpd - starting local daemons:Sun Jan 4 16:46:37 PST 2009 - January 4 16:46:37 init: kernel security level changed from 0 to 1 - January 4 16:46:40 getty: /dev/tty01: Device not configured - ... - - 2.11 BSD UNIX (curly.2bsd.com) (console) - - login: {root} - erase, kill ^U, intr ^C + Startup scripts are provided with each oskit. They call the w11a_max + configuration, so will show in the emulator what w11a can do when + finished. - Now the system is in multi-user mode, daemons runnng. You can explore - the system, e.g. with a 'pstat -T' or a 'mount' command. At end is - important to shutdown properly with a 'halt': + All examples below use the same basic setup - # {pstat -T} - 7/186 files - 39/208 inodes - 11/150 processes - 6/ 46 texts active, 28 used - 2/135 swapmap entries, 366 kB used, 2069 kB free, 2063 kB max - 33/150 coremap entries, 2960 kB free, 2867 kB max - 1/ 10 ub_map entries, 10 free, 10 max - # {mount} - /dev/rk0h on / - /dev/rk2h on /tmp - /dev/rk3h on /bin - /dev/rk4h on /usr - # {halt} - syncing disks... done - halting + - setup vt100 emulator window for 2nd DL11 - Now the server process can be stopped with ^D. + cd $RETROBASE/tools/oskit/ + telnet_starter -d -s DL1 & + + {Note: the -s ensures that the port numbers used by simh are taken!} + + - start the simulator + + pdp11 _boot.scmd + +5. oskits ----------------------------------------------------------------- + + Ready to be used 'oskits' are provided under + $RETROBASE/tools/oskit/ + + The tarballs with the disk images are provided from a web server + and have to be installed separately. + +5a. Unix systems ----------------------------------------------------- + + Legal and license issues: + + Ancient UNIX systems for the PDP-11 can now be freely used under the + 'Caldera license'. 2.11BSD was released 1992 under the 4 clause BSD + license. Taken together + + - Unix V1 to V7 + - all BSD Unix versions for PDP-11 + + can be freely distributed and used for non-commercial purposes. + + Two oskits are currently provided: + + - unix-v5_rk: Unix V5 System on RK05 + - 211bsd_rk: 2.11BSD system on RK05 + + For further details consult the README_set.txt file in the + oskit directory. + +5b. DEC operating systems -------------------------------------------- + + Legal and license issues: + + Unfortunately there is no general hobbyist license for DEC operating + systems for PDP-11 computers. The 'Mentec license' commonly understood + to cover the some older versions of DEC operating systems, for example + - RT-11 V5.3 or prior + - RSX-11M V4.3 or prior + - RSX-11M PLUS V3.0 or prior + on software simulators, most notably on the 'simh' suite. + + HOWEVER: THIS LICENSE DOES NOT COVER THE USAGE OF THESE HISTORIC DEC + OPERATING SYSTEMS ON ANY 'REAL HARDWARE' IMPLEMENTATION OF A + PDP-11. SO USAGE ON THE W11 IS *NOT* COVERED BY THE + 'Mentec-license'. + + Some oskits are provided with systems sysgen'ed to run on a configuration + like the w11a. + + - Feel free to explore them with the simh simulator. + The boot scripts for simh are included ( .simh ) + + - In case you happen to have a valid license feel free to try them + out the W11A and let the author know whether is works as it should. + For convenience the boot scripts are also included ( .tcl ). + + Three oskits are currently provided + + - rsx11m-31_rk: RSX-11M V3.1 on RK05 + - rsx11m-40_rk: RSX-11M V4.0 on RK05 + - rt11-40_rk: RT-11 V4.0 on RK05 + + For further details consult the README_set.txt file in the + oskit directory. diff --git a/rtl/ibus/ibdr_lp11.vhd b/rtl/ibus/ibdr_lp11.vhd index 5393d52f..73874dfe 100644 --- a/rtl/ibus/ibdr_lp11.vhd +++ b/rtl/ibus/ibdr_lp11.vhd @@ -1,6 +1,6 @@ --- $Id: ibdr_lp11.vhd 427 2011-11-19 21:04:11Z mueller $ +-- $Id: ibdr_lp11.vhd 515 2013-05-04 17:28:59Z mueller $ -- --- Copyright 2009-2011 by Walter F.J. Mueller +-- Copyright 2009-2013 by Walter F.J. Mueller -- -- This program is free software; you may redistribute and/or modify it under -- the terms of the GNU General Public License as published by the Free @@ -18,7 +18,7 @@ -- Dependencies: - -- Test bench: - -- Target Devices: generic --- Tool versions: xst 8.2, 9.1, 9.2, 10.1, 12.1, 13.1; ghdl 0.18-0.29 +-- Tool versions: xst 8.2, 9.1, 9.2, 10.1, 12.1, 13.3; ghdl 0.18-0.29 -- -- Synthesized (xst): -- Date Rev ise Target flop lutl lutm slic t peri @@ -27,6 +27,7 @@ -- -- Revision History: -- Date Rev Version Comment +-- 2013-05-04 515 1.3 BUGFIX: r.err was cleared in racc read ! -- 2011-11-18 427 1.2.2 now numeric_std clean -- 2010-10-23 335 1.2.1 rename RRI_LAM->RB_LAM; -- 2010-10-17 333 1.2 use ibus V2 interface @@ -119,6 +120,7 @@ begin variable ibreq : slbit := '0'; variable ibrd : slbit := '0'; variable ibw0 : slbit := '0'; + variable ibw1 : slbit := '0'; variable ilam : slbit := '0'; begin @@ -129,6 +131,7 @@ begin ibreq := IB_MREQ.re or IB_MREQ.we; ibrd := IB_MREQ.re; ibw0 := IB_MREQ.we and IB_MREQ.be0; + ibw1 := IB_MREQ.we and IB_MREQ.be1; ilam := '0'; -- ibus address decoder @@ -158,7 +161,9 @@ begin end if; end if; else -- rri - n.err := IB_MREQ.din(csr_ibf_err); + if ibw1 = '1' then + n.err := IB_MREQ.din(csr_ibf_err); + end if; end if; when ibaddr_buf => -- BUF -- data buffer ---------------- diff --git a/rtl/ibus/ibdr_pc11.vhd b/rtl/ibus/ibdr_pc11.vhd index 228c8a4a..3beec1b0 100644 --- a/rtl/ibus/ibdr_pc11.vhd +++ b/rtl/ibus/ibdr_pc11.vhd @@ -1,6 +1,6 @@ --- $Id: ibdr_pc11.vhd 427 2011-11-19 21:04:11Z mueller $ +-- $Id: ibdr_pc11.vhd 515 2013-05-04 17:28:59Z mueller $ -- --- Copyright 2009-2011 by Walter F.J. Mueller +-- Copyright 2009-2013 by Walter F.J. Mueller -- -- This program is free software; you may redistribute and/or modify it under -- the terms of the GNU General Public License as published by the Free @@ -18,7 +18,7 @@ -- Dependencies: - -- Test bench: xxdp: zpcae0 -- Target Devices: generic --- Tool versions: xst 8.2, 9.1, 9.2, 12.1, 13.1; ghdl 0.18-0.29 +-- Tool versions: xst 8.2, 9.1, 9.2, 12.1, 13.3; ghdl 0.18-0.29 -- -- Synthesized (xst): -- Date Rev ise Target flop lutl lutm slic t peri @@ -27,6 +27,8 @@ -- -- Revision History: -- Date Rev Version Comment +-- 2013-05-04 515 1.3 BUGFIX: r.rbuf was immediately cleared ! Was broken +-- since ibus V2 update, never tested afterwards... -- 2011-11-18 427 1.2.2 now numeric_std clean -- 2010-10-23 335 1.2.1 rename RRI_LAM->RB_LAM; -- 2010-10-17 333 1.2 use ibus V2 interface @@ -215,8 +217,8 @@ begin idout(r.rbuf'range) := r.rbuf; if IB_MREQ.racc = '0' then -- cpu --------------------- - if true then -- !! PC11 is unusual !! - n.rdone := '0'; -- any read or write will clear done + if ibreq = '1' then -- !! PC11 is unusual !! + n.rdone := '0'; -- *any* read or write will clear done n.rbuf := (others=>'0'); -- and the reader buffer n.rintreq := '0'; -- also interrupt is canceled end if; diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic/.cvsignore b/rtl/sys_gen/tst_fx2loop/nexys3/ic/.cvsignore new file mode 100644 index 00000000..5b8e883f --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic/.cvsignore @@ -0,0 +1,4 @@ +_impactbatch.log +sys_tst_fx2loop_ic_n3.ucf +*.dep_ucf_cpp +*.svf diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic/Makefile b/rtl/sys_gen/tst_fx2loop/nexys3/ic/Makefile new file mode 100644 index 00000000..907e385f --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic/Makefile @@ -0,0 +1,30 @@ +# $Id: Makefile 477 2013-01-27 14:07:10Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2012-04-09 461 1.0 Initial version +# +# +VBOM_all = $(wildcard *.vbom) +BIT_all = $(VBOM_all:.vbom=.bit) +# +include $(RETROBASE)/rtl/make/xflow_default_nexys3.mk +FX2_FILE = nexys3_jtag_2fifo_ic.ihx +# +.PHONY : all clean +# +all : $(BIT_all) +# +clean : ise_clean + rm -f $(VBOM_all:.vbom=.ucf) +# +#---- +# +include $(RETROBASE)/rtl/make/generic_xflow.mk +include $(RETROBASE)/rtl/make/generic_ghdl.mk +# +ifndef DONTINCDEP +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +endif +# diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_conf.vhd b/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_conf.vhd new file mode 100644 index 00000000..249e803c --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_conf.vhd @@ -0,0 +1,59 @@ +-- $Id: sys_conf.vhd 510 2013-04-26 16:14:57Z mueller $ +-- +-- Copyright 2012-2013 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: sys_conf +-- Description: Definitions for sys_tst_fx2loop_ic_n3 (for synthesis) +-- +-- Dependencies: - +-- Tool versions: xst 13.3, 14.5; ghdl 0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2012-04-24 510 1.1 use 3/2 clock-> 150 MHz sysclk +-- 2012-04-09 461 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package sys_conf is + + constant sys_conf_clkfx_divide : positive := 2; + constant sys_conf_clkfx_multiply : positive := 3; + + constant sys_conf_fx2_type : string := "ic2"; + + -- dummy values defs for generic parameters of as controller + constant sys_conf_fx2_rdpwldelay : positive := 1; + constant sys_conf_fx2_rdpwhdelay : positive := 1; + constant sys_conf_fx2_wrpwldelay : positive := 1; + constant sys_conf_fx2_wrpwhdelay : positive := 1; + constant sys_conf_fx2_flagdelay : positive := 1; + + -- pktend timer setting + -- petowidth=10 -> 2^10 30 MHz clocks -> ~33 usec (normal operation) + constant sys_conf_fx2_petowidth : positive := 10; + + constant sys_conf_fx2_ccwidth : positive := 5; + + constant sys_conf_hio_debounce : boolean := true; -- instantiate debouncers + + -- derived constants + + constant sys_conf_clksys : integer := + (100000000/sys_conf_clkfx_divide)*sys_conf_clkfx_multiply; + constant sys_conf_clksys_mhz : integer := sys_conf_clksys/1000000; + +end package sys_conf; diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_tst_fx2loop_ic_n3.ucf_cpp b/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_tst_fx2loop_ic_n3.ucf_cpp new file mode 100644 index 00000000..e002c6e0 --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_tst_fx2loop_ic_n3.ucf_cpp @@ -0,0 +1,20 @@ +## $Id: sys_tst_fx2loop_ic_n3.ucf_cpp 461 2012-04-09 21:17:54Z mueller $ +## +## Revision History: +## Date Rev Version Comment +## 2012-04-09 461 1.0 Initial version +## + +NET "I_CLK100" TNM_NET = "I_CLK100"; +TIMESPEC "TS_I_CLK100" = PERIOD "I_CLK100" 10.0 ns HIGH 50 %; +OFFSET = IN 10 ns BEFORE "I_CLK100"; +OFFSET = OUT 20 ns AFTER "I_CLK100"; + +## std board +## +#include "bplib/nexys3/nexys3_pins.ucf" +## +## FX2 interface +## +#include "bplib/nexys3/nexys3_pins_fx2.ucf" +#include "bplib/nexys3/nexys3_time_fx2_ic.ucf" diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_tst_fx2loop_ic_n3.vbom b/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_tst_fx2loop_ic_n3.vbom new file mode 100644 index 00000000..49e749ba --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic/sys_tst_fx2loop_ic_n3.vbom @@ -0,0 +1,8 @@ +# conf +sys_conf = sys_conf.vhd +# libs +# components +# design +../sys_tst_fx2loop_n3.vbom +@ucf_cpp: sys_tst_fx2loop_ic_n3.ucf +@top: sys_tst_fx2loop_n3 diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic3/.cvsignore b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/.cvsignore new file mode 100644 index 00000000..4e8c9810 --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/.cvsignore @@ -0,0 +1,4 @@ +_impactbatch.log +sys_tst_fx2loop_ic3_n3.ucf +*.dep_ucf_cpp +*.svf diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic3/Makefile b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/Makefile new file mode 100644 index 00000000..f463486f --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/Makefile @@ -0,0 +1,30 @@ +# $Id: Makefile 477 2013-01-27 14:07:10Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2012-04-09 461 1.0 Initial version +# +# +VBOM_all = $(wildcard *.vbom) +BIT_all = $(VBOM_all:.vbom=.bit) +# +include $(RETROBASE)/rtl/make/xflow_default_nexys3.mk +FX2_FILE = nexys3_jtag_3fifo_ic.ihx +# +.PHONY : all clean +# +all : $(BIT_all) +# +clean : ise_clean + rm -f $(VBOM_all:.vbom=.ucf) +# +#---- +# +include $(RETROBASE)/rtl/make/generic_xflow.mk +include $(RETROBASE)/rtl/make/generic_ghdl.mk +# +ifndef DONTINCDEP +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +endif +# diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_conf.vhd b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_conf.vhd new file mode 100644 index 00000000..3604a998 --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_conf.vhd @@ -0,0 +1,59 @@ +-- $Id: sys_conf.vhd 510 2013-04-26 16:14:57Z mueller $ +-- +-- Copyright 2012-2013 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: sys_conf +-- Description: Definitions for sys_tst_fx2loop_ic3_n3 (for synthesis) +-- +-- Dependencies: - +-- Tool versions: xst 13.3, 14.5; ghdl 0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2012-04-25 510 1.1 use 3/2 clock-> 150 MHz sysclk +-- 2012-04-09 461 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package sys_conf is + + constant sys_conf_clkfx_divide : positive := 2; + constant sys_conf_clkfx_multiply : positive := 3; + + constant sys_conf_fx2_type : string := "ic3"; + + -- dummy values defs for generic parameters of as controller + constant sys_conf_fx2_rdpwldelay : positive := 1; + constant sys_conf_fx2_rdpwhdelay : positive := 1; + constant sys_conf_fx2_wrpwldelay : positive := 1; + constant sys_conf_fx2_wrpwhdelay : positive := 1; + constant sys_conf_fx2_flagdelay : positive := 1; + + -- pktend timer setting + -- petowidth=10 -> 2^10 30 MHz clocks -> ~33 usec (normal operation) + constant sys_conf_fx2_petowidth : positive := 10; + + constant sys_conf_fx2_ccwidth : positive := 5; + + constant sys_conf_hio_debounce : boolean := true; -- instantiate debouncers + + -- derived constants + + constant sys_conf_clksys : integer := + (100000000/sys_conf_clkfx_divide)*sys_conf_clkfx_multiply; + constant sys_conf_clksys_mhz : integer := sys_conf_clksys/1000000; + +end package sys_conf; diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_tst_fx2loop_ic3_n3.ucf_cpp b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_tst_fx2loop_ic3_n3.ucf_cpp new file mode 100644 index 00000000..14535ffd --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_tst_fx2loop_ic3_n3.ucf_cpp @@ -0,0 +1,20 @@ +## $Id: sys_tst_fx2loop_ic3_n3.ucf_cpp 461 2012-04-09 21:17:54Z mueller $ +## +## Revision History: +## Date Rev Version Comment +## 2012-04-09 461 1.0 Initial version +## + +NET "I_CLK100" TNM_NET = "I_CLK100"; +TIMESPEC "TS_I_CLK100" = PERIOD "I_CLK100" 10.0 ns HIGH 50 %; +OFFSET = IN 10 ns BEFORE "I_CLK100"; +OFFSET = OUT 20 ns AFTER "I_CLK100"; + +## std board +## +#include "bplib/nexys3/nexys3_pins.ucf" +## +## FX2 interface +## +#include "bplib/nexys3/nexys3_pins_fx2.ucf" +#include "bplib/nexys3/nexys3_time_fx2_ic.ucf" diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_tst_fx2loop_ic3_n3.vbom b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_tst_fx2loop_ic3_n3.vbom new file mode 100644 index 00000000..bed54e92 --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/ic3/sys_tst_fx2loop_ic3_n3.vbom @@ -0,0 +1,8 @@ +# conf +sys_conf = sys_conf.vhd +# libs +# components +# design +../sys_tst_fx2loop_n3.vbom +@ucf_cpp: sys_tst_fx2loop_ic3_n3.ucf +@top: sys_tst_fx2loop_n3 diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/sys_tst_fx2loop_n3.vbom b/rtl/sys_gen/tst_fx2loop/nexys3/sys_tst_fx2loop_n3.vbom new file mode 100644 index 00000000..11f8997a --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/sys_tst_fx2loop_n3.vbom @@ -0,0 +1,30 @@ +# this is the vbom for the 'generic' top level entity +# to be referenced in the vbom's of the specific systems +# ./as/sys_tst_fx2loop_as_n3 +# ./ic/sys_tst_fx2loop_ic_n3 +# ./ic3/sys_tst_fx2loop_ic3_n3 +# +# libs +../../../vlib/slvtypes.vhd +../../../vlib/xlib/xlib.vhd +../../../vlib/genlib/genlib.vhd +../../../bplib/bpgen/bpgenlib.vbom +../tst_fx2looplib.vbom +../../../bplib/fx2lib/fx2lib.vhd +../../../bplib/nxcramlib/nxcramlib.vhd +${sys_conf} +# components +[xst,isim]../../../vlib/xlib/dcm_sfs_unisim_s3e.vbom +[ghdl]../../../vlib/xlib/dcm_sfs_gsim.vbom +../../../vlib/genlib/clkdivce.vbom +../../../bplib/bpgen/sn_humanio.vbom +../tst_fx2loop_hiomap.vbom +../tst_fx2loop.vbom +../../../bplib/fx2lib/fx2_2fifoctl_as.vbom +../../../bplib/fx2lib/fx2_2fifoctl_ic.vbom +../../../bplib/fx2lib/fx2_3fifoctl_ic.vbom +../../../bplib/nxcramlib/nx_cram_dummy.vbom +# design +sys_tst_fx2loop_n3.vhd +## no @ucf_cpp + diff --git a/rtl/sys_gen/tst_fx2loop/nexys3/sys_tst_fx2loop_n3.vhd b/rtl/sys_gen/tst_fx2loop/nexys3/sys_tst_fx2loop_n3.vhd new file mode 100644 index 00000000..b3ed0f49 --- /dev/null +++ b/rtl/sys_gen/tst_fx2loop/nexys3/sys_tst_fx2loop_n3.vhd @@ -0,0 +1,364 @@ +-- $Id: sys_tst_fx2loop_n3.vhd 514 2013-05-03 16:11:23Z mueller $ +-- +-- Copyright 2012-2013 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: sys_tst_fx2loop_n3 - syn +-- Description: test of Cypress EZ-USB FX2 controller +-- +-- Dependencies: vlib/xlib/dcm_sfs +-- vlib/genlib/clkdivce +-- bpgen/sn_humanio +-- tst_fx2loop_hiomap +-- tst_fx2loop +-- bplib/fx2lib/fx2_2fifoctl_as [sys_conf_fx2_type="as2"] +-- bplib/fx2lib/fx2_2fifoctl_ic [sys_conf_fx2_type="ic2"] +-- bplib/fx2lib/fx2_3fifoctl_ic [sys_conf_fx2_type="ic3"] +-- bplib/nxcramlib/nx_cram_dummy +-- +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 13.3, 14.5; ghdl 0.29 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri ctl/MHz +-- 2013-04-25 510 14.5 P58f xc6slx16-2 416 516 68 199 p 5.3 ic3/150 +-- 2013-04-24 510 13.3 O76d xc6slx16-2 417 674 68 228 p 5.3 ic3/175 +-- 2012-04-09 461 13.3 O76d xc6slx16-2 429 620 48 232 p 7.2 ic3/100 +-- +-- 2013-04-25 510 14.5 P58f xc6slx16-2 349 427 48 163 p 5.4 ic2/150 +-- 2013-04-24 510 13.3 O76d xc6slx16-2 355 569 48 208 p 5.4 ic2/175 +-- 2012-04-09 461 13.3 O76d xc6slx16-2 347 499 32 175 p 7.9 ic2/100 +-- +-- 2013-04-24 510 13.3 O76d xc6slx16-2 299 486 32 175 p FAIL as2/100 +-- 2012-04-09 461 13.3 O76d xc6slx16-2 299 460 32 164 p FAIL as2/100 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2013-04-24 510 1.0.1 CLKDIV.CDUWIDTH now 8, support >127 sysclk +-- 2012-04-09 461 1.0 Initial version (derived from sys_tst_fx2loop_n2) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.slvtypes.all; +use work.xlib.all; +use work.genlib.all; +use work.bpgenlib.all; +use work.tst_fx2looplib.all; +use work.fx2lib.all; +use work.nxcramlib.all; +use work.sys_conf.all; + +-- ---------------------------------------------------------------------------- + +entity sys_tst_fx2loop_n3 is -- top level + -- implements nexys3_aif + fx2 pins + port ( + I_CLK100 : in slbit; -- 100 MHz clock + I_RXD : in slbit; -- receive data (board view) + O_TXD : out slbit; -- transmit data (board view) + I_SWI : in slv8; -- n3 switches + I_BTN : in slv5; -- n3 buttons + O_LED : out slv8; -- n3 leds + O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low) + O_SEG_N : out slv8; -- 7 segment disp: segments (act.low) + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16; -- cram: data lines + O_PPCM_CE_N : out slbit; -- ppcm: ... + O_PPCM_RST_N : out slbit; -- ppcm: ... + I_FX2_IFCLK : in slbit; -- fx2: interface clock + O_FX2_FIFO : out slv2; -- fx2: fifo address + I_FX2_FLAG : in slv4; -- fx2: fifo flags + O_FX2_SLRD_N : out slbit; -- fx2: read enable (act.low) + O_FX2_SLWR_N : out slbit; -- fx2: write enable (act.low) + O_FX2_SLOE_N : out slbit; -- fx2: output enable (act.low) + O_FX2_PKTEND_N : out slbit; -- fx2: packet end (act.low) + IO_FX2_DATA : inout slv8 -- fx2: data lines + ); +end sys_tst_fx2loop_n3; + +architecture syn of sys_tst_fx2loop_n3 is + + signal CLK : slbit := '0'; + signal RESET : slbit := '0'; + + signal CE_USEC : slbit := '0'; + signal CE_MSEC : slbit := '0'; + + signal SWI : slv8 := (others=>'0'); + signal BTN : slv5 := (others=>'0'); + signal LED : slv8 := (others=>'0'); + signal DSP_DAT : slv16 := (others=>'0'); + signal DSP_DP : slv4 := (others=>'0'); + + signal LED_MAP : slv8 := (others=>'0'); + + signal HIO_CNTL : hio_cntl_type := hio_cntl_init; + signal HIO_STAT : hio_stat_type := hio_stat_init; + + signal FX2_RXDATA : slv8 := (others=>'0'); + signal FX2_RXVAL : slbit := '0'; + signal FX2_RXHOLD : slbit := '0'; + signal FX2_RXAEMPTY : slbit := '0'; + signal FX2_TXDATA : slv8 := (others=>'0'); + signal FX2_TXENA : slbit := '0'; + signal FX2_TXBUSY : slbit := '0'; + signal FX2_TXAFULL : slbit := '0'; + signal FX2_TX2DATA : slv8 := (others=>'0'); + signal FX2_TX2ENA : slbit := '0'; + signal FX2_TX2BUSY : slbit := '1'; + signal FX2_TX2AFULL : slbit := '0'; + signal FX2_MONI : fx2ctl_moni_type := fx2ctl_moni_init; + +begin + + assert (sys_conf_clksys mod 1000000) = 0 + report "assert sys_conf_clksys on MHz grid" + severity failure; + + DCM : dcm_sfs + generic map ( + CLKFX_DIVIDE => sys_conf_clkfx_divide, + CLKFX_MULTIPLY => sys_conf_clkfx_multiply, + CLKIN_PERIOD => 10.0) + port map ( + CLKIN => I_CLK100, + CLKFX => CLK, + LOCKED => open + ); + + CLKDIV : clkdivce + generic map ( + CDUWIDTH => 8, -- good for up to 255 MHz ! + USECDIV => sys_conf_clksys_mhz, + MSECDIV => 1000) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC + ); + + HIO : sn_humanio + generic map ( + BWIDTH => 5, + DEBOUNCE => sys_conf_hio_debounce) + port map ( + CLK => CLK, + RESET => '0', + CE_MSEC => CE_MSEC, + SWI => SWI, + BTN => BTN, + LED => LED, + DSP_DAT => DSP_DAT, + DSP_DP => DSP_DP, + I_SWI => I_SWI, + I_BTN => I_BTN, + O_LED => O_LED, + O_ANO_N => O_ANO_N, + O_SEG_N => O_SEG_N + ); + + RESET <= BTN(0); -- BTN(0) will reset tester !! + + HIOMAP : tst_fx2loop_hiomap + port map ( + CLK => CLK, + RESET => RESET, + HIO_CNTL => HIO_CNTL, + HIO_STAT => HIO_STAT, + FX2_MONI => FX2_MONI, + SWI => SWI, + BTN => BTN(3 downto 0), + LED => LED_MAP, + DSP_DAT => DSP_DAT, + DSP_DP => DSP_DP + ); + + proc_led: process (SWI, LED_MAP, FX2_TX2BUSY, FX2_TX2ENA, + FX2_TXBUSY, FX2_TXENA, FX2_RXHOLD, FX2_RXVAL) + begin + + if SWI(4) = '1' then + LED(7) <= '0'; + LED(6) <= '0'; + LED(5) <= FX2_TX2BUSY; + LED(4) <= FX2_TX2ENA; + LED(3) <= FX2_TXBUSY; + LED(2) <= FX2_TXENA; + LED(1) <= FX2_RXHOLD; + LED(0) <= FX2_RXVAL; + else + LED <= LED_MAP; + end if; + + end process proc_led; + + + TST : tst_fx2loop + port map ( + CLK => CLK, + RESET => RESET, + CE_MSEC => CE_MSEC, + HIO_CNTL => HIO_CNTL, + HIO_STAT => HIO_STAT, + FX2_MONI => FX2_MONI, + RXDATA => FX2_RXDATA, + RXVAL => FX2_RXVAL, + RXHOLD => FX2_RXHOLD, + TXDATA => FX2_TXDATA, + TXENA => FX2_TXENA, + TXBUSY => FX2_TXBUSY, + TX2DATA => FX2_TX2DATA, + TX2ENA => FX2_TX2ENA, + TX2BUSY => FX2_TX2BUSY + ); + + FX2_CNTL_AS : if sys_conf_fx2_type = "as2" generate + CNTL : fx2_2fifoctl_as + generic map ( + RXFAWIDTH => 5, + TXFAWIDTH => 5, + CCWIDTH => sys_conf_fx2_ccwidth, + RXAEMPTY_THRES => 1, + TXAFULL_THRES => 1, + PETOWIDTH => sys_conf_fx2_petowidth, + RDPWLDELAY => sys_conf_fx2_rdpwldelay, + RDPWHDELAY => sys_conf_fx2_rdpwhdelay, + WRPWLDELAY => sys_conf_fx2_wrpwldelay, + WRPWHDELAY => sys_conf_fx2_wrpwhdelay, + FLAGDELAY => sys_conf_fx2_flagdelay) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + RESET => RESET, + RXDATA => FX2_RXDATA, + RXVAL => FX2_RXVAL, + RXHOLD => FX2_RXHOLD, + RXAEMPTY => FX2_RXAEMPTY, + TXDATA => FX2_TXDATA, + TXENA => FX2_TXENA, + TXBUSY => FX2_TXBUSY, + TXAFULL => FX2_TXAFULL, + MONI => FX2_MONI, + I_FX2_IFCLK => I_FX2_IFCLK, + O_FX2_FIFO => O_FX2_FIFO, + I_FX2_FLAG => I_FX2_FLAG, + O_FX2_SLRD_N => O_FX2_SLRD_N, + O_FX2_SLWR_N => O_FX2_SLWR_N, + O_FX2_SLOE_N => O_FX2_SLOE_N, + O_FX2_PKTEND_N => O_FX2_PKTEND_N, + IO_FX2_DATA => IO_FX2_DATA + ); + end generate FX2_CNTL_AS; + + FX2_CNTL_IC : if sys_conf_fx2_type = "ic2" generate + CNTL : fx2_2fifoctl_ic + generic map ( + RXFAWIDTH => 5, + TXFAWIDTH => 5, + PETOWIDTH => sys_conf_fx2_petowidth, + CCWIDTH => sys_conf_fx2_ccwidth, + RXAEMPTY_THRES => 1, + TXAFULL_THRES => 1) + port map ( + CLK => CLK, + RESET => RESET, + RXDATA => FX2_RXDATA, + RXVAL => FX2_RXVAL, + RXHOLD => FX2_RXHOLD, + RXAEMPTY => FX2_RXAEMPTY, + TXDATA => FX2_TXDATA, + TXENA => FX2_TXENA, + TXBUSY => FX2_TXBUSY, + TXAFULL => FX2_TXAFULL, + MONI => FX2_MONI, + I_FX2_IFCLK => I_FX2_IFCLK, + O_FX2_FIFO => O_FX2_FIFO, + I_FX2_FLAG => I_FX2_FLAG, + O_FX2_SLRD_N => O_FX2_SLRD_N, + O_FX2_SLWR_N => O_FX2_SLWR_N, + O_FX2_SLOE_N => O_FX2_SLOE_N, + O_FX2_PKTEND_N => O_FX2_PKTEND_N, + IO_FX2_DATA => IO_FX2_DATA + ); + end generate FX2_CNTL_IC; + + FX2_CNTL_IC3 : if sys_conf_fx2_type = "ic3" generate + CNTL : fx2_3fifoctl_ic + generic map ( + RXFAWIDTH => 5, + TXFAWIDTH => 5, + PETOWIDTH => sys_conf_fx2_petowidth, + CCWIDTH => sys_conf_fx2_ccwidth, + RXAEMPTY_THRES => 1, + TXAFULL_THRES => 1, + TX2AFULL_THRES => 1) + port map ( + CLK => CLK, + RESET => RESET, + RXDATA => FX2_RXDATA, + RXVAL => FX2_RXVAL, + RXHOLD => FX2_RXHOLD, + RXAEMPTY => FX2_RXAEMPTY, + TXDATA => FX2_TXDATA, + TXENA => FX2_TXENA, + TXBUSY => FX2_TXBUSY, + TXAFULL => FX2_TXAFULL, + TX2DATA => FX2_TX2DATA, + TX2ENA => FX2_TX2ENA, + TX2BUSY => FX2_TX2BUSY, + TX2AFULL => FX2_TX2AFULL, + MONI => FX2_MONI, + I_FX2_IFCLK => I_FX2_IFCLK, + O_FX2_FIFO => O_FX2_FIFO, + I_FX2_FLAG => I_FX2_FLAG, + O_FX2_SLRD_N => O_FX2_SLRD_N, + O_FX2_SLWR_N => O_FX2_SLWR_N, + O_FX2_SLOE_N => O_FX2_SLOE_N, + O_FX2_PKTEND_N => O_FX2_PKTEND_N, + IO_FX2_DATA => IO_FX2_DATA + ); + end generate FX2_CNTL_IC3; + + SRAM_PROT : nx_cram_dummy -- connect CRAM to protection dummy + port map ( + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADV_N => O_MEM_ADV_N, + O_MEM_CLK => O_MEM_CLK, + O_MEM_CRE => O_MEM_CRE, + I_MEM_WAIT => I_MEM_WAIT, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA + ); + + O_PPCM_CE_N <= '1'; -- keep parallel PCM memory disabled + O_PPCM_RST_N <= '1'; -- + + O_TXD <= I_RXD; -- loop-back in serial port... + +end syn; + diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys2/ic/tb/tb_tst_rlink_cuff_ic_n2.vbom b/rtl/sys_gen/tst_rlink_cuff/nexys2/ic/tb/tb_tst_rlink_cuff_ic_n2.vbom index d1343201..793f0433 100644 --- a/rtl/sys_gen/tst_rlink_cuff/nexys2/ic/tb/tb_tst_rlink_cuff_ic_n2.vbom +++ b/rtl/sys_gen/tst_rlink_cuff/nexys2/ic/tb/tb_tst_rlink_cuff_ic_n2.vbom @@ -1,4 +1,4 @@ -# configure tb_nexsy2_fusp with sys_tst_rlink_n2 target; +# configure tb_nexsy2_fusp_cuff with sys_tst_rlink_cuff_n2 target; # use vhdl configure file (tb_tst_rlink_cuff_ic_n2.vhd) to allow # that all configurations will co-exist in work library ${nexys2_fusp_cuff_aif := ../sys_tst_rlink_cuff_ic_n2.vbom} diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/.cvsignore b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/.cvsignore new file mode 100644 index 00000000..5b93b2e6 --- /dev/null +++ b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/.cvsignore @@ -0,0 +1,6 @@ +tb_tst_rlink_cuff_ic_n3 +tb_tst_rlink_cuff_ic_n3_[sft]sim +rlink_cext_fifo_rx +rlink_cext_fifo_tx +rlink_cext_conf +*.dep_ucf_cpp diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/Makefile b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/Makefile new file mode 100644 index 00000000..1cb06add --- /dev/null +++ b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/Makefile @@ -0,0 +1,32 @@ +# $Id: Makefile 512 2013-04-28 07:44:02Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2013-04-27 512 1.0 Initial version +# +EXE_all = tb_tst_rlink_cuff_ic_n3 +# +include $(RETROBASE)/rtl/make/xflow_default_nexys3.mk +# +.PHONY : all all_ssim all_tsim clean +# +all : $(EXE_all) +all_ssim : $(EXE_all:=_ssim) +all_tsim : $(EXE_all:=_tsim) +# +clean : ise_clean ghdl_clean + rm -f sys_tst_rlink_cuff_ic_n3.ucf +# +#----- +# +include $(RETROBASE)/rtl/make/generic_ghdl.mk +include $(RETROBASE)/rtl/make/generic_xflow.mk +# +VBOM_all = $(wildcard *.vbom) +# +ifndef DONTINCDEP +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +include $(wildcard *.o.dep_ghdl) +endif +# diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/sys_conf_sim.vhd b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/sys_conf_sim.vhd new file mode 100644 index 00000000..655b20af --- /dev/null +++ b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/sys_conf_sim.vhd @@ -0,0 +1,60 @@ +-- $Id: sys_conf_sim.vhd 512 2013-04-28 07:44:02Z mueller $ +-- +-- Copyright 2013- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: sys_conf +-- Description: Definitions for sys_tst_rlink_cuff_ic_n3 (for simulation) +-- +-- Dependencies: - +-- Tool versions: xst 13.3; ghdl 0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2013-04-27 512 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package sys_conf is + + constant sys_conf_clkfx_divide : positive := 1; + constant sys_conf_clkfx_multiply : positive := 1; + + constant sys_conf_ser2rri_cdinit : integer := 1-1; -- 1 cycle/bit in sim + + constant sys_conf_hio_debounce : boolean := false; -- no debouncers + + constant sys_conf_fx2_type : string := "ic2"; + + -- dummy values defs for generic parameters of as controller + constant sys_conf_fx2_rdpwldelay : positive := 1; + constant sys_conf_fx2_rdpwhdelay : positive := 1; + constant sys_conf_fx2_wrpwldelay : positive := 1; + constant sys_conf_fx2_wrpwhdelay : positive := 1; + constant sys_conf_fx2_flagdelay : positive := 1; + + -- pktend timer setting + -- petowidth=10 -> 2^10 30 MHz clocks -> ~33 usec (normal operation) + constant sys_conf_fx2_petowidth : positive := 10; + + constant sys_conf_fx2_ccwidth : positive := 5; + + -- derived constants + + constant sys_conf_clksys : integer := + (100000000/sys_conf_clkfx_divide)*sys_conf_clkfx_multiply; + constant sys_conf_clksys_mhz : integer := sys_conf_clksys/1000000; + +end package sys_conf; diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/sys_tst_rlink_cuff_ic_n3.ucf_cpp b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/sys_tst_rlink_cuff_ic_n3.ucf_cpp new file mode 120000 index 00000000..5c37ba70 --- /dev/null +++ b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/sys_tst_rlink_cuff_ic_n3.ucf_cpp @@ -0,0 +1 @@ +../sys_tst_rlink_cuff_ic_n3.ucf_cpp \ No newline at end of file diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3.vbom b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3.vbom new file mode 100644 index 00000000..03093f31 --- /dev/null +++ b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3.vbom @@ -0,0 +1,7 @@ +# configure tb_nexsy3_fusp_cuff with sys_tst_rlink_cuff_n3 target; +# use vhdl configure file (tb_tst_rlink_cuff_ic_n3.vhd) to allow +# that all configurations will co-exist in work library +${nexys3_fusp_cuff_aif := ../sys_tst_rlink_cuff_ic_n3.vbom} +sys_conf = sys_conf_sim.vhd +../../../../../bplib/nexys3/tb/tb_nexys3_fusp_cuff.vbom +tb_tst_rlink_cuff_ic_n3.vhd diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3.vhd b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3.vhd new file mode 100644 index 00000000..ebc30eed --- /dev/null +++ b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3.vhd @@ -0,0 +1,40 @@ +-- $Id: tb_tst_rlink_cuff_ic_n3.vhd 512 2013-04-28 07:44:02Z mueller $ +-- +-- Copyright 2013- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_tst_rlink_cuff_ic_n3 +-- Description: Configuration for tb_tst_rlink_cuff_ic_n3 for +-- tb_nexys3_fusp_cuff +-- +-- Dependencies: sys_tst_rlink_cuff_n3 (fx2_type = 'ic2') +-- +-- To test: sys_tst_rlink_cuff_n3 (fx2_type = 'ic2') +-- +-- Verified: +-- Date Rev Code ghdl ise Target Comment +-- 2013-01-xx xxx - 0.29 13.3 O76d xc6slx16-2 u:??? +-- +-- Revision History: +-- Date Rev Version Comment +-- 2013-04-27 512 1.0 Initial version +------------------------------------------------------------------------------ + +configuration tb_tst_rlink_cuff_ic_n3 of tb_nexys3_fusp_cuff is + + for sim + for all : nexys3_fusp_cuff_aif + use entity work.sys_tst_rlink_cuff_n3; + end for; + end for; + +end tb_tst_rlink_cuff_ic_n3; diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3_ssim.vbom b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3_ssim.vbom new file mode 100644 index 00000000..0cf07684 --- /dev/null +++ b/rtl/sys_gen/tst_rlink_cuff/nexys3/ic/tb/tb_tst_rlink_cuff_ic_n3_ssim.vbom @@ -0,0 +1,6 @@ +# configure for _*sim case +# Note: this tb uses sys_tst_rlink_n3.vbom in local directory +# (not in .. as usual) to allow a tb specific configure !!! +nexys3_fusp_cuff_aif = sys_tst_rlink_cuff_ic_n3_ssim.vhd +tb_tst_rlink_cuff_ic_n3.vbom +@top:tb_tst_rlink_cuff_ic_n3 diff --git a/rtl/sys_gen/tst_rlink_cuff/nexys3/sys_tst_rlink_cuff_n3.vhd b/rtl/sys_gen/tst_rlink_cuff/nexys3/sys_tst_rlink_cuff_n3.vhd index dba61d71..ca31877b 100644 --- a/rtl/sys_gen/tst_rlink_cuff/nexys3/sys_tst_rlink_cuff_n3.vhd +++ b/rtl/sys_gen/tst_rlink_cuff/nexys3/sys_tst_rlink_cuff_n3.vhd @@ -1,4 +1,4 @@ --- $Id: sys_tst_rlink_cuff_n3.vhd 476 2013-01-26 22:23:53Z mueller $ +-- $Id: sys_tst_rlink_cuff_n3.vhd 512 2013-04-28 07:44:02Z mueller $ -- -- Copyright 2013- by Walter F.J. Mueller -- @@ -32,7 +32,7 @@ -- -- Synthesized (xst): -- Date Rev ise Target flop lutl lutm slic t peri ctl/MHz --- 2013-01-04 469 13.3 O76d xc3s1200e-4 ??? ???? ??? ???? p ??.? ic2/ 50 +-- 2013-01-04 469 13.3 O76d xc6slx16-2 ??? ???? ??? ???? p ??.? ic2/ 50 -- -- Revision History: -- Date Rev Version Comment diff --git a/rtl/sys_gen/w11a/tb/211bsd_rk_boot.pcmd b/rtl/sys_gen/w11a/tb/211bsd_rk_boot.pcmd deleted file mode 100644 index d045201c..00000000 --- a/rtl/sys_gen/w11a/tb/211bsd_rk_boot.pcmd +++ /dev/null @@ -1,28 +0,0 @@ -; $Id: 211bsd_rk_boot.pcmd 312 2010-07-04 18:25:58Z mueller $ -; -; Setup file for 211bsd RK based system (w11a, in sys/tb area...) -; -; Usage: -; -; telnet_starter -d DL0 & -; telnet_starter -d DL1 & -; -; dorri -s3 @211bsd_rk_boot.pcmd (for ghdl sim of tb_w11a_s3) -; dorri -n2 @211bsd_rk_boot.pcmd (for ghdl sim of tb_w11a_n2) -; -; dorri -t @211bsd_rk_boot.pcmd (fpga link via /dev/ttyS0) -; dorri -u0,460 @211bsd_rk_boot.pcmd (fpga link via /dev/ttyUSB0) -; -.mode serv11 -; -att TT0 8000 -att TT1 8001 -; -reset -att rk0 211bsd_rk_root.dsk -att rk1 211bsd_rk_swap.dsk -att rk2 211bsd_rk_tmp.dsk -att rk3 211bsd_rk_bin.dsk -att rk4 211bsd_rk_usr.dsk -boot rk0 -server diff --git a/rtl/sys_gen/w11a/tb/211bsd_rk_boot.tcl b/rtl/sys_gen/w11a/tb/211bsd_rk_boot.tcl deleted file mode 100644 index f343d6a9..00000000 --- a/rtl/sys_gen/w11a/tb/211bsd_rk_boot.tcl +++ /dev/null @@ -1,38 +0,0 @@ -# $Id: 211bsd_rk_boot.tcl 511 2013-04-27 13:51:46Z mueller $ -# -# Setup file for 211bsd RK based system (w11a, in sys/tb area...) -# -# Usage: -# -# telnet_starter -d DL0 & -# telnet_starter -d DL1 & -# torri -xxx @211bsd_rk_boot.tcl ( -xxx depends on sim or fpga connect) -# - -# setup w11 cpu -puts [rlw] - -# 2.11 bsd uses parity, so strip it -cpu0tta0 set to7bit 1 -cpu0ttb0 set to7bit 1 - -# setup tcp links for terminals -cpu0tta0 att "tcp:?port=8000" -cpu0ttb0 att "tcp:?port=8001" - -# setup log files -cpu0tta0 set log "tt_dl0.log?crlf" -cpu0ttb0 set log "tt_dl1.log?crlf" - -# mount disks -cpu0rka0 att 211bsd_rk_root.dsk -cpu0rka1 att 211bsd_rk_swap.dsk -cpu0rka2 att 211bsd_rk_tmp.dsk -cpu0rka3 att 211bsd_rk_bin.dsk -cpu0rka4 att 211bsd_rk_usr.dsk - -# and boot -#cpu0rka set trace 1 -rw11::cpumon -rw11::cpucons -cpu0 boot rka0 diff --git a/rtl/sys_gen/w11a/tb/dorri b/rtl/sys_gen/w11a/tb/dorri deleted file mode 100755 index ae5cfc2c..00000000 --- a/rtl/sys_gen/w11a/tb/dorri +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/perl -w -# $Id: dorri 510 2013-04-26 16:14:57Z mueller $ -# -# Revision History: -# Date Rev Version Comment -# 2011-12-03 435 1.5 add w11a_n3 support; add break/flow control to -u -# 2010-05-29 296 1.4 allow -ux,baud (usb devnum and baudrate) -# 2010-05-28 295 1.3 w11a_s3/w11a_n2 support: -s3 and -n2 instead of -f -# add -tmu option -# 2010-05-03 287 1.2 add -u[123] options for fast usb serport -# 2009-08-01 237 1.1.1 use 115200 instead of 38400 as default baud rate -# 2009-04-26 209 1.1 add -b (batch) option -# 2009-04-11 206 1.0 Initial version -# - -use 5.005; # require Perl 5.005 or higher -use strict; # require strict checking -use FileHandle; - -sub print_usage; - -autoflush STDOUT 1; # autoflush, so noting lost on exec later - -my $opt_b; -my $opt_io = ''; -my $opt_tmu; -my $pirri; -my $val_cmax="3"; -my $val_time="3."; -my $val_term=",115200,1"; -my $val_log="rri.log"; -my $val_tb_s3="tbw ../s3board/tb/tb_w11a_s3"; -my $val_tb_n2="tbw ../nexys2/tb/tb_w11a_n2"; -my $val_tb_n3="tbw ../nexys3/tb/tb_w11a_n3"; -my $val_tb; -my $val_e; - -my @arglist; - -my %baudtbl = ( - "57" => 57600, - "115" => 115200, - "230" => 230400, - "460" => 460800, - "500" => 500000, - "1000" => 1000000, - "2000" => 2000000, - "3000" => 2000000 - ); - -# -# process dorri options -# -while (scalar(@ARGV)) { - my $curarg = $ARGV[0]; - if ($curarg =~ m{^-b$} ) { # -b - $opt_b = 1; - shift @ARGV; - } elsif ($curarg =~ m{^-tmu$} ) { # -tmu - $opt_tmu = 1; - shift @ARGV; - } elsif ($curarg =~ m{^-s3$} ) { # -s3 - $opt_io = "f"; - $val_tb = $val_tb_s3; - shift @ARGV; - } elsif ($curarg =~ m{^-n2$} ) { # -n2 - $opt_io = "f"; - $val_tb = $val_tb_n2; - shift @ARGV; - } elsif ($curarg =~ m{^-n3$} ) { # -n3 - $opt_io = "f"; - $val_tb = $val_tb_n3; - shift @ARGV; - } elsif ($curarg =~ m{^-t$} ) { # -t - $opt_io = "t"; - - } elsif ($curarg =~ m{^-u(\d),?} ) { # -ux... - my $devnum = $1; - my ($dev,$baud,$break,$flow) = split /,/,$curarg; - $baud = "115" unless defined $baud; - $break = 1 unless defined $break; # default: break - $flow = 1 unless defined $flow; # default: cts - - if ($baud !~ m{^\d*$} || $break !~ m{^[01]$} || $flow !~ m{^[012]$}) { - print STDERR "dorri-E: invalid format of -u option\n"; - exit 1; - } - - my $baudrate; - if (defined $baudtbl{$baud}) { - $baudrate = $baudtbl{$baud}; - } else { - print STDERR "dorri-E: invalid baudrate specification $baud\n"; - exit 1; - } - $opt_io = "t"; - $val_term = sprintf "/dev/ttyUSB%d,%d,%d,%d", - $devnum, $baudrate, $break, $flow; - shift @ARGV; - - } elsif ($curarg =~ m{^-e$} ) { # -e - print STDERR "dorri-W: multiple -e options, only last taken\n" - if defined $val_e; - shift @ARGV; - if (scalar(@ARGV) == 0 || $ARGV[0] =~ m{^-}) { - print STDERR "dorri-E: no file name after -e option\n"; - exit 1; - } else { - $val_e = shift @ARGV; - if (not -r $val_e) { - print STDERR "dorri-E: file '$val_e' not found\n"; - exit 1; - } - } - } else { - last; - } -} - -# -# rename old log file -# -if (-r $val_log) { - my $old_log = $val_log; - $old_log =~ s{\.log}{\.old\.log}; - rename $val_log, $old_log - or die "failed to rename: $!"; -} - -# -# check that either -s3/n2/n3 or -t given -# setup pi_rri options for either case -# - -if ($opt_io eq "f") { - push @arglist, "--fifo"; - push @arglist, "--run"; - push @arglist, $val_tb; -} elsif ($opt_io eq "t") { - push @arglist, "--term=$val_term"; -} else { - print STDERR "dorri-E: neither -s3/-n2/-n3 nor -t or -u specified\n"; - print_usage(); - exit 1; -} - -# -# setup all other options -# - -push @arglist, "--timeout=$val_time"; -push @arglist, "--cmax=$val_cmax"; -push @arglist, "--log=$val_log"; -push @arglist, "--dserv"; -push @arglist, "--tserv"; -push @arglist, "--int" unless $opt_b; - -if (defined $val_e) { - push @arglist, ".mode serv11"; - push @arglist, "ldabs $val_e"; - push @arglist, "set sim tmu 1" if $opt_tmu; - push @arglist, "start 200"; -} - -while (scalar(@ARGV)) { - my $curarg = shift @ARGV; - if ($curarg =~ m{^@(.*)$} && ! -r $1) { - print STDERR "dorri-E: file '$1' not found\n"; - exit 1; - } - push @arglist,$curarg; -} - -if (defined $val_e) { - push @arglist, "server"; -} - -# -# find pi_rri executable -# - -$pirri=`which pi_rri`; -chomp $pirri; -if ($pirri eq "" || ! -e $pirri) { - print STDERR "dorri-E: failed to locate pi_rri\n"; - exit 1; -} - -# -# print command file -# -if (1) { - print "pi_rri ", join (" ", map {(m{\s}) ? "\"$_\"" : $_} @arglist) , "\n"; -} - -# -# and do it -# -exec $pirri, @arglist - or die "failed to exec: $!"; - -exit 1; - -# ---------------------------------------------------------------------------- -sub print_usage { - print "usage: dorri [-f] [-t] [-u(123) [-e file] ...\n"; -} diff --git a/rtl/sys_gen/w11a/tb/uv5_boot.pcmd b/rtl/sys_gen/w11a/tb/uv5_boot.pcmd deleted file mode 100644 index 3cd69ea9..00000000 --- a/rtl/sys_gen/w11a/tb/uv5_boot.pcmd +++ /dev/null @@ -1,22 +0,0 @@ -; $Id: uv5_boot.pcmd 312 2010-07-04 18:25:58Z mueller $ -; -; Setup file for Unix V5 System -; -; Usage: -; -; telnet_starter -d DL0 & -; -; dorri -s3 @uv5_boot.pcmd (for ghdl sim of tb_w11a_s3) -; dorri -n2 @uv5_boot.pcmd (for ghdl sim of tb_w11a_n2) -; -; dorri -t @uv5_boot.pcmd (fpga link via /dev/ttyS0) -; dorri -u0,460 @uv5_boot.pcmd (fpga link via /dev/ttyUSB0) -; -.mode serv11 -; -att TT0 8000 -; -reset -att rk0 unix_v5_rk.dsk -boot rk0 -server diff --git a/rtl/sys_gen/w11a/tb/uv5_boot.tcl b/rtl/sys_gen/w11a/tb/uv5_boot.tcl deleted file mode 100644 index d0bae991..00000000 --- a/rtl/sys_gen/w11a/tb/uv5_boot.tcl +++ /dev/null @@ -1,29 +0,0 @@ -# $Id: uv5_boot.tcl 511 2013-04-27 13:51:46Z mueller $ -# -# Setup file for Unix V5 System -# -# Usage: -# -# telnet_starter -d DL0 & -# torri -xxx @uv5_boot.tcl ( -xxx depends on sim or fpga connect) - -# setup w11 cpu -puts [rlw] - -# 2.11 bsd uses parity, so strip it -cpu0tta0 set to7bit 1 - -# setup tcp links for terminals -cpu0tta0 att "tcp:?port=8000" - -# setup log files -cpu0tta0 set log "tt_dl0.log?crlf" - -# mount disks -cpu0rka0 att unix_v5_rk.dsk - -# and boot -#cpu0rka set trace 1 -rw11::cpumon -rw11::cpucons -cpu0 boot rka0 diff --git a/tools/bin/pi_rri b/tools/bin/pi_rri deleted file mode 100755 index 034dd478..00000000 --- a/tools/bin/pi_rri +++ /dev/null @@ -1,7269 +0,0 @@ -#!/usr/bin/perl -w -# $Id: pi_rri 499 2013-03-24 20:26:18Z mueller $ -# -# Copyright 2007-2011 by Walter F.J. Mueller -# -# This program is free software; you may redistribute and/or modify it under -# the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 2, or at your option any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for complete details. -# -# Revision History: -# Date Rev Version Comment -# 2011-12-18 440 1.6.6 add xon/xoff flow control support -# 2011-12-04 435 1.6.5 add control over flow control (cts or none) -# 2011-09-17 410 1.6.4 use for crc8 now a6 polynomial -# 2010-12-29 351 1.6.3 rename rriext->cext and cpmon->rlmon -# 2010-06-27 310 1.6.2 fix autoflush for fh_log; duplicate exec err to log -# 2010-06-18 306 1.6.1 PDPCP_ADDR_IBRB now 020, PDPCP_ADDR_IBR now 0200; -# ibrbase now just drops the 6 lsb's; pdpcp mode: -# rename librb -> wibrb; finished cp/rri overhaul -# 2010-06-13 305 1.6 change PDPCP_ADDR_ assignments, add PDPCP_FUNC_ -# constants; adapt pdpcp mode to changed rri addr and -# stim file format; emulate old 'sta' behaviour with -# new 'stapc' command; rename lal,lah -> wal,wah and -# implement locally; adapt serv11 mode to new rri -# 2010-06-11 303 1.5.1 add cmd_inter; flush{"line"} after interactive cmd -# added readline support. -# 2010-06-07 302 1.5 use sop/eop framing instead of soc+chaining -# 2010-06-06 301 1.4.18 rename .rpmon->.rbmon; NCOMM=4 (new eop,nak commas) -# 2010-06-03 299 1.4.17 adapt .reset to new rbus init decode -# 2010-05-05 288 1.4.16 first preliminary implementation of eval based -# perl macro's via @@pmac; add ^C signal handler; -# added optional min/max check for cget_gdat() and -# cget_tagval_gdat(). -# 2010-05-02 287 1.4.15 enable hardware flow control in termios -# 2010-05-01 286 1.4.14 add .sinit command for rri and pdpcp modes; -# add 500k,1M,2M,3M baudrates, check value now -# 2010-04-26 284 1.4.13 add error check for GetOptions -# 2010-04-25 283 1.4.12 raw_rcv9_to: handle undef as return value correctly -# 2009-10-11 244 1.4.11 support > 115kbaud speed; new stat output in log; -# use nxbuf_max=8 as default; -# 2009-09-27 242 1.4.10 add "ERR --" messages in log file; fix usage of -# uninitialized vars in serv11_exec_probe(); -# 2009-09-25 241 1.4.9 BUGFIX: serv11_server_attn_get() now or's attn bits -# 2009-09-20 240 1.4.8 serv11_rri_uset cache under $ctl, not in unittbl -# 2009-09-13 238 1.4.7 add ctlname for DL11 log entries; only TTA output -# written to stdout when no terminal attached. -# 2009-07-26 236 1.4.6 fix cpraw mode and .mode error handling; -# 2009-07-12 233 1.4.5 add attach/detach support for term; telnet support; -# 2009-07-05 232 1.4.4 add cchk_number(), cget_regrange(); rename _atdt_ to -# _attdet_; serv11: add exa/dep command; removed -# rr[0-7], wr[0-7], rmem, and wmem commands; new probe -# handling, use {probe_[ir]val} and {probemask}; -# serv11: command parser supports abbeviations; -# serv11: add set/sho command, reorganize ls* cmds; -# serv11: add {trace} parameter; rri_sideband() flush; -# 2009-07-04 231 1.4.3 first reglist definitions; add CPU in _ctltbl; -# add serv11_probe_cpu(); -# 2009-06-28 230 1.4.2 use serv11_atdt_pc11(), remove atdt via ucb hack; -# add serv11_rri_uset(); pc11 now fully supported; -# attn log message now gives device; use -e as file -# test; add ptape boot mode support; lsconf output -# sorted by ibus address; -# 2009-06-21 228 1.4.1 BUGFIX: correct typo in RK6 ucb; reorganize init -# handling, introduce usethdl; reorganize attach; -# add atdthdl at ctl or ucb level; add det command; -# 2009-06-20 227 1.4 nxbuf_min,max,inc now a ctl property; -# 2009-06-14 226 1.3.31 add very preliminary lp11 device handling -# 2009-06-11 225 1.3.30 quick hack to add dl11 log files. -# 2009-05-30 220 1.3.29 add papertape boot code; -# 2009-05-24 219 1.3.28 add papertape hook as dev "PC" units "PTR" and "PTP" -# 2009-05-21 217 1.3.27 rk11: now error message when init not done -# 2009-05-17 216 1.3.26 BUGFIX:rk11: fix read/write logic for short sectors; -# BUGFIX:rk11: re-work the seek complete handling -# add read/write check support; add PGE error support; -# 2009-05-13 215 1.3.25 dl11: drop parity bit in transmit path; -# rk11: add read/write format; set SOK at init time; -# 2009-05-10 214 1.3.24 BUGFIX: in serv11_attn_rk11() RKER was written -# instead of RKMR for RKCS_DRESET, _WLOCK, _SEEK -# 2009-04-11 206 1.3.23 add --int to force interactive mode -# fix handling of odd length records in lsabs -# 2008-12-14 177 1.3.22 correct DL11_BASE_B to 176500 (was RL address) -# 2008-11-28 173 1.3.21 serv11_rri_lalh(): allow now mode =0,1,2 and 3; -# serv11_rdma_rk11(): use mode=3 in rri_lalh, thus -# enable 22bit and ubmap simultaneously. -# add proper MEX update for RKCS in rdma_rk11. -# add proper DRSEL propagation for RKDA in rdma_rk11. -# 2008-05-30 151 1.3.20 BUGFIX: corrected @que_rcv logic in serv11 input -# loop, TT0 output will not longer hang sometimes; -# disable the attn+ioto(16 or 63 ms) hack; -# 2008-05-23 150 1.3.19 tio[89b] messages: to $fh_log now, add delta-time; -# fixes in disk extend logic and messages; add the -# (^c form of ( command; add adaptive read vector -# in serv11_attn_dl11; -# 2008-05-22 149 1.3.18 add term_tios_print, fixes for --term under cygwin; -# 2008-05-22 148 1.3.17 add (,< short-cut commands -# 2008-05-18 147 1.3.16 ATTN comma drop now warning, -W (was -I); -# 2008-05-12 145 1.3.15 rename ldpta -> ldabs -# 2008-05-09 144 1.3.14 disable call in attn_dispatch(1) (needs busy logic) -# 2008-05-01 142 1.3.13 serv11: add stop,cont,reset; add $force for attn -# handlers; use attn+ioto(16ms) to avoid TTO hangs -# 2008-05-01 141 1.3.12 write TTO char-by-char now to STDOUT -# 2008-04-25 138 1.3.11 show ccc/scc for code 000257/000277 in disassembler -# 2008-04-19 137 1.3.10 minor fix disassembler: use f reg prefix for f4,f5 -# 2008-04-18 136 1.3.9 hack in a poor man's output to console... -# 2008-04-13 135 1.3.8 substitute environment variables in cmd file names -# 2008-04-11 134 1.3.7 allow line comments starting with ";" (for simh) -# 2008-04-06 133 1.3.6 fix file check in serv11_cexec_ldpta; fix wrong -# opcode for mfps; fixed bug in disassembling mode=77 -# add -a for lsmem; -# 2008-04-04 132 1.3.5 add in disassembler non-11/70 and fpp codes; -# add (>|>>)file option for lsmem (redirect to file) -# 2008-03-39 131 1.3.4 lsmem -m: use now wide (3 word) symbolic dump format -# add ldpta command (load paper tape abs format) -# add start and step command -# 2008-03-24 129 1.3.3 allow comments when in serv11 server mode. -# check attach file size; zero-fill after partial -# block write; reorganize dsk file and rdma handling -# leading blanks now ignored in commands -# 2008-03-22 128 1.3.2 fully functional server mode (todo: TT <-> telnet) -# 2008-03-19 127 1.3.1 very preliminary server mode now working -# 2008-03-09 124 1.3 add serv11 mode; add PDP11 disamssebler -# 2008-03-02 121 1.2.5 the default .sdef now checks for hard errors. -# the _open handlers for rri and pdpcp setup default -# Add .cerr, .merr as ignored directives for pdpcp -# 2008-02-24 119 1.2.4 added lah,rps,wps command in .pdpcp mode -# 2008-02-16 116 1.2.3 add librb,[rw]ibr,and wtlam to pdpcp command set -# 2007-12-25 105 1.2.2 for rri mode add .dbas[io] (set base for data vals) -# add ${par}, ${par:=val}, ${par:-val} substitution -# allow parameter definition via par=val lines -# add $[..perl code..] escape to embed perl code -# allow @file(arg1,arg2,arg3,...); print .wtlam wait -# 2007-11-24 98 1.2.1 adapt to new rri internal init handling -# 2007-11-18 96 1.2 add 'read before write' logic to avoid deadlocks -# under cygwin broken fifo (size=1 !) implementation -# 2007-10-12 88 1.1.4 fix some -w issues -# 2007-09-23 84 1.1.3 .reset command in pdpcp mode; keep-alive in --fifo -# 2007-09-16 83 1.1.2 add --cmax; full --term implemented -# 2007-09-09 80 1.1.1 add --run; modularize I/O handling; initial --term -# proper return code / retry loop for sysread/write -# 2007-09-09 80 1.1 new non-blocking/blocking handling; ignore IDLE's -# and unexpected ATTN commas; add _flush; add -# data check handling, command chaining, 'pdpcp' mode. -# 2007-09-02 79 1.0.1 implement 'rri' mode -# 2007-09-01 78 1.0 Initial version - -use 5.005; # require Perl 5.005 or higher -use strict; # require strict checking - -use FileHandle; -use POSIX qw(mkfifo isatty :termios_h); -use Fcntl qw(O_WRONLY O_RDONLY O_NOCTTY); -use Errno qw(EINTR); -use Time::HiRes qw(gettimeofday); -use Socket; -use Term::ReadLine; - -use constant CPREF => 0x80; -use constant NCOMM => 4; -use constant CESC => CPREF|0x0f ; -use constant CEN1 => (~CPREF)&0xf0; -use constant D9IDLE => 0x100; -use constant D9SOP => 0x101; -use constant D9EOP => 0x102; -use constant D9NAK => 0x103; -use constant D9ATTN => 0x104; - -use constant KC_XON => 0x11; # XON char -> ^Q = hex 11 -use constant KC_XOFF => 0x13; # XOFF char -> ^S = hex 13 -use constant KC_XESC => 0x1b; # XESC char -> ^[ = ESC = hex 1B - -use constant PDPCP_ADDR_CONF => 000; -use constant PDPCP_ADDR_CNTL => 001; -use constant PDPCP_ADDR_STAT => 002; -use constant PDPCP_ADDR_PSW => 003; -use constant PDPCP_ADDR_AL => 004; -use constant PDPCP_ADDR_AH => 005; -use constant PDPCP_ADDR_MEM => 006; -use constant PDPCP_ADDR_MEMI => 007; -use constant PDPCP_ADDR_R0 => 010; -use constant PDPCP_ADDR_PC => 017; -use constant PDPCP_ADDR_IBRB => 020; -use constant PDPCP_ADDR_IBR => 0200; - -use constant PDPCP_FUNC_NOOP => 000; -use constant PDPCP_FUNC_STA => 001; -use constant PDPCP_FUNC_STO => 002; -use constant PDPCP_FUNC_CONT => 003; -use constant PDPCP_FUNC_STEP => 004; -use constant PDPCP_FUNC_RST => 017; - -use constant LINUX_B57600 => 0010001; # B57600 not part of POSIX package ! -use constant LINUX_B115200 => 0010002; # in linux these values are in -use constant LINUX_B230400 => 0010003; # termios.h, specifically in -use constant LINUX_B460800 => 0010004; # /usr/include/bits/termios.h -use constant LINUX_B500000 => 0010005; -use constant LINUX_B576000 => 0010006; -use constant LINUX_B921600 => 0010007; -use constant LINUX_B1000000 => 0010010; -use constant LINUX_B2000000 => 0010013; -use constant LINUX_B3000000 => 0010015; - -use constant LINUX_CRTSCTS => 020000000000; # ! Not part of POSIX !! - -use Getopt::Long; - -my %opts = (); - -GetOptions(\%opts, "help", "int", "trace", - "tio8", "tio9", "tiob", - "dserv", "tserv", "log:s", - "fifo:s", "term:s", - "timeout=f", "cmax=i", - "run=s", - ) - or die "bad options"; - -sub init_regtbl; # initialize regtbl from reglist -sub get_command; -sub do_command; -sub read_command; -sub setpar_command; -sub nomode_open; -sub nomode_flush; -sub nomode_close; -sub nomode_cexec; -sub cpraw_open; -sub cpraw_flush; -sub cpraw_close; -sub cpraw_cexec; -sub do_cprx; -sub do_cptx; -sub cpraw_tx_match_now; -sub cpraw_tx_match; -sub rri_open; -sub rri_flush; -sub rri_close; -sub rri_cexec; -sub rri_cget_stat; -sub rri_cget_addr; -sub rri_cget_nblk; -sub rri_sideband; -sub rri_cmdlist_do; -sub rri_cmdlist_dump; -sub rri_cmdlist_exec; -sub rri_cmdlist_check_stat; -sub rri_cmdlist_get_rval; -sub rri_cmdlist_conv_rval; -sub rri_ref_check; # check reference data (1=err) -sub pdpcp_open; -sub pdpcp_flush; -sub pdpcp_close; -sub pdpcp_cexec; -sub pdpcp_cmd_rreg; -sub pdpcp_cmd_wreg; -sub serv11_open; -sub serv11_flush; -sub serv11_close; -sub serv11_cexec; -sub serv11_cexec_shoreg; -sub serv11_cexec_shommu_ssrx; -sub serv11_cexec_shommu_sadr; -sub serv11_cexec_ldabs; -sub serv11_cexec_shoconf; -sub serv11_cexec_shoatt; -sub serv11_cexec_attdet; -sub serv11_cexec_boot; -sub serv11_cexec_exa; -sub serv11_cexec_dep; -sub serv11_config; -sub serv11_init_dispatch; -sub serv11_server; -sub serv11_server_attn_get; -sub serv11_server_attn_dispatch; -sub serv11_probe_gen; # generic probe handler -sub serv11_init_gen; # generic controller init handler -sub serv11_detach_gen; # generic detach handler -sub serv11_attdet_disk; # generic disk att/det handler -sub serv11_attdet_ronly; # generic in only att/det handler -sub serv11_attdet_wonly; # generic out only att/det handler -sub serv11_attdet_term; # generic term att/det handler -sub serv11_probe_cpu; # cpu: probe handler -sub serv11_attn_cpu; # cpu: attention handler -sub serv11_exadep_cpu; # cpu: exa/dep handler -sub serv11_ichr_dl11; -sub serv11_attn_dl11; -sub serv11_uset_lp11; -sub serv11_attn_lp11; -sub serv11_uset_pc11; -sub serv11_attdet_pc11; -sub serv11_attn_pc11; -sub serv11_uset_rk11; -sub serv11_attn_rk11; -sub serv11_attn_rk11_logerr; -sub serv11_rdma_rk11; -sub serv11_icb_disk_read; # read one dsk file block -sub serv11_icb_disk_write; # write one dsk file block -sub serv11_rri_init; # issue rri init command -sub serv11_rri_attn; # issue rri attn command -sub serv11_rri_stat; # issue rri stat command -sub serv11_rri_rreg; # issue rri rreg command -sub serv11_rri_wreg; # issue rri wreg command -sub serv11_rri_rblk; # issue rri rblk command -sub serv11_rri_wblk; # issue rri wblk command -sub serv11_rri_lalh; # issue pdpcp lal and lah commands -sub serv11_rri_ibrb; # issue rbus set base address -sub serv11_rri_ribr; # issue rbus read -sub serv11_rri_wibr; # issue rbus write -sub serv11_rri_clear; -sub serv11_rri_exec; -sub serv11_rri_uset; # issue rbus uset writes -sub serv11_exec_rblk; -sub serv11_exec_wblk; -sub serv11_exec_probe; -sub next_nxbuf; # calculate next nxbuf value -sub telnet_readhdl; # telnet: socket read handler -sub telnet_writehdl; # telnet: write handler -sub pdp11_disassemble; # simple PDP11 disassembler -sub pdp11_disassemble_regmod; # helper -sub file_seek; # fseek wrapper -sub file_read; # fread wrapper -sub file_seek_read; # fseek+fread wrapper -sub file_write; # fwrite wrapper -sub file_seek_write; # fseek+fwrite wrapper -sub raw_get9_crc_16bit; # read 16 bit value -sub raw_get9_crc_8bit; # read 8bit value -sub raw_get9_crc_check; # get 9bit, block, crc, ref value -sub raw_get9_check; # get 9bit, block, expect ref value -sub raw_get9_checksop; # get 9bit, block, expect 'sop' -sub raw_get9_checkeop; # get 9bit, block, expect 'eop' -sub raw_get9_crc; # get 9bit, block, update crc -sub raw_get9; # get 9bit, block -sub raw_snd9_crc; # put 9bit to RX, update crc -sub raw_snd9; # put 9bit to RX -sub raw_snd8; # put 8bit to RX -sub raw_rcv9; # get 9bit from TX, non-blocking -sub raw_rcv8; # get 8bit from TX, non-blocking -sub raw_rcv9_to; # get 9bit from TX, expl. time-out -sub raw_rcv8_to; # get 8bit from TX, expl. time-out -sub wait_sel_filercv; # poll/wait for RCV to be ready -sub fifo_open; # chan fifo: open handler -sub fifo_close; # chan fifo: close handler -sub term_open; # chan term: open handler -sub term_close; # chan term: close handler -sub term_tios_print; # chan term: print termios state -sub genio_read; # generic io: read handler -sub genio_write; # generic io: write handler -sub cget_chkblank; # check for unused chars in cmd line -sub cget_tagval2_gdat; # get tag=v1[,v2], generic base -sub cget_tagval_gdat; # get tag=val, generic base -sub cget_gdat; # get generic base value -sub cget_name; # get name \w+ -sub cget_bool; # get boolean [01] -sub cget_file; # get filename [\w\/.]+ -sub cget_ucb; # get ucb (read name, return ucb) -sub cget_opt; # get option -sub cget_optset; # get option set -sub cget_regrange; # get register/memory range -sub cchk_number; # check for number. any gdat value -sub sget_bdat; # convert 01 string -> binary value -sub conv_etime; # generate timestamp string -sub conv_dat9; -sub conv_dat8; -sub conv_str2bytes; # string to bytelist; handle \n -sub conv_buf2wlist; # string buffer -> word list -sub conv_wlist2buf; # word list -> string buffer -sub conv_byte2ascii2; # byte -> 2 charcter ASCII display -sub gconv_dat16; -sub hdl_sigint; # SIGINT handler -sub get_time; -sub get_timestamp; -sub filename_expand; # expand $nnn in name -sub print_fatal; -sub print_help; - -my %stat_tab = ( obyte => 0., - oesc => 0., - osop => 0., - ibyte => 0., - iesc => 0., - att => 0., - xreg => 0., - xblk => 0., - rdisk => 0., - wdisk => 0.); -my %stat_tab_last = %stat_tab; - -my %mode_tab = (nomode => {open => \&nomode_open, - flush => \&nomode_flush, - close => \&nomode_close, - cmd => \&nomode_cexec}, - cpraw => {open => \&cpraw_open, - flush => \&cpraw_flush, - close => \&cpraw_close, - cmd => \&cpraw_cexec}, - rri => {open => \&rri_open, - flush => \&rri_flush, - close => \&rri_close, - cmd => \&rri_cexec}, - pdpcp => {open => \&pdpcp_open, - flush => \&pdpcp_flush, - close => \&pdpcp_close, - cmd => \&pdpcp_cexec}, - serv11 => {open => \&serv11_open, - flush => \&serv11_flush, - close => \&serv11_close, - cmd => \&serv11_cexec} - ); - -my %chan_tab = (fifo => {open => \&fifo_open, - close => \&fifo_close, - read => \&genio_read, - write => \&genio_write}, - term => {open => \&term_open, - close => \&term_close, - read => \&genio_read, - write => \&genio_write} - ); - -my $curmode = "nomode"; -my $curcmd = \&nomode_cexec; -my $curchan = undef; -my @cmdfh; -my @cmdfn; -my @cmdargs; -my $time0 = -1; -my $tlast_tio8 = 0; -my $tlast_tio9 = 0; -my $tlast_tiob = 0; - -my @que_rcv; -my @que_snd; - -my @cpraw_tx_read; -my @cpraw_tx_expt; - -my $fh_log = *STDOUT; -my $fh_snd; -my $fh_rcv; -my $fdset_filercv; -my $fifo_keep; -my $term_oldtios; -my $raw_rcv_esc = 0; -my $raw_timeout = 1.; -my $cmax = 16; - -my $xesc_enable = 0; # enables xon/xoff/xesc escaping -my $xesc_pending = 0; # xesc pending on receive - -my $cmd_line; -my $cmd_rest; -my $cmd_bad; -my $cmd_inter; # interactive cmd flag - -my $term; -if (-t STDIN) { - $term = new Term::ReadLine 'pi_rri'; -} - -my %par; # params for command line substitution -my $sigint_count = 0; # SIGINT counter - -use constant TELNET_CODE_NULL => 0; -use constant TELNET_CODE_LF => 10; -use constant TELNET_CODE_CR => 13; -use constant TELNET_CODE_ESC => 27; -use constant TELNET_CODE_SE => 240; -use constant TELNET_CODE_NOP => 241; -use constant TELNET_CODE_IP => 244; -use constant TELNET_CODE_GA => 249; -use constant TELNET_CODE_SB => 250; -use constant TELNET_CODE_WILL => 251; -use constant TELNET_CODE_WONT => 252; -use constant TELNET_CODE_DO => 253; -use constant TELNET_CODE_DONT => 254; -use constant TELNET_CODE_IAC => 255; - -use constant TELNET_OPT_BIN => 0; -use constant TELNET_OPT_ECHO => 1; -use constant TELNET_OPT_SGA => 3; -use constant TELNET_OPT_TTYP => 24; -use constant TELNET_OPT_LINE => 34; - -use constant TELNET_STATE_LISTEN => -1; -use constant TELNET_STATE_STREAM => 0; -use constant TELNET_STATE_IAC => 1; -use constant TELNET_STATE_CMD => 2; -use constant TELNET_STATE_SUBNEG => 3; -use constant TELNET_STATE_SUBIAC => 4; - -# -# %telnettbl->{snum} --> telnet session table, hash of hashes, key'ed by port -# -> {port} port number (int) -# -> {state} state: (_LISTEN|_STREAM|_IAC|_CMD|_SUBNEG|_SUBIAC) -# -> {fh_port} file handle of port socket (for listen) -# -> {fh_data} file handle of data socket -# -> {ucb} ucb the port is attached to -# - -my %telnettbl; - -my $rri_ref_sdef = 0x00; # by default check for 'hard' errors -my $rri_msk_sdef = 0xf0; # ignore the status bits + attn flag -my %rri_amtbl; -my @rri_cmdlist; -my $rri_rvalcnt = 0; -my $rri_ncmdmax = undef; -my $rri_dbasi = 2; # default input base -my $rri_dbaso = 8; # default output base -my $rri_nodfill = " " x 5; # filler string for "d=-" stanzas - -my %rri_cname2cmd = (rreg => 0, # c_rri_cmd_rreg : slv3 := "000"; - rblk => 1, # c_rri_cmd_rblk : slv3 := "001"; - wreg => 2, # c_rri_cmd_wreg : slv3 := "010"; - wblk => 3, # c_rri_cmd_wblk : slv3 := "011"; - stat => 4, # c_rri_cmd_stat : slv3 := "100"; - attn => 5, # c_rri_cmd_attn : slv3 := "101"; - init => 6); # c_rri_cmd_init : slv3 := "110"; - -my @crc8_tbl = ( 0, 77, 154, 215, 121, 52, 227, 174, # from gen_crc8_tbl - 242, 191, 104, 37, 139, 198, 17, 92, - 169, 228, 51, 126, 208, 157, 74, 7, - 91, 22, 193, 140, 34, 111, 184, 245, - 31, 82, 133, 200, 102, 43, 252, 177, - 237, 160, 119, 58, 148, 217, 14, 67, - 182, 251, 44, 97, 207, 130, 85, 24, - 68, 9, 222, 147, 61, 112, 167, 234, - 62, 115, 164, 233, 71, 10, 221, 144, - 204, 129, 86, 27, 181, 248, 47, 98, - 151, 218, 13, 64, 238, 163, 116, 57, - 101, 40, 255, 178, 28, 81, 134, 203, - 33, 108, 187, 246, 88, 21, 194, 143, - 211, 158, 73, 4, 170, 231, 48, 125, - 136, 197, 18, 95, 241, 188, 107, 38, - 122, 55, 224, 173, 3, 78, 153, 212, - 124, 49, 230, 171, 5, 72, 159, 210, - 142, 195, 20, 89, 247, 186, 109, 32, - 213, 152, 79, 2, 172, 225, 54, 123, - 39, 106, 189, 240, 94, 19, 196, 137, - 99, 46, 249, 180, 26, 87, 128, 205, - 145, 220, 11, 70, 232, 165, 114, 63, - 202, 135, 80, 29, 179, 254, 41, 100, - 56, 117, 162, 239, 65, 12, 219, 150, - 66, 15, 216, 149, 59, 118, 161, 236, - 176, 253, 42, 103, 201, 132, 83, 30, - 235, 166, 113, 60, 146, 223, 8, 69, - 25, 84, 131, 206, 96, 45, 250, 183, - 93, 16, 199, 138, 36, 105, 190, 243, - 175, 226, 53, 120, 214, 155, 76, 1, - 244, 185, 110, 35, 141, 192, 23, 90, - 6, 75, 156, 209, 127, 50, 229, 168); - -my $ocrc = 0; -my $icrc = 0; -my $kpid = -1; - -my @pdp11_opcode_tbl = ( - {code=>0000000, mask=>0000000, name=>"halt", type=>"0arg"}, - {code=>0000001, mask=>0000000, name=>"wait", type=>"0arg"}, - {code=>0000002, mask=>0000000, name=>"rti ", type=>"0arg"}, - {code=>0000003, mask=>0000000, name=>"bpt ", type=>"0arg"}, - {code=>0000004, mask=>0000000, name=>"iot ", type=>"0arg"}, - {code=>0000005, mask=>0000000, name=>"reset",type=>"0arg"}, - {code=>0000006, mask=>0000000, name=>"rtt ", type=>"0arg"}, - {code=>0000007, mask=>0000000, name=>"!!mfpt", type=>"0arg"}, - {code=>0000100, mask=>0000077, name=>"jmp ", type=>"1arg"}, - {code=>0000200, mask=>0000007, name=>"rts ", type=>"1reg"}, - {code=>0000230, mask=>0000007, name=>"spl ", type=>"spl"}, - {code=>0000240, mask=>0000017, name=>"cl", type=>"ccop"}, - {code=>0000260, mask=>0000017, name=>"se", type=>"ccop"}, - {code=>0000300, mask=>0000077, name=>"swap", type=>"1arg"}, - {code=>0000400, mask=>0000377, name=>"br ", type=>"br"}, - {code=>0001000, mask=>0000377, name=>"bne ", type=>"br"}, - {code=>0001400, mask=>0000377, name=>"beq ", type=>"br"}, - {code=>0002000, mask=>0000377, name=>"bge ", type=>"br"}, - {code=>0002400, mask=>0000377, name=>"blt ", type=>"br"}, - {code=>0003000, mask=>0000377, name=>"bgt ", type=>"br"}, - {code=>0003400, mask=>0000377, name=>"ble ", type=>"br"}, - {code=>0004000, mask=>0000777, name=>"jsr ", type=>"jsr"}, - {code=>0005000, mask=>0000077, name=>"clr ", type=>"1arg"}, - {code=>0005100, mask=>0000077, name=>"com ", type=>"1arg"}, - {code=>0005200, mask=>0000077, name=>"inc ", type=>"1arg"}, - {code=>0005300, mask=>0000077, name=>"dec ", type=>"1arg"}, - {code=>0005400, mask=>0000077, name=>"neg ", type=>"1arg"}, - {code=>0005500, mask=>0000077, name=>"adc ", type=>"1arg"}, - {code=>0005600, mask=>0000077, name=>"sbc ", type=>"1arg"}, - {code=>0005700, mask=>0000077, name=>"tst ", type=>"1arg"}, - {code=>0006000, mask=>0000077, name=>"ror ", type=>"1arg"}, - {code=>0006100, mask=>0000077, name=>"rol ", type=>"1arg"}, - {code=>0006200, mask=>0000077, name=>"asr ", type=>"1arg"}, - {code=>0006300, mask=>0000077, name=>"asl ", type=>"1arg"}, - {code=>0006400, mask=>0000077, name=>"mark", type=>"mark"}, - {code=>0006500, mask=>0000077, name=>"mfpi", type=>"1arg"}, - {code=>0006600, mask=>0000077, name=>"mtpi", type=>"1arg"}, - {code=>0006700, mask=>0000077, name=>"sxt ", type=>"1arg"}, - {code=>0007000, mask=>0000077, name=>"!!csm", type=>"1arg"}, - {code=>0007200, mask=>0000077, name=>"!!tstset",type=>"1arg"}, - {code=>0007300, mask=>0000077, name=>"!!wrtlck",type=>"1arg"}, - {code=>0010000, mask=>0007777, name=>"mov ", type=>"2arg"}, - {code=>0020000, mask=>0007777, name=>"cmp ", type=>"2arg"}, - {code=>0030000, mask=>0007777, name=>"bit ", type=>"2arg"}, - {code=>0040000, mask=>0007777, name=>"bic ", type=>"2arg"}, - {code=>0050000, mask=>0007777, name=>"bis ", type=>"2arg"}, - {code=>0060000, mask=>0007777, name=>"add ", type=>"2arg"}, - {code=>0070000, mask=>0000777, name=>"mul ", type=>"rdst"}, - {code=>0071000, mask=>0000777, name=>"div ", type=>"rdst"}, - {code=>0072000, mask=>0000777, name=>"ash ", type=>"rdst"}, - {code=>0073000, mask=>0000777, name=>"ashc", type=>"rdst"}, - {code=>0074000, mask=>0000777, name=>"xor ", type=>"rdst"}, - {code=>0077000, mask=>0000777, name=>"sob ", type=>"sob"}, - {code=>0100000, mask=>0000377, name=>"bpl ", type=>"br"}, - {code=>0100400, mask=>0000377, name=>"bmi ", type=>"br"}, - {code=>0101000, mask=>0000377, name=>"bhi ", type=>"br"}, - {code=>0101400, mask=>0000377, name=>"blos", type=>"br"}, - {code=>0102000, mask=>0000377, name=>"bvc ", type=>"br"}, - {code=>0102400, mask=>0000377, name=>"bvs ", type=>"br"}, - {code=>0103000, mask=>0000377, name=>"bcc ", type=>"br"}, - {code=>0103400, mask=>0000377, name=>"bcs ", type=>"br"}, - {code=>0104000, mask=>0000377, name=>"emt ", type=>"trap"}, - {code=>0104400, mask=>0000377, name=>"trap", type=>"trap"}, - {code=>0105000, mask=>0000077, name=>"clrb", type=>"1arg"}, - {code=>0105100, mask=>0000077, name=>"comb", type=>"1arg"}, - {code=>0105200, mask=>0000077, name=>"incb", type=>"1arg"}, - {code=>0105300, mask=>0000077, name=>"decb", type=>"1arg"}, - {code=>0105400, mask=>0000077, name=>"negb", type=>"1arg"}, - {code=>0105500, mask=>0000077, name=>"adcb", type=>"1arg"}, - {code=>0105600, mask=>0000077, name=>"sbcb", type=>"1arg"}, - {code=>0105700, mask=>0000077, name=>"tstb", type=>"1arg"}, - {code=>0106000, mask=>0000077, name=>"rorb", type=>"1arg"}, - {code=>0106100, mask=>0000077, name=>"rolb", type=>"1arg"}, - {code=>0106200, mask=>0000077, name=>"asrb", type=>"1arg"}, - {code=>0106300, mask=>0000077, name=>"aslb", type=>"1arg"}, - {code=>0106400, mask=>0000077, name=>"!!mtps", type=>"1arg"}, - {code=>0106500, mask=>0000077, name=>"mfpd", type=>"1arg"}, - {code=>0106600, mask=>0000077, name=>"mtpd", type=>"1arg"}, - {code=>0106700, mask=>0000077, name=>"!!mfps", type=>"1arg"}, - {code=>0110000, mask=>0007777, name=>"movb", type=>"2arg"}, - {code=>0120000, mask=>0007777, name=>"cmpb", type=>"2arg"}, - {code=>0130000, mask=>0007777, name=>"bitb", type=>"2arg"}, - {code=>0140000, mask=>0007777, name=>"bicb", type=>"2arg"}, - {code=>0150000, mask=>0007777, name=>"bisb", type=>"2arg"}, - {code=>0160000, mask=>0007777, name=>"sub ", type=>"2arg"}, - {code=>0170000, mask=>0000000, name=>"!!cfcc", type=>"0arg"}, - {code=>0170001, mask=>0000000, name=>"!!setf", type=>"0arg"}, - {code=>0170011, mask=>0000000, name=>"!!setd", type=>"0arg"}, - {code=>0170002, mask=>0000000, name=>"!!seti", type=>"0arg"}, - {code=>0170012, mask=>0000000, name=>"!!setl", type=>"0arg"}, - {code=>0170100, mask=>0000077, name=>"!!ldfps",type=>"1fpp"}, - {code=>0170200, mask=>0000077, name=>"!!stfps",type=>"1fpp"}, - {code=>0170300, mask=>0000077, name=>"!!stst", type=>"1fpp"}, - {code=>0170400, mask=>0000077, name=>"!!clrf", type=>"1fpp"}, - {code=>0170500, mask=>0000077, name=>"!!tstf", type=>"1fpp"}, - {code=>0170600, mask=>0000077, name=>"!!absf", type=>"1fpp"}, - {code=>0170700, mask=>0000077, name=>"!!negf", type=>"1fpp"}, - {code=>0171000, mask=>0000377, name=>"!!mulf", type=>"rfpp"}, - {code=>0171400, mask=>0000377, name=>"!!modf", type=>"rfpp"}, - {code=>0172000, mask=>0000377, name=>"!!addf", type=>"rfpp"}, - {code=>0172400, mask=>0000377, name=>"!!ldf", type=>"rfpp"}, - {code=>0173000, mask=>0000377, name=>"!!subf", type=>"rfpp"}, - {code=>0173400, mask=>0000377, name=>"!!cmpf", type=>"rfpp"}, - {code=>0174000, mask=>0000377, name=>"!!stf", type=>"rfpp"}, - {code=>0174400, mask=>0000377, name=>"!!divf", type=>"rfpp"}, - {code=>0175000, mask=>0000377, name=>"!!stexp",type=>"rfpp"}, - {code=>0175400, mask=>0000377, name=>"!!stcif",type=>"rfpp"}, - {code=>0176000, mask=>0000377, name=>"!!stcfd",type=>"rfpp"}, - {code=>0176400, mask=>0000377, name=>"!!ldexp",type=>"rfpp"}, - {code=>0177000, mask=>0000377, name=>"!!ldcif",type=>"rfpp"}, - {code=>0177400, mask=>0000377, name=>"!!ldcdf",type=>"rfpp"} - ); - -use constant BIT00 => 0000001; -use constant BIT01 => 0000002; -use constant BIT02 => 0000004; -use constant BIT03 => 0000010; -use constant BIT04 => 0000020; -use constant BIT05 => 0000040; -use constant BIT06 => 0000100; -use constant BIT07 => 0000200; -use constant BIT08 => 0000400; -use constant BIT09 => 0001000; -use constant BIT10 => 0002000; -use constant BIT11 => 0004000; -use constant BIT12 => 0010000; -use constant BIT13 => 0020000; -use constant BIT14 => 0040000; -use constant BIT15 => 0100000; - -use constant REGATTR_RBMBOX => 0000001; # rbus is mailbox, skip on exa loop -use constant REGATTR_RBRD => 0000002; # by default read on rbus -use constant REGATTR_RBWR => 0000004; # by default write on rbus -use constant REGATTR_IBMBOX => 0000010; # ibus is mailbox, skip on exa loop - -# some common defs - -my @partbl_nxbuf = ( nxbuf_min => { type => "hval:d" }, - nxbuf_inc => { type => "hval:d" }, - nxbuf_max => { type => "hval:d" }, - nxbuf => { type => "hval:d" } ); - -# CPU general defs - -use constant CPU_MMR3 => 0172516; -use constant CPU_SDREG => 0177570; -use constant CPU_MMR0 => 0177572; -use constant CPU_MMR1 => 0177574; -use constant CPU_MMR2 => 0177576; -use constant CPU_LOSIZE => 0177760; -use constant CPU_HISIZE => 0177762; -use constant CPU_SYSID => 0177764; -use constant CPU_CPUERR => 0177766; -use constant CPU_MBRK => 0177770; -use constant CPU_PIRQ => 0177772; -use constant CPU_STKLIM => 0177774; -use constant CPU_PSW => 0177776; - -# DL11 general defs -use constant DL11_BASE_A => 0177560; -use constant DL11_BASE_B => 0176500; - -# DL11 address offsets -use constant DL11_RCSR => 00; -use constant DL11_RBUF => 02; -use constant DL11_XCSR => 04; -use constant DL11_XBUF => 06; - -# DL11 register defs -use constant DL11_RCSR_M_RDONE => BIT07; -use constant DL11_XCSR_M_XRDY => BIT07; -use constant DL11_XBUF_M_RRDY => BIT09; -use constant DL11_XBUF_M_XVAL => BIT08; -use constant DL11_XBUF_M_XBUF => 0377; - -my @reglist_dl11 = ({name => "rcsr", - offset => DL11_RCSR}, - {name => "rbuf", - offset => DL11_RBUF, - attr => REGATTR_IBMBOX}, - {name => "xcsr", - offset => DL11_XCSR}, - {name => "xbuf", - offset => DL11_XBUF, - attr => REGATTR_RBMBOX}); - -my %partbl_dl11 = ( trace => { type => "hval:b" }, - @partbl_nxbuf ); - -# LP11 general defs -use constant LP11_BASE => 0177514; - -# LP11 address offsets -use constant LP11_CSR => 00; -use constant LP11_BUF => 02; - -# LP11 register defs -use constant LP11_CSR_M_ERR => BIT15; -use constant LP11_BUF_M_VAL => BIT08; -use constant LP11_BUF_M_BUF => 0177; - -my @reglist_lp11 = ({name => "csr", - offset => LP11_CSR}, - {name => "buf", - offset => LP11_BUF, - attr => REGATTR_RBMBOX}); -my %partbl_lp11 = ( trace => { type => "hval:b" }, - @partbl_nxbuf ); - -# PC11 address offsets -use constant PC11_RCSR => 00; -use constant PC11_RBUF => 02; -use constant PC11_PCSR => 04; -use constant PC11_PBUF => 06; - -# PC11 register defs -use constant PC11_RCSR_M_ERR => BIT15; -use constant PC11_PCSR_M_ERR => BIT15; -use constant PC11_PBUF_M_RBUSY => BIT09; -use constant PC11_PBUF_M_PVAL => BIT08; -use constant PC11_PBUF_M_PBUF => 0377; - -my @reglist_pc11 = ({name => "rcsr", - offset => PC11_RCSR}, - {name => "rbuf", - offset => PC11_RBUF, - attr => REGATTR_IBMBOX}, - {name => "pcsr", - offset => PC11_PCSR}, - {name => "pbuf", - offset => PC11_PBUF, - attr => REGATTR_RBMBOX}); -my %partbl_pc11 = ( trace => { type => "hval:b" }, - @partbl_nxbuf ); - -# RK11 general defs -use constant RK11_BASE => 0177400; -use constant RK11_NUMSE => 12; # number of sectors -use constant RK11_NUMHD => 2; # number of heads -use constant RK11_NUMCY => 203; # number of cylinders -use constant RK11_NUMDR => 8; # number of drives -use constant RK11_NUMBL => RK11_NUMSE * RK11_NUMHD * RK11_NUMCY; -use constant RK11_BLKSIZE => 512; # disk block size -use constant RK11_VOLSIZE => RK11_BLKSIZE * RK11_NUMBL; # disk volume size - -# RK11 address offsets -use constant RK11_RKDS => 00; -use constant RK11_RKER => 02; -use constant RK11_RKCS => 04; -use constant RK11_RKWC => 06; -use constant RK11_RKBA => 010; -use constant RK11_RKDA => 012; -use constant RK11_RKMR => 014; - -# RK11 register defs - -use constant RKDS_M_ID => 0160000; # ID: drive number -use constant RKDS_V_ID => 13; -use constant RKDS_B_ID => 0007; -use constant RKDS_M_HDEN => BIT11; # HDEN: high density drive (rk05) -use constant RKDS_M_DRU => BIT10; # DRU: drive unsafe -use constant RKDS_M_SIN => BIT09; # SIN: seek incomplete -use constant RKDS_M_SOK => BIT08; # SOK: sector counter OK -use constant RKDS_M_DRY => BIT07; # DRY: drive ready -use constant RKDS_M_ADRY => BIT06; # ADRY: access ready -use constant RKDS_M_WPS => BIT05; # WPS: write protect -use constant RKDS_B_SC => 0017; # SC: sector counter - -use constant RKER_M_DRE => BIT15; # DRE: drive error -use constant RKER_M_OVR => BIT14; # OVR: overrun -use constant RKER_M_WLO => BIT13; # WLO: write lock violation -use constant RKER_M_PGE => BIT11; # PGE: programming error -use constant RKER_M_NXM => BIT10; # NXM: non existent memory -use constant RKER_M_NXD => BIT07; # NXD: non existent drive -use constant RKER_M_NXC => BIT06; # NXC: non existent cylinder -use constant RKER_M_NXS => BIT05; # NXS: non existent sector -use constant RKER_M_CSE => BIT01; # CSE: check sum error -use constant RKER_M_WCE => BIT00; # WCE: write check error - -use constant RKCS_M_MAINT => BIT12; # MAINT: maintenance mode -use constant RKCS_M_IBA => BIT11; # IBA: inhibit increment RKBA -use constant RKCS_M_FMT => BIT10; # FMT: format -use constant RKCS_M_RWA => BIT09; # RWA: read-write all -use constant RKCS_M_SSE => BIT08; # SSE: stop on soft errors -use constant RKCS_M_MEX => 0000060; # MEX: memory extension -use constant RKCS_V_MEX => 4; -use constant RKCS_B_MEX => 0003; -use constant RKCS_V_FUNC => 1; # FUNC: function -use constant RKCS_B_FUNC => 0007; -use constant RKCS_CRESET => 0; -use constant RKCS_WRITE => 1; -use constant RKCS_READ => 2; -use constant RKCS_WCHK => 3; -use constant RKCS_SEEK => 4; -use constant RKCS_RCHK => 5; -use constant RKCS_DRESET => 6; -use constant RKCS_WLOCK => 7; -use constant RKCS_M_GO => BIT00; # GO: go bit - -use constant RKDA_M_DRSEL => 0160000; # DRSEL: drive number -use constant RKDA_V_DRSEL => 13; -use constant RKDA_B_DRSEL => 0007; -use constant RKDA_M_CYL => 0017740; # CYL: cyclinder address -use constant RKDA_V_CYL => 5; -use constant RKDA_B_CYL => 0377; -use constant RKDA_M_SUR => 0000020; # SUR: surface -use constant RKDA_V_SUR => 4; -use constant RKDA_B_SUR => 0001; -use constant RKDA_B_SC => 0017; # SC: sector address - -use constant RKMR_M_RID => 0160000; # RID: drive id for RKDS RB read -use constant RKMR_V_RID => 13; -use constant RKMR_V_CRDONE => 11; # CRDONE: control reset done -use constant RKMR_V_SBCLR => 10; # SBCLR: clear SBUSY's with SDONE -use constant RKMR_V_CRESET => 9; # CRESET: initiate control reset -use constant RKMR_V_FDONE => 8; # FDONE: initiate function done - -my @reglist_rk11 = ({name => "rkds", - offset => RK11_RKDS}, - {name => "rker", - offset => RK11_RKER}, - {name => "rkcs", - offset => RK11_RKCS}, - {name => "rkwc", - offset => RK11_RKWC}, - {name => "rkba", - offset => RK11_RKBA}, - {name => "rkda", - offset => RK11_RKDA}, - {name => "rkmr", - offset => RK11_RKMR}); - -my %partbl_rk11 = ( trace => { type => "hval:b" } ); - -# KWP general defs - -my @reglist_kwp = ({name => "csr", - offset => 0}, - {name => "csb", - offset => 2}, - {name => "ctr", - offset => 4}); - -# KWL general defs - -my @reglist_kwl = ({name => "csr", - offset => 0}); - -# IIST general defs - -my @reglist_iist = ({name => "acr", - offset => 0}, - {name => "adr", - offset => 2}); - -use constant BOOT_START => 02000; - -my $serv11_fds_update = 1; -my $serv11_config_done = 0; -my $serv11_init_pending = 1; -my $serv11_rdma_chunk = 256; - -my $serv11_init_anena = 0x8000; # enable attn -#my $serv11_init_anena = 0xC03f; # enable attn+ioto(63ms) - -# -# %serv11_ctltbl->{dev} --> controller table; is hash of hashes -# -> {ctlname} controller name -# -> {ctltype} controller type (e.g. DL11) -# -> {devname} device name -# -> {type} device type: term, lpr, ptap, disk, tape, eth -# -> {units} array of unit names -# -> {base} controller base address -# -> {ibrb} controller base mapping for remote ib access -# -> {csroff} csr offset from base (for probing) -# -> {lam} lam number used by controller -# -> {nxbuf_min} nxbuf: minimal vector size -# -> {nxbuf_inc} nxbuf: vector size increment -# -> {nxbuf_max} nxbuf: maximal vector size -# -> {probehdl} address of probe handler -# -> {probemask} sides to be tested (set to "ir" if missing) -# -> {ichrhdl} address of input character handler -# -> {inithdl} address of controler init handler -# -> {usethdl} address of unit setup handler -# -> {attdethdl} address of attach/detach handler -# -> {attnhdl} address of attention handler -# -> {reglist} register list (array of regdsc's) -# -> {regtbl} register table (by name, created by ...) -# -> {partbl} parameter table (array of pardsc's) -# -> {blksize} block size (in bytes) {for disk} -# -> {volsize} volume size (in bytes) {for disk} -# -> {boot_mode} boot mode: "ptape" undef -# -> {boot_base} base address for boot code if not BOOT_START {for ptap} -# -> {boot_mode} boot mode: "ptape" undef -# -> {boot_entry} boot code entry point, relative to BOOT_START -# -> {boot_unit} offset from BOOT_START where unit number is stored -# -> {boot_code} array with boot loader code -# -# -> {memsize} memory size {for cpu} -# -# -> {nxbuf} nxbuf: current value -# -> {probe_ival} defined if cpu side probing ok -# -> {probe_rval} defined if rem side probing ok -# -> {probe_ok} true if required sides available (see probe_mask) -# -> {probe_text} text for "sho conf" generated during probe - -my %serv11_ctltbl = ( - CPU => - { ctlname => "CPU", - ctltype => "W11A", - type => "cpu", - base => CPU_PSW, # use psw to get it to top of list - lam => 0, - probehdl => \&serv11_probe_cpu, - probemask => "i", - attnhdl => \&serv11_attn_cpu, - reglist => [ ], - partbl => { } - }, - - TTA => - { ctlname => "TTA", - ctltype => "DL11", - devname => "TT", - type => "term", - units => ["TT0"], - base => DL11_BASE_A, - ibrb => DL11_BASE_A & ~(077), - csroff => 0, - lam => 1, - nxbuf_min => 2, # to disable nxbuf mechanism use - nxbuf_inc => 2, # min=1, inc=0, max=1 - nxbuf_max => 8, # otherwise: min=2,inc=2,max=8 - trace => 1, - probehdl => \&serv11_probe_gen, - ichrhdl => \&serv11_ichr_dl11, - attdethdl => \&serv11_attdet_term, - attnhdl => \&serv11_attn_dl11, - reglist => [ @reglist_dl11 ], - partbl => { %partbl_dl11 } - }, - - TTB => - { ctlname => "TTB", - ctltype => "DL11", - devname => "TT", - type => "term", - units => ["TT1"], - base => DL11_BASE_B, - ibrb => DL11_BASE_B & ~(077), - csroff => 0, - lam => 2, - nxbuf_min => 2, - nxbuf_inc => 2, - nxbuf_max => 8, - trace => 1, - probehdl => \&serv11_probe_gen, - ichrhdl => \&serv11_ichr_dl11, - attdethdl => \&serv11_attdet_term, - attnhdl => \&serv11_attn_dl11, - reglist => [ @reglist_dl11 ], - partbl => { %partbl_dl11 } - }, - - DZ => - { ctlname => "DZ", - ctltype => "DZ11", - devname => "DZ", - type => "term", - units => ["DZ0","DZ1","DZ2","DZ3","DZ4","DZ5","DZ6","DZ7"], - base => 0160100, - ibrb => 0160100 & ~(077), - csroff => 0, - lam => 3, - probehdl => \&serv11_probe_gen - }, - - LP => - { ctlname => "LP", - ctltype => "LP11", - devname => "LP", - type => "lpr", - units => ["LP0"], - base => 0177514, - ibrb => 0177514 & ~(077), - csroff => 0, - lam => 8, - nxbuf_min => 2, # to disable nxbuf mechanism use - nxbuf_inc => 2, # min=1, inc=0, max=1 - nxbuf_max => 8, # otherwise: min=2,inc=2,max=8 - trace => 1, - probehdl => \&serv11_probe_gen, - inithdl => \&serv11_init_gen, - usethdl => \&serv11_uset_lp11, - attdethdl => \&serv11_attdet_wonly, - attnhdl => \&serv11_attn_lp11, - reglist => [ @reglist_lp11 ], - partbl => { %partbl_lp11 } - }, - - PC => - { ctlname => "PC", - ctltype => "PC11", - devname => "PC", - type => "ptap", - units => ["PTR","PTP"], - base => 0177550, - ibrb => 0177550 & ~(077), - csroff => 0, - lam => 10, - nxbuf_min => 2, - nxbuf_inc => 2, - nxbuf_max => 8, - trace => 1, - probehdl => \&serv11_probe_gen, - usethdl => \&serv11_uset_pc11, - attdethdl => \&serv11_attdet_pc11, - attnhdl => \&serv11_attn_pc11, - reglist => [ @reglist_pc11 ], - partbl => { %partbl_pc11 }, - boot_mode => "ptape", - boot_base => 0017476, - boot_entry=> 0017500, - boot_code => [ # papertape lda loader, from dec-11-l2pc-po - 0000000, # C000: halt - 0010706, # astart: mov pc,sp - 0024646, # cmp -(sp),-(sp) - 0010705, # mov pc,r5 - 0062705, 0000112, # add #000112,r5 - 0005001, # clr r1 - 0013716, 0177570, # B000: mov @#cp.dsr,(sp) - 0006016, # ror (sp) - 0103402, # bcs B001 - 0005016, # clr (sp) - 0000403, # br B002 - 0006316, # B001: asl (sp) - 0001001, # bne B002 - 0010116, # mov r1,(sp) - 0005000, # B002: clr r0 - 0004715, # jsr pc,(r5) - 0105303, # decb r3 - 0001374, # bne B002 - 0004715, # jsr pc,(r5) - 0004767, 0000074, # jsr pc,R000 - 0010402, # mov r4,r2 - 0162702, 0000004, # sub #000004,r2 - 0022702, 0000002, # cmp #000002,r2 - 0001441, # beq B007 - 0004767, 0000054, # jsr pc,R000 - 0061604, # add (sp),r4 - 0010401, # mov r4,r1 - 0004715, # B003: jsr pc,(r5) - 0002004, # bge B005 - 0105700, # tstb r0 - 0001753, # beq B002 - 0000000, # B004: halt - 0000751, # br B002 - 0110321, # B005: movb r3,(r1)+ - 0000770, # br B003 - 0016703, 0000152, # ldchr: mov p.prcs,r3 - 0105213, # incb (r3) - 0105713, # B006: tstb (r3) - 0100376, # bpl B006 - 0116303, 0000002, # movb 000002(r3),r3 - 0060300, # add r3,r0 - 0042703, 0177400, # bic #177400,r3 - 0005302, # dec r2 - 0000207, # rts pc - 0012667, 0000046, # R000: mov (sp)+,D000 - 0004715, # jsr pc,(r5) - 0010304, # mov r3,r4 - 0004715, # jsr pc,(r5) - 0000303, # swap r3 - 0050304, # bis r3,r4 - 0016707, 0000030, # mov D000,pc - 0004767, 0177752, # B007: jsr pc,R000 - 0004715, # jsr pc,(r5) - 0105700, # tstb r0 - 0001342, # bne B004 - 0006204, # asr r4 - 0103002, # bcc B008 - 0000000, # halt - 0000700, # br B000 - 0006304, # B008: asl r4 - 0061604, # add (sp),r4 - 0000114, # jmp (r4) - 0000000, # D000: .word 000000 - 0012767, 0000352, 0000020, # L000: mov #000352,B009+2 - 0012767, 0000765, 0000034, # mov #000765,D001 - 0000167, 0177532, # jmp C000 - 0016701, 0000026, # bstart: mov p.prcs,r1 - 0012702, 0000352, # B009: mov #000352,r2 - 0005211, # inc (r1) - 0105711, # B010: tstb (r1) - 0100376, # bpl B010 - 0116162, 0000002, 0157400, # movb 000002(r1),157400(r2) - 0005267, 0177756, # inc B009+2 - 0000765, # D001: br B009 - 0177550 # p.prcs: .word 177550 - ] - }, - - RK => - { ctlname => "RK", - ctltype => "RK11/RK05", - devname => "RK", - type => "disk", - units => ["RK0","RK1","RK2","RK3","RK4","RK5","RK6","RK7"], - base => RK11_BASE, - ibrb => RK11_BASE & ~(077), - csroff => 4, - lam => 4, - trace => 1, - probehdl => \&serv11_probe_gen, - inithdl => \&serv11_init_gen, - usethdl => \&serv11_uset_rk11, - attdethdl => \&serv11_attdet_disk, - attnhdl => \&serv11_attn_rk11, - reglist => [ @reglist_rk11 ], - partbl => { %partbl_rk11 }, - blksize => RK11_BLKSIZE, - volsize => RK11_VOLSIZE, - boot_entry=> BOOT_START + 002, - boot_unit => BOOT_START + 010, - boot_code => [ # rk05 boot loader - from simh pdp11_rk.c - 0042113, # "KD" - 0012706, BOOT_START, # MOV #boot_start, SP - 0012700, 0000000, # MOV #unit, R0 ; unit number - 0010003, # MOV R0, R3 - 0000303, # SWAB R3 - 0006303, # ASL R3 - 0006303, # ASL R3 - 0006303, # ASL R3 - 0006303, # ASL R3 - 0006303, # ASL R3 - 0012701, 0177412, # MOV #RKDA, R1 ; rkda - 0010311, # MOV R3, (R1) ; load da - 0005041, # CLR -(R1) ; clear ba - 0012741, 0177000, # MOV #-256.*2, -(R1) ; load wc - 0012741, 0000005, # MOV #READ+GO, -(R1) ; read & go - 0005002, # CLR R2 - 0005003, # CLR R3 - 0012704, BOOT_START+020, # MOV #START+20, R4 - 0005005, # CLR R5 - 0105711, # TSTB (R1) - 0100376, # BPL .-2 - 0105011, # CLRB (R1) - 0005007 # CLR PC (5007) - ] - }, - - RL => - { ctlname => "RL", - ctltype => "RL11/RL02", - devname => "RL", - type => "disk", - units => ["RL0","RL1","RL2","RL3"], - base => 0174400, - ibrb => 0174400 & ~(077), - csroff => 0, # ???CHECK-ME??? - lam => 5, - probehdl => \&serv11_probe_gen, - boot_entry=> BOOT_START + 002, - boot_unit => BOOT_START + 010, - boot_code => [ # rl02 boot loader - from simh pdp11_rl.c - 0042114, # "LD" - 0012706, BOOT_START, # MOV #boot_start, SP - 0012700, 0000000, # MOV #unit, R0 - 0010003, # MOV R0, R3 - 0000303, # SWAB R3 - 0012701, 0174400, # MOV #RLCS, R1 ; csr - 0012761, 0000013, 0000004, # MOV #13, 4(R1) ; clr err - 0052703, 0000004, # BIS #4, R3 ; unit+gstat - 0010311, # MOV R3, (R1) ; issue cmd - 0105711, # TSTB (R1) ; wait - 0100376, # BPL .-2 - 0105003, # CLRB R3 - 0052703, 0000010, # BIS #10, R3 ; unit+rdhdr - 0010311, # MOV R3, (R1) ; issue cmd - 0105711, # TSTB (R1) ; wait - 0100376, # BPL .-2 - 0016102, 0000006, # MOV 6(R1), R2 ; get hdr - 0042702, 0000077, # BIC #77, R2 ; clr sector - 0005202, # INC R2 ; magic bit - 0010261, 0000004, # MOV R2, 4(R1) ; seek to 0 - 0105003, # CLRB R3 - 0052703, 0000006, # BIS #6, R3 ; unit+seek - 0010311, # MOV R3, (R1) ; issue cmd - 0105711, # TSTB (R1) ; wait - 0100376, # BPL .-2 - 0005061, 0000002, # CLR 2(R1) ; clr ba - 0005061, 0000004, # CLR 4(R1) ; clr da - 0012761, 0177000, 0000006, # MOV #-512., 6(R1) ; set wc - 0105003, # CLRB R3 - 0052703, 0000014, # BIS #14, R3 ; unit+read - 0010311, # MOV R3, (R1) ; issue cmd - 0105711, # TSTB (R1) ; wait - 0100376, # BPL .-2 - 0042711, 0000377, # BIC #377, (R1) - 0005002, # CLR R2 - 0005003, # CLR R3 - 0012704, BOOT_START+020, # MOV #START+20, R4 - 0005005, # CLR R5 - 0005007 # CLR PC - ] - }, - - - RP => - { ctlname => "RP", - ctltype => "RH70/RP06", - devname => "RP", - type => "disk", - units => ["RP0","RP1","RP2","RP3"], - base => 0176700, - ibrb => 0176700 & ~(077), - csroff => 0, # ???CHECK-ME??? - lam => 6, - probehdl => \&serv11_probe_gen, - boot_entry=> BOOT_START + 002, - boot_unit => BOOT_START + 010, - boot_code => [ # rp/rm boot loader - from simh pdp11_rp.c - 0042102, # "BD" - 0012706, BOOT_START, # mov #boot_start, sp - 0012700, 0000000, # mov #unit, r0 - 0012701, 0176700, # mov #RPCS1, r1 - 0012761, 0000040, 0000010, # mov #CS2_CLR, 10(r1) ; reset - 0010061, 0000010, # mov r0, 10(r1) ; set unit - 0012711, 0000021, # mov #RIP+GO, (r1) ; pack ack - 0012761, 0010000, 0000032, # mov #FMT16B, 32(r1) ; 16b mode - 0012761, 0177000, 0000002, # mov #-512., 2(r1) ; set wc - 0005061, 0000004, # clr 4(r1) ; clr ba - 0005061, 0000006, # clr 6(r1) ; clr da - 0005061, 0000034, # clr 34(r1) ; clr cyl - 0012711, 0000071, # mov #READ+GO, (r1) ; read - 0105711, # tstb (r1) ; wait - 0100376, # bpl .-2 - 0005002, # clr R2 - 0005003, # clr R3 - 0012704, BOOT_START+020, # mov #start+020, r4 - 0005005, # clr R5 - 0105011, # clrb (r1) - 0005007 # clr PC - ] - }, - - TM => - { ctlname => "TM", - ctltype => "TM11", - devname => "TM", - type => "tape", - units => ["TM0","TM1","TM2","TM3","TM4","TM5","TM6","TM7"], - base => 0172520, - ibrb => 0172520 & ~(077), - csroff => 2, - lam => 7, - probehdl => \&serv11_probe_gen, - boot_entry=> BOOT_START + 002, - boot_unit => BOOT_START + 010, - boot_code => [ # tm11 boot2 (skip 1st record) - from simh pdp11_tm.c - 0046524, # boot_start: "TM" - 0012706, BOOT_START, # mov #boot_start, sp - 0012700, 0000000, # mov #unit_num, r0 - 0012701, 0172526, # mov #172526, r1 ; mtcma - 0005011, # clr (r1) - 0012741, 0177777, # mov #-1, -(r1) ; mtbrc - 0010002, # mov r0,r2 - 0000302, # swab r2 - 0062702, 0060011, # add #60011, r2 - 0010241, # mov r2, -(r1) ; space + go - 0105711, # tstb (r1) ; mtc - 0100376, # bpl .-2 - 0010002, # mov r0,r2 - 0000302, # swab r2 - 0062702, 0060003, # add #60003, r2 - 0010211, # mov r2, (r1) ; read + go - 0105711, # tstb (r1) ; mtc - 0100376, # bpl .-2 - 0005002, # clr r2 - 0005003, # clr r3 - 0012704, BOOT_START+020, # mov #boot_start+20, r4 - 0005005, # clr r5 - 0005007 # clr r7 - ] - }, - - XU => - { ctlname => "XU", - ctltype => "DENUA", - devname => "XU", - type => "eth", - units => ["XU0"], - base => 0174510, - ibrb => 0174510 & ~(077), - csroff => 0, - lam => 9, - probehdl => \&serv11_probe_gen - }, - - KWP => - { ctlname => "KWP", - ctltype => "KW11-P", - devname => "--", - type => "misc", - base => 0172540, - probehdl => \&serv11_probe_gen, - probemask => "i", - reglist => [ @reglist_kwp ] - }, - - KWL => - { ctlname => "KWL", - ctltype => "KW11-L", - devname => "--", - type => "misc", - base => 0177546, - probehdl => \&serv11_probe_gen, - probemask => "i", - reglist => [ @reglist_kwl ] - }, - - IIS => - { ctlname => "IIS", - ctltype => "IIST", - devname => "--", - type => "misc", - base => 0177500, - probehdl => \&serv11_probe_gen, - probemask => "i", - reglist => [ @reglist_iist ] - } - - ); - -# -# %serv11_unittbl->{unit} --> unit table; is hash of hashes -# -> {unitname} unit name -# -> {ctlname} controller name -# -> {ctlunit} unit number of controller {ctlname} -# -> {devunit} device number for device $ucb->{ctlname}->{devname} -# -> {rcvque} receive queue {for term} -# -> {sndque} send queue {for term} -# -> {rcv7bit} use only 7 bits in receive {for term} -# -> {logfile} name of logfile -# -> {logfh} file handle for logfile -# - -my %serv11_unittbl = ( - TT0 => { unitname => "TT0", - ctlname => "TTA", - ctlunit => 0, - devunit => 0, - rcvque => [], - sndque => [], - rcv7bit => 1, - logfile => "pi_tt0.log", - logfh => undef - }, - TT1 => { unitname => "TT1", - ctlname => "TTB", - ctlunit => 0, - devunit => 1, - rcvque => [], - sndque => [], - rcv7bit => 1, - logfile => "pi_tt1.log", - logfh => undef - }, - - DZ0 => { unitname => "DZ0", - ctlname => "DZ", - ctlunit => 0, - devunit => 0, - rcvque => [], - sndque => [] - }, - DZ1 => { unitname => "DZ1", - ctlname => "DZ", - ctlunit => 1, - devunit => 1, - rcvque => [], - sndque => [] - }, - DZ2 => { unitname => "DZ2", - ctlname => "DZ", - ctlunit => 2, - devunit => 2, - rcvque => [], - sndque => [] - }, - DZ3 => { unitname => "DZ3", - ctlname => "DZ", - ctlunit => 3, - devunit => 3, - rcvque => [], - sndque => [] - }, - DZ4 => { unitname => "DZ4", - ctlname => "DZ", - ctlunit => 4, - devunit => 4, - rcvque => [], - sndque => [] - }, - DZ5 => { unitname => "DZ5", - ctlname => "DZ", - ctlunit => 5, - devunit => 5, - rcvque => [], - sndque => [] - }, - DZ6 => { unitname => "DZ6", - ctlname => "DZ", - ctlunit => 6, - devunit => 6, - rcvque => [], - sndque => [] - }, - DZ7 => { unitname => "DZ7", - ctlname => "DZ", - ctlunit => 7, - devunit => 7, - rcvque => [], - sndque => [] - }, - - LP0 => { unitname => "LP0", - ctlname => "LP", - ctlunit => 0, - devunit => 0, - logfile => "pi_lp0.log", - logfh => undef - }, - - PTR => { unitname => "PTR", - ctlname => "PC", - ctlunit => 0, - devunit => 0 - }, - - PTP => { unitname => "PTP", - ctlname => "PC", - ctlunit => 1, - devunit => 1 - }, - - RK0 => { unitname => "RK0", - ctlname => "RK", - ctlunit => 0, - devunit => 0 - }, - RK1 => { unitname => "RK1", - ctlname => "RK", - ctlunit => 1, - devunit => 1 - }, - RK2 => { unitname => "RK2", - ctlname => "RK", - ctlunit => 2, - devunit => 2 - }, - RK3 => { unitname => "RK3", - ctlname => "RK", - ctlunit => 3, - devunit => 3 - }, - RK4 => { unitname => "RK4", - ctlname => "RK", - ctlunit => 4, - devunit => 4 - }, - RK5 => { unitname => "RK5", - ctlname => "RK", - ctlunit => 5, - devunit => 5 - }, - RK6 => { unitname => "RK6", - ctlname => "RK", - ctlunit => 6, - devunit => 6 - }, - RK7 => { unitname => "RK7", - ctlname => "RK", - ctlunit => 7, - devunit => 7 - }, - - RL0 => { unitname => "RL0", - ctlname => "RL", - ctlunit => 0, - devunit => 0 - }, - RL1 => { unitname => "RL1", - ctlname => "RL", - ctlunit => 1, - devunit => 1 - }, - RL2 => { unitname => "RL2", - ctlname => "RL", - ctlunit => 2, - devunit => 2 - }, - RL3 => { unitname => "RL3", - ctlname => "RL", - ctlunit => 3, - devunit => 3 - }, - - RP0 => { unitname => "RP0", - ctlname => "RP", - ctlunit => 0, - devunit => 0 - }, - RP1 => { unitname => "RP1", - ctlname => "RP", - ctlunit => 1, - devunit => 1 - }, - RP2 => { unitname => "RP2", - ctlname => "RP", - ctlunit => 2, - devunit => 2 - }, - RP3 => { unitname => "RP3", - ctlname => "RP", - ctlunit => 3, - devunit => 3 - }, - - TM0 => { unitname => "TM0", - ctlname => "TM", - ctlunit => 0, - devunit => 0 - }, - TM1 => { unitname => "TM1", - ctlname => "TM", - ctlunit => 1, - devunit => 1 - }, - TM2 => { unitname => "TM2", - ctlname => "TM", - ctlunit => 2, - devunit => 2 - }, - TM3 => { unitname => "TM3", - ctlname => "TM", - ctlunit => 3, - devunit => 3 - }, - TM4 => { unitname => "TM4", - ctlname => "TM", - ctlunit => 4, - devunit => 4 - }, - TM5 => { unitname => "TM5", - ctlname => "TM", - ctlunit => 5, - devunit => 5 - }, - TM6 => { unitname => "TM6", - ctlname => "TM", - ctlunit => 6, - devunit => 6 - }, - TM7 => { unitname => "TM7", - ctlname => "TM", - ctlunit => 7, - devunit => 7 - }, - - XU0 => { unitname => "XU0", - ctlname => "XU", - ctlunit => 0, - devunit => 0 - } - - ); - -my @serv11_attntbl; - -my $serv11_active = 0; -my $serv11_attn_mask = 0; -my $serv11_attn_seen = 0; - -my @serv11_icbque = (); - -my $only_argv = 0; -$only_argv = 1 if scalar(@ARGV) > 0; -$only_argv = 0 if exists $opts{int}; - -# -# -- Main program starts here ------------------------------------------------ -# - -autoflush STDOUT 1 if (-p STDOUT); # autoflush if output into pipe -autoflush STDOUT 1 if (-t STDOUT); # autoflush if output into term - -if (exists $opts{help}) { - print_help(); - exit 0; -} - -$SIG{INT} = 'hdl_sigint'; # install ^C (SIGINT) handler - -if (exists $opts{log} && $opts{log} ne "") { - my $fh = new FileHandle; - my $filename = $opts{log}; - $fh->open(">$filename") or die "couldn't open log file"; - $fh_log = $fh; - autoflush $fh_log if (-t $fh); - printf $fh_log "==== opened log file on %s\n", get_timestamp(); -} - -$raw_timeout = $opts{timeout} if exists $opts{timeout}; -$cmax = $opts{cmax} if exists $opts{cmax}; - -if (exists $opts{run}) { - if (not defined ($kpid=fork())) { - die "cannot fork: $!"; - } elsif ($kpid == 0) { # in child - exec "/bin/sh", "-c", $opts{run}; - die "failed to exec /bin/sh -c $opts{run}: $!"; - } else { # in parent - } -} - -fifo_open($opts{fifo}) if (exists $opts{fifo}); -$time0 = get_time(); # do T0 after fifo open -term_open($opts{term}) if (exists $opts{term}); - -while(1) { - my $cmd = get_command(); - if (defined $cmd) { - do_command($cmd); - } else { - do_command(".mode nomode"); - last; - } -} - -if ($curchan) { - &{$chan_tab{$curchan}{write}}(); # flush write queue before close - &{$chan_tab{$curchan}{close}}(); -} - -if (exists $opts{run}) { - waitpid($kpid, 0); - print "pi_rri($curmode)-I: exit status: $?\n" if $?; -} -0; - -#------------------------------------------------------------------------------- - -sub init_regtbl { # initialize regtbl from reglist - foreach my $ctlname (sort keys %serv11_ctltbl) { - my $ctl = $serv11_ctltbl{$ctlname}; - next unless defined $ctl->{reglist}; - - $ctl->{regtbl} = {}; - my $nregs = scalar (@{$ctl->{reglist}}); - - for (my $i = 0; $i<$nregs; $i++) { - my $name = $ctl->{reglist}->[$i]->{name}; - $ctl->{regtbl}->{$name} = $i; - $ctl->{reglist}->[$i]->{rank} = $i; - ##print "+++ 1a $ctl->{ctlname} $name $i\n"; - } - } -} - -#------------------------------------------------------------------------------- - -sub get_command { - my $cmd; - while (1) { - - $cmd = read_command; - return $cmd if (not defined $cmd); # quit if EOF - - print "$cmd\n" if exists $opts{trace}; - - if ($cmd =~ m/^C/) { # ignore, but print "C ..." lines - &{$mode_tab{$curmode}{flush}}("comm"); - print "$cmd\n" unless exists $opts{trace}; - next; - } - - $cmd =~ s{^\s*}{}; # remove leading blanks - - next if $cmd =~ m/^#/; # ignore "# ...." lines - next if $cmd =~ m/^;/; # ignore "; ...." lines - - $cmd =~ s{--.*}{}; # remove comments after -- - $cmd =~ s{\s*$}{}; # remove trailing blanks - next if $cmd eq ""; # ignore empty lines - - return $cmd; - } -} - -#------------------------------------------------------------------------------- - -sub do_command { - my ($cmd) = @_; - - if ($cmd =~ /^\.mode\s*(\w*)/) { # .mode command - if (exists $mode_tab{$1}) { - &{$mode_tab{$curmode}{flush}}("mode"); - &{$mode_tab{$curmode}{close}}(); - print "pi_rri($curmode)-I: closed mode\n" unless $curmode eq "nomode"; - $curmode = $1; - $curcmd = $mode_tab{$curmode}{cmd}; - print "pi_rri($curmode)-I: open mode\n" unless $curmode eq "nomode"; - &{$mode_tab{$curmode}{open}}(); - - } else { - printf "pi_rri($curmode)-E: mode '%s' doesn't exist\n", $1; - printf "pi_rri($curmode)-E: use %s\n", join ",", (sort keys %mode_tab); - } - - } else { # any other command - $sigint_count = 0; # clear pending ^C's - &$curcmd($cmd); - &{$mode_tab{$curmode}{flush}}("line") if $cmd_inter; - } -} - -#------------------------------------------------------------------------------- - -sub read_command { - my $cmd; - - $cmd_inter = 0; - - while (1) { - -# read command line - - if (scalar(@cmdfh)==0 && scalar(@ARGV)>0) { - $cmd = shift @ARGV; - } else { - if (scalar(@cmdfh)) { - my $fh = $cmdfh[$#cmdfh]; - $cmd = <$fh>; - chomp $cmd if defined $cmd; - if (defined $cmd && $cmd =~ /\\$/) { # continuation line ? - $cmd = $`; - my $cline = <$fh>; - chomp $cline; - $cmd .= $cline if defined $cline; - } - unless (defined $cmd) { - $fh->close(); - pop @cmdfh; - print "pi_rri($curmode)-I: close " . pop(@cmdfn) . "\n"; - &{$mode_tab{$curmode}{flush}}("file"); - pop @cmdargs; - setpar_command($cmdargs[-1]) if scalar(@cmdargs); - next; - } - } else { - return undef if $only_argv; - if (defined $term) { - $cmd = $term->readline('>'); - } else { - $cmd = ; - } - if (-t STDIN && -t STDOUT) { - $cmd_inter = 1; # signal that cmd interactive - } - chomp $cmd if defined $cmd; - return undef if not defined $cmd; - if (defined $cmd && $cmd =~ /\\$/) { # continuation line ? - $cmd = $`; - my $cline = ; - chomp $cline; - $cmd .= $cline if defined $cline; - } - } - } - -# preprocess command line -# handle substitutions - - while ($cmd =~ /\$\{(\w*):([-=])(.*?)\}/) { # ${name:[-=]val} seen - my $name = $1; - my $typ = $2; - my $val = $3; - if (exists $par{$name}) { - $cmd = $` . $par{$name} . $'; - } else { - $cmd = $` . $val . $'; - $par{$name} = $val if ($typ eq "="); - } - } - - while ($cmd =~ /\$\{(\w*)\}/) { # ${name} seen - my $name = $1; - if (exists $par{$name}) { - $cmd = $` . $par{$name} . $'; - } else { - print "pi_rri($curmode)-E: variable \"$name\" not defined\n"; - $cmd = $` . "\$?$name?" . $'; - } - } - - while ($cmd =~ /\$\[(.*)\]/) { # $[name] seen - my $evalstr = $1; - my $evalval = eval $evalstr; - if ($@) { - print "pi_rri($curmode)-E: eval error for \"$evalstr\"\n"; - print "pi_rri($curmode)-E: $@\n"; - $cmd = $` . "\$?$evalstr?" . $'; - } else { - $evalval = "" unless defined $evalval; - $cmd = $` . $evalval . $'; - } - } - -# handle asignments - - if ($cmd =~ /^(\w*)=/) { - my $name = $1; - my $val = $'; - $val =~ s/--.*$//; - $val =~ s/\s*$//; - $par{$name} = $val; - next; - } - -# handle @@xxx lines (pmac perl macros) - - if ($cmd =~ /^\s*\@\@(\S*)\s*(.*)$/) { # is it a "@@xxx" macro call ? - my $file = $1; - my $args = $2; - my $fileexp = filename_expand($file); - - print_fatal "pmac file $fileexp not found" unless -r $fileexp; - open (PMACFILE, "<$fileexp") or die "failed to open $fileexp: $!"; - my @code = ; - close PMACFILE; - my $code = join "", @code; - ##printf "+++1 code to execute from $fileexp:\n$code---\n"; - - $cmd_line = $cmd; - $cmd_rest = $args; - $cmd_bad = 0; - - $sigint_count = 0; # clear pending ^C's - { eval $code; } - if ($@) { - print STDERR "pi_rri-E: compile error in $fileexp:\n"; - print STDERR $@; - } - next; - } - -# handle @xxx lines (pcmd command lists) - - if ($cmd =~ /^\s*\@(.*)$/) { # is it a "@xxx" command ? - my $file = $1; - my $args = ""; - if ($file =~ /\((.*)\)$/) { # is it a "@xxx(args)" command ? - $file = $`; - $args = $1; - } - - my $fileexp = filename_expand($file); - - print_fatal "pcmd file $fileexp not found" unless -r $fileexp; - my $fh = new FileHandle; - $fh->open("<$fileexp") or die "failed to open $fileexp: $!"; - print "pi_rri($curmode)-I: open $fileexp\n"; - push @cmdfh, $fh; - push @cmdfn, $fileexp; - push @cmdargs, $args; - setpar_command($args); - } else { - return $cmd; - } - } -} - -#------------------------------------------------------------------------------- - -sub setpar_command { - my ($args) = @_; - my @arglist = split /,/,$args; - for (my $i=scalar(@arglist); $i<8; $i++) { - $arglist[$i] = ""; - } - for (my $i=0; $i0 && - scalar(@cpraw_tx_read)>0) { - my $dat_e = shift @cpraw_tx_expt; - my $dat_r = shift @cpraw_tx_read; - - print conv_etime(), "cptx ", conv_dat9($dat_r), " CHECK "; - if ($dat_e == $dat_r) { - print "OK"; - } else { - print "FAIL exp=", conv_dat9($dat_e); - } - print "\n"; - } - -} - -#------------------------------------------------------------------------------- - -sub rri_open { - $rri_ref_sdef = 0x00; # by default check for 'hard' errors - $rri_msk_sdef = 0xf0; # ignore the status bits + attn flag -} - -#------------------------------------------------------------------------------- - -sub rri_flush { - my ($case) = @_; - rri_cmdlist_do(); -} - -#------------------------------------------------------------------------------- - -sub rri_close { -} - -#------------------------------------------------------------------------------- -# .rlmon 0|1 -# .rbmon 0|1 -# .scntl n 0|1 -# .sinit g8 g16 -# .sdef [s=g8] -# .amclr -# .amdef name g8 -# .reset -# .wait n -# .wtlam n -# .cclst -# rreg [d=g16] [s=g8] -# rblk n [s=g8] -# followed by n d=g16 data check values -# wreg g16 [s=g8] -# wblk n [s=g8] -# followed by n g16 data values -# stat [d=g16] [s=d8] -# attn [d=g16] [s=d8] -# init g16 [s=g8] - -sub rri_cexec { - my ($cmd) = @_; - - $cmd_line = $cmd; - $cmd_rest = ""; - $cmd_bad = 0; - - if ($cmd =~ /^(\.rlmon|\.rbmon)\s+([01])/) { # .rlmon, .rbmon ------------- - my $ind = ($1 eq ".rlmon") ? 15 : 14; - $cmd_rest = $'; - rri_sideband(0x00, ($ind<<8) + $2); - - } elsif ($cmd =~ /^\.scntl\s+(\d+)\s([01])/) { # .scntl ------------------ - $cmd_rest = $'; - rri_sideband(0x00, ($1<<8) + $2); - - } elsif ($cmd =~ /^\.sinit/) { # .sinit ------------------ - $cmd_rest = $'; - my $addr = cget_gdat(8,$rri_dbasi); - my $data = cget_gdat(16,$rri_dbasi); - rri_sideband($addr, $data) if (not $cmd_bad); - - } elsif ($cmd =~ /^\.sdef/) { # .sdef ------------------------- - $cmd_rest = $'; - ($rri_ref_sdef,$rri_msk_sdef) = cget_tagval2_gdat("s",8,2); - - } elsif ($cmd =~ /^\.amclr/) { # .amclr ------------------------ - $cmd_rest = $'; - %rri_amtbl = (); - - } elsif ($cmd =~ /^\.amdef\s+([a-zA-Z][a-zA-Z0-9]*)/) {# .amdef ------------ - $cmd_rest = $'; - my $name = $1; - my $addr = cget_gdat(8,2); - if (defined $addr) { - $rri_amtbl{$name} = $addr; - } else { - $cmd_bad = 1; - } - - } elsif ($cmd =~ /^\.dbasi\s+(\d+)/) { # .dbasi ----------------------- - $cmd_rest = $'; - my $dbase = int $1; - $rri_dbasi = $dbase; - } elsif ($cmd =~ /^\.dbaso\s+(\d+)/) { # .dbaso ----------------------- - $cmd_rest = $'; - my $dbase = int $1; - $rri_dbaso = $dbase; - if ($rri_dbaso == 2) { - $rri_nodfill = " " x 15; - } elsif ($rri_dbaso == 8) { - $rri_nodfill = " " x 5; - } elsif ($rri_dbaso == 16) { - $rri_nodfill = " " x 3; - } else { - $rri_nodfill = "???"; - } - - } elsif ($cmd =~ /^\.reset/) { # .reset ------------------------ - $cmd_rest = $'; - print "pi_rri($curmode)-I: $cmd currently ignored\n"; - - } elsif ($cmd =~ /^\.wait\s+(\d+)/) { # .wait ------------------------ - $cmd_rest = $'; - my $delay = int $1; - rri_cmdlist_do(); # flush before waiting - for (my $i = 0; $i < $delay; $i++) { - raw_snd9(D9IDLE); - } - - } elsif ($cmd =~ /^\.wtlam\s+(\d+)/) { # .wtlam ------------------------ - $cmd_rest = $'; - rri_cmdlist_do(); # flush before wait for ATTN - my $tstart = get_time(); - raw_get9_check(D9ATTN, "wtlam"); # ???FIXME this is a hack... - printf "-- .wtlam # wait for %7.3f sec\n", get_time()-$tstart; - - } elsif ($cmd =~ /^\.cclst/) { # .cclst ------------------------ - $cmd_rest = $'; - $rri_ncmdmax = scalar(@rri_cmdlist) + 1; # force exec after next cmd - - } elsif ($cmd =~ /^rreg/) { # rreg -------------------------- - $cmd_rest = $'; - my $addr = rri_cget_addr; - my ($ref_data, $msk_data) = cget_tagval2_gdat("d",16,$rri_dbasi); - my ($ref_stat, $msk_stat) = rri_cget_stat; - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "rreg", - addr => $addr, - ref_data => $ref_data, - msk_data => $msk_data, - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } elsif ($cmd =~ /^rblk/) { # rblk -------------------------- - $cmd_rest = $'; - my $addr = rri_cget_addr; - my $nblk = rri_cget_nblk; - my ($ref_stat, $msk_stat) = rri_cget_stat; - my @ref_rblk; - my @msk_rblk; - my $i; - cget_chkblank(); - for ($i = 0; $i < $nblk; $i++) { - $cmd_rest = get_command() if ($cmd_rest eq ""); - $cmd_rest =~ s/^\s*//; - my ($ref,$msk) = cget_tagval2_gdat("d",16,$rri_dbasi); - push @ref_rblk, $ref; - push @msk_rblk, $msk; - } - cget_chkblank(); - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "rblk", - addr => $addr, - nblk => $nblk, - ref_rblk => [@ref_rblk], - msk_rblk => [@msk_rblk], - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } elsif ($cmd =~ /^wreg/) { # wreg -------------------------- - $cmd_rest = $'; - my $addr = rri_cget_addr; - my $data = cget_gdat(16,$rri_dbasi); - my ($ref_stat, $msk_stat) = rri_cget_stat; - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "wreg", - addr => $addr, - data => $data, - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } elsif ($cmd =~ /^wblk/) { # wblk -------------------------- - $cmd_rest = $'; - my $addr = rri_cget_addr; - my $nblk = rri_cget_nblk; - my ($ref_stat, $msk_stat) = rri_cget_stat; - my @dat_wblk; - my $i; - cget_chkblank(); - for ($i = 0; $i < $nblk; $i++) { - $cmd_rest = get_command() if ($cmd_rest eq ""); - $cmd_rest =~ s/^\s*//; - push @dat_wblk, cget_gdat(16,$rri_dbasi); - } - cget_chkblank(); - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "wblk", - addr => $addr, - nblk => $nblk, - dat_wblk => [@dat_wblk], - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } elsif ($cmd =~ /^stat/) { # stat -------------------------- - $cmd_rest = $'; - my ($ref_data, $msk_data) = cget_tagval_gdat("d",16,2); - my ($ref_stat, $msk_stat) = rri_cget_stat; - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "stat", - ref_data => $ref_data, - msk_data => $msk_data, - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } elsif ($cmd =~ /^attn/) { # attn -------------------------- - $cmd_rest = $'; - my ($ref_data, $msk_data) = cget_tagval_gdat("d",16,$rri_dbasi); - my ($ref_stat, $msk_stat) = rri_cget_stat; - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "attn", - ref_data => $ref_data, - msk_data => $msk_data, - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } elsif ($cmd =~ /^init/) { # init -------------------------- - $cmd_rest = $'; - my $addr = rri_cget_addr; - my $data = cget_gdat(16,$rri_dbasi); - my ($ref_stat, $msk_stat) = rri_cget_stat; - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "init", - addr => $addr, - data => $data, - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } else { - print "pi_rri($curmode)-E: unknown command: \"$cmd_line\"\n"; - } - - cget_chkblank() unless $cmd_bad; - if ($cmd_bad) { - print "pi_rri($curmode)-E: parse error, command ignored: \"$cmd_line\"\n"; - } else { - if (scalar(@rri_cmdlist) >= $cmax || - ($rri_ncmdmax && scalar(@rri_cmdlist) >= $rri_ncmdmax)) { - $rri_ncmdmax = undef; - rri_cmdlist_do(); - } - } -} - -#------------------------------------------------------------------------------- - -sub rri_cget_stat { - my ($dat, $msk) = cget_tagval2_gdat("s",8,2); - if (defined $dat) { - return ($dat, $msk); - } else { - return ($rri_ref_sdef, $rri_msk_sdef); - } -} - -#------------------------------------------------------------------------------- - -sub rri_cget_addr { - my $odat; - $cmd_rest =~ s/^\s*//; - if ($cmd_rest =~ /^\.([a-zA-Z][a-zA-Z0-9]*)/) { - $cmd_rest = $'; - if (exists $rri_amtbl{$1}) { - $odat = $rri_amtbl{$1}; - if ($cmd_rest =~ /^\|/) { - $cmd_rest = $'; - $odat |= cget_gdat(8,2); - } - } else { - print "pi_rri($curmode)-E: undefined address mnemo: \"$1\"\n"; - $cmd_bad = 1; - } - } else { - $odat = cget_gdat(8,2); - } - return $odat; -} - -#------------------------------------------------------------------------------- - -sub rri_cget_nblk { - my $odat; - $cmd_rest =~ s/^\s*//; - if ($cmd_rest =~ /^(\d*)/) { - $cmd_rest = $'; - $odat = int $1; - if ($odat <= 0 || $odat > 256) { - print "pi_rri($curmode)-E: block length <0 or >256\n"; - $cmd_bad = 1; - } - } else { - $cmd_bad = 1; - } - return $odat; -} - -#------------------------------------------------------------------------------- - -sub rri_cmdlist_dump { - my ($href,$dblk,$fh) = @_; - my $fh_old; - - $fh_old = select($fh) if defined $fh; - - foreach my $ele (@$href) { - - printf "-- %-4s",$ele->{cname}; - - printf " %-7s","[$ele->{aname}]" if exists $ele->{aname}; - - printf " c=%1.1x%1d%1d", $ele->{cmd}>>4, ($ele->{cmd}>>3)&0x1, - $ele->{cmd}&0x7 if exists $ele->{cmd}; - - printf " a=%s",conv_dat8($ele->{addr}) if exists $ele->{addr}; - - printf " n=%d", $ele->{nblk} if exists $ele->{nblk}; - - printf " d=%s", gconv_dat16($ele->{data},$rri_dbaso) if exists $ele->{data}; - - if (exists $ele->{ref_data}) { - if ((defined $ele->{msk_data} && $ele->{msk_data} == 0xffff) - || not defined $ele->{ref_data}) { - printf " d=-%s", $rri_nodfill; - } else { - printf " d=%s", gconv_dat16($ele->{ref_data},$rri_dbaso); - printf ",%s", gconv_dat16($ele->{msk_data},$rri_dbaso) if $ele->{msk_data}; - } - } - - if (defined $ele->{rcv_data}) { - printf " D=%s%s", gconv_dat16($ele->{rcv_data},$rri_dbaso), - ($ele->{err_data} ? "(#)" : " "); - } - - if (exists $ele->{ref_stat}) { - if ((defined $ele->{msk_stat} && $ele->{msk_stat} == 0xffff) - || not defined $ele->{ref_stat}) { - printf " s=-"; - } else { - printf " s=%s", conv_dat8($ele->{ref_stat}); - printf ",%s", conv_dat8($ele->{msk_stat}) if $ele->{msk_stat}; - } - } - - if (defined $ele->{rcv_stat}) { - printf " S=%s%s", conv_dat8($ele->{rcv_stat}), - ($ele->{err_stat} ? "(#)" : " "); - } - - if (exists $ele->{ok}) { - print ($ele->{ok} ? " OK" : "FAIL"); - } else { - print " PEND"; - } - - if (exists $ele->{dat_wblk} && $dblk) { - my $i = 0; - foreach ( @{$ele->{dat_wblk}} ) { - printf "\n-- " if ($i % 8 == 0); - printf " %s", gconv_dat16($_,$rri_dbaso); - $i += 1; - } - } - - if (exists $ele->{ref_rblk} && $dblk && scalar(@{$ele->{ref_rblk}}) ) { - my $i; - my $nblk = $ele->{nblk}; - for ($i = 0; $i < $nblk; $i++) { - printf "\n-- " if ($i % 4 == 0); - if ((defined $ele->{msk_rblk}[$i] && $ele->{msk_rblk}[$i] == 0xffff) - || not defined $ele->{ref_rblk}[$i]){ - printf " d=-%s %s", $rri_nodfill, $rri_nodfill; - } else { - printf " d=%s", gconv_dat16($ele->{ref_rblk}[$i],$rri_dbaso); - if ($ele->{msk_rblk}[$i]) { - printf ",%s", gconv_dat16($ele->{msk_rblk}[$i],$rri_dbaso); - } else { - print " "; - } - } - } - } - - if (exists $ele->{rcv_rblk} && $dblk) { - my $i; - my $nblk = $ele->{nblk}; - for ($i = 0; $i < $nblk; $i++) { - printf "\n-- " if ($i % 4 == 0); - printf " D=%s%s ", gconv_dat16($ele->{rcv_rblk}[$i],$rri_dbaso), - ($ele->{err_rblk}[$i] ? "(#)" : " "); - } - } - - printf "\n"; - } - - select($fh_old) if defined $fh_old; - -} - -#------------------------------------------------------------------------------- - -sub rri_sideband { - my ($addr,$data) = @_; - my $dl = $data & 0xff; - my $dh = ($data>>8) & 0xff; - rri_cmdlist_do(); - raw_snd8(CESC); - raw_snd8(CESC); - raw_snd8($addr); # ADDR - raw_snd8($dl); # DL - raw_snd8($dh); # DH - &{$chan_tab{$curchan}{write}}(); # flush write queue -} - -#------------------------------------------------------------------------------- - -sub rri_cmdlist_do { - if (scalar(@rri_cmdlist)) { - rri_cmdlist_exec(\@rri_cmdlist); - rri_cmdlist_dump(\@rri_cmdlist, 1); - @rri_cmdlist = (); - } -} - -#------------------------------------------------------------------------------- - -sub rri_cmdlist_exec { - my ($href) = @_; - my $seq = 0; - my $nele = scalar(@$href); - - return unless $nele; - - $ocrc = 0; - $icrc = 0; - - raw_snd9(D9SOP); - - foreach my $ele (@$href) { - my $cname = $ele->{cname}; - my $cmd; - - $cmd = $rri_cname2cmd{$cname}; - $cmd |= 0x08 if $seq < $nele-1; # set chain bit - $cmd |= ($seq & 0xf) << 4; # set sequence number field - $ele->{cmd} = $cmd; - raw_snd9_crc($cmd); - $seq += 1; - - if ($cname eq "rreg") { - $stat_tab{xreg} += 1; - raw_snd9_crc($ele->{addr}); - raw_snd9($ocrc); - } elsif ($cname eq "rblk") { - $stat_tab{xblk} += 1; - raw_snd9_crc($ele->{addr}); - raw_snd9_crc($ele->{nblk}-1); - raw_snd9($ocrc); - } elsif ($cname eq "wreg") { - $stat_tab{xreg} += 1; - raw_snd9_crc($ele->{addr}); - raw_snd9_crc( $ele->{data} & 0xff); - raw_snd9_crc(($ele->{data}>>8) & 0xff); - raw_snd9($ocrc); - } elsif ($cname eq "wblk") { - $stat_tab{xblk} += 1; - raw_snd9_crc($ele->{addr}); - raw_snd9_crc($ele->{nblk}-1); - raw_snd9($ocrc); - foreach ( @{$ele->{dat_wblk}} ) { - raw_snd9_crc( $_ & 0xff); - raw_snd9_crc(($_>>8) & 0xff); - } - raw_snd9($ocrc); - } elsif ($cname eq "stat") { - raw_snd9($ocrc); - } elsif ($cname eq "attn") { - raw_snd9($ocrc); - } elsif ($cname eq "init") { - raw_snd9_crc($ele->{addr}); - raw_snd9_crc( $ele->{data} & 0xff); - raw_snd9_crc(($ele->{data}>>8) & 0xff); - raw_snd9($ocrc); - } - } - - raw_snd9(D9EOP); - - raw_get9_checksop() or return 0; - - foreach my $ele (@$href) { - my $cname = $ele->{cname}; - my $idat; - my $ok = 1; - - raw_get9_crc_check($ele->{cmd}, "cmd") or return 0; - - if ($cname eq "rreg") { - raw_get9_crc_16bit(\$ele->{rcv_data}) or return 0; - raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; - raw_get9_check($icrc, "crc") or return 0; - } elsif ($cname eq "rblk") { - raw_get9_crc_check($ele->{nblk}-1, "nblk") or return 0; - for (my $i=0; $i<$ele->{nblk}; $i++) { - my $data; - my $err; - raw_get9_crc_16bit(\$data) or return 0; - push @{$ele->{rcv_rblk}}, $data; - $err = rri_ref_check($data, $ele->{ref_rblk}[$i], $ele->{msk_rblk}[$i]); - push @{$ele->{err_rblk}}, $err; - $ok = 0 if $err; - } - raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; - raw_get9_check($icrc, "crc") or return 0; - } elsif ($cname eq "wreg") { - raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; - raw_get9_check($icrc, "crc") or return 0; - } elsif ($cname eq "wblk") { - raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; - raw_get9_check($icrc, "crc") or return 0; - } elsif ($cname eq "stat") { - raw_get9_crc_8bit(\$ele->{rcv_ccmd}) or return 0; - raw_get9_crc_16bit(\$ele->{rcv_data}) or return 0; - raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; - raw_get9_check($icrc, "crc") or return 0; - } elsif ($cname eq "attn") { - raw_get9_crc_16bit(\$ele->{rcv_data}) or return 0; - raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; - raw_get9_check($icrc, "crc") or return 0; - } elsif ($cname eq "init") { - raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; - raw_get9_check($icrc, "crc") or return 0; - } - - if (defined $ele->{rcv_data}) { - $ele->{err_data} = rri_ref_check($ele->{rcv_data}, - $ele->{ref_data}, $ele->{msk_data}); - $ok = 0 if $ele->{err_data}; - } - if (defined $ele->{rcv_stat}) { - $ele->{err_stat} = rri_ref_check($ele->{rcv_stat}, - $ele->{ref_stat}, $ele->{msk_stat}); - $ok = 0 if $ele->{err_stat}; - } - - $ele->{ok} = $ok; - - } - - raw_get9_checkeop() or return 0; - - return 1; -} - -#------------------------------------------------------------------------------- - -sub rri_cmdlist_check_stat { - my ($href) = @_; - - foreach my $ele (@$href) { - return 1 if not exists $ele->{rcv_stat}; - return 1 if $ele->{err_stat}; - } - - return 0; -} - -#------------------------------------------------------------------------------- - -sub rri_cmdlist_get_rval { - my ($href,$ind) = @_; - my $nele = scalar(@$href); - - return (undef, "#ind?#") if ($ind >= $nele); - - return (undef, "#sta?#") if not exists $$href[$ind]->{rcv_stat}; - - return (undef, sprintf "#s=%2.2x#",$$href[$ind]->{rcv_stat}) - if $$href[$ind]->{err_stat}; - - return (undef, "#dat?#") if (not exists $$href[$ind]->{rcv_data}); - - return ($$href[$ind]->{rcv_data}, sprintf "%6.6o",$$href[$ind]->{rcv_data}); -} - -#------------------------------------------------------------------------------- - -sub rri_cmdlist_conv_rval { - my ($href,$ind) = @_; - my ($val,$str) = rri_cmdlist_get_rval($href, $ind); - return $str; -} - -#------------------------------------------------------------------------------- - -sub rri_ref_check { # check reference data (1=err) - my ($rcv,$ref,$msk) = @_; - if (defined $ref) { - my $mask = (defined $msk) ? $msk : 0; - my $mrcv = $rcv | $mask; - my $mref = $ref | $mask; - return 1 if $mrcv != $mref; - } - return 0; -} - -#------------------------------------------------------------------------------- - -sub pdpcp_open { - $rri_ref_sdef = 0x00; # by default check for 'hard' errors - $rri_msk_sdef = 0x70; # ignore cpuhalt,cpugo and attn -} - -#------------------------------------------------------------------------------- - -sub pdpcp_flush { - my ($case) = @_; - rri_cmdlist_do(); -} - -#------------------------------------------------------------------------------- - -sub pdpcp_close { -} - -#------------------------------------------------------------------------------- -# .tocmd n -# .tostp n -# .togo n -# .anena 0|1 -# .rlmon 0|1 -# .rbmon 0|1 -# .scntl n 0|1 -# .sinit g8 g16 -# .sdef [s=g8] -# .cerr 0|1 -# .merr 0|1 -# .reset -# .wait n -# .cclst -# rr* [d=g16] [s=g8] -# wr* g16 [s=g8] -# brm n [s=g8] -# followed by n d=g16 data check values -# bwm n [s=g8] -# followed by n g16 data values -# wal g16 [s=g8] -# wah g16 [s=g8] -# rps [d=g16] [s=g8] -# wps g16 [s=g8] -# rm [d=g16] [s=g8] -# rmi [d=g16] [s=g8] -# wm g16 [s=g8] -# wmi g16 [s=g8] -# stapc g16 [s=g8] -# sta [s=g8] -# sto [s=g8] -# cont [s=g8] -# step [s=g8] -# rst [s=g8] -# wibrb g16 -# ribr g6 [d=g16] [s=g8] -# wibr g6 g16 -# wtgo -# wtlam [d=g16] -# - -sub pdpcp_cexec { - my ($cmd) = @_; - my $cclast; - my $aname; - if ($cmd =~ /^([a-z0-9]*)/) { - $aname = $1; - } - - $cmd =~ s/^rsp/rr6/; # rsp -> rr6 - $cmd =~ s/^rpc/rr7/; # rpc -> rr7 - $cmd =~ s/^wsp/wr6/; # wsp -> wr6 - $cmd =~ s/^wpc/wr7/; # wpc -> wr7 - - $cmd_line = $cmd; - $cmd_rest = ""; - $cmd_bad = 0; - - if ($cmd =~ /^\.to(cmd|stp|go)\s+(\d*)/) {# .tocmd, .tostp, .togo - $cmd_rest = $'; - print "pi_rri($curmode)-I: $cmd currently ignored\n"; - - } elsif ($cmd =~ /^\.anena\s+([01])/) { # .anena ------------------------ - $cmd_rest = $'; - my $ena = int $1; - my $ena_data = ($ena==0) ? 0x0000 : 0x8000; - rri_cmdlist_do(); - push @rri_cmdlist, {cname => "init", - aname => ".anena", - addr => 0xff, - data => $ena_data}; - rri_cmdlist_do(); - - } elsif ($cmd =~ /^(\.rlmon|\.rbmon)\s+([01])/) { # .rlmon, .rbmon --------- - $cmd_rest = $'; - my $ind = ($1 eq ".rlmon") ? 15 : 14; - $cmd_rest = $'; - rri_sideband(0x00, ($ind<<8) + $2); - - } elsif ($cmd =~ /^\.scntl\s+(\d+)\s([01])/) { # .scntl ------------------ - $cmd_rest = $'; - rri_sideband(0x00, ($1<<8) + $2); - - } elsif ($cmd =~ /^\.sinit/) { # .sinit ------------------ - $cmd_rest = $'; - my $addr = cget_gdat(8,$rri_dbasi); - my $data = cget_gdat(16,$rri_dbasi); - rri_sideband($addr, $data) if (not $cmd_bad); - - } elsif ($cmd =~ /^\.sdef/) { # .sdef ------------------------- - $cmd_rest = $'; - ($rri_ref_sdef,$rri_msk_sdef) = cget_tagval2_gdat("s",8,2); - - } elsif ($cmd =~ /^\.[cm]err\s*[01]/) { # .[cm]err - # ignore, no action - - } elsif ($cmd =~ /^\.reset/) { # .reset ------------------------ - $cmd_rest = $'; - rri_cmdlist_do(); # flush before reset - push @rri_cmdlist, {cname => "init", - aname => ".reset", - addr => 0x00, - data => 0x01}; - rri_cmdlist_do(); # flush after reset - - } elsif ($cmd =~ /^\.wait\s+(\d+)/) { # .wait ------------------------ - $cmd_rest = $'; - my $delay = int $1; - rri_cmdlist_do(); # flush before waiting - for (my $i = 0; $i < $delay; $i++) { - raw_snd9(D9IDLE); - } - - } elsif ($cmd =~ /^\.cclst/) { # .cclst ------------------------ - $cmd_rest = $'; - $rri_ncmdmax = scalar(@rri_cmdlist) + 1; # force exec after next cmd - - } elsif ($cmd =~ /^rr([0-7])/) { # rr* --------------------------- - $cmd_rest = $'; - my $rnum = int $1; - pdpcp_cmd_rreg($aname, PDPCP_ADDR_R0+$rnum); - - } elsif ($cmd =~ /^wr([0-7])/) { # wr* --------------------------- - $cmd_rest = $'; - my $rnum = int $1; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_R0+$rnum); - - } elsif ($cmd =~ /^brm/) { # brm --------------------------- - $cmd_rest = $'; - my $addr = PDPCP_ADDR_MEMI; - my $nblk = rri_cget_nblk; - my ($ref_stat, $msk_stat) = rri_cget_stat; - my @ref_rblk; - my @msk_rblk; - my $i; - cget_chkblank(); - for ($i = 0; $i < $nblk; $i++) { - $cmd_rest = get_command() if ($cmd_rest eq ""); - $cmd_rest =~ s/^\s*//; - my ($ref,$msk) = cget_tagval2_gdat("d",16,8); - push @ref_rblk, $ref; - push @msk_rblk, $msk; - } - cget_chkblank(); - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "rblk", - aname => $aname, - addr => $addr, - nblk => $nblk, - ref_rblk => [@ref_rblk], - msk_rblk => [@msk_rblk], - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } elsif ($cmd =~ /^bwm/) { # bwm --------------------------- - $cmd_rest = $'; - my $addr = PDPCP_ADDR_MEMI; - my $nblk = rri_cget_nblk; - my ($ref_stat, $msk_stat) = rri_cget_stat; - my @dat_wblk; - my $i; - cget_chkblank(); - for ($i = 0; $i < $nblk; $i++) { - $cmd_rest = get_command() if ($cmd_rest eq ""); - $cmd_rest =~ s/^\s*//; - push @dat_wblk, cget_gdat(16,8); - } - cget_chkblank(); - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "wblk", - aname => $aname, - addr => $addr, - nblk => $nblk, - dat_wblk => [@dat_wblk], - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } - - } elsif ($cmd =~ /^wal/) { # wal --------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_AL); - - } elsif ($cmd =~ /^wah/) { # wah --------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_AH); - - } elsif ($cmd =~ /^rps/) { # rps --------------------------- - $cmd_rest = $'; - pdpcp_cmd_rreg($aname, PDPCP_ADDR_PSW); - - } elsif ($cmd =~ /^wps/) { # wps --------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_PSW); - - } elsif ($cmd =~ /^rmi/) { # rmi --------------------------- - $cmd_rest = $'; - pdpcp_cmd_rreg($aname, PDPCP_ADDR_MEMI); - - } elsif ($cmd =~ /^rm/) { # rm ---------------------------- - $cmd_rest = $'; - pdpcp_cmd_rreg($aname, PDPCP_ADDR_MEM); - - } elsif ($cmd =~ /^wmi/) { # wmi --------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_MEMI); - - } elsif ($cmd =~ /^wm/) { # wm ---------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_MEM); - - } elsif ($cmd =~ /^stapc/) { # stapc ------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_PC); - pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_STA); - - } elsif ($cmd =~ /^sta/) { # sta --------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_STA); - - } elsif ($cmd =~ /^sto/) { # sto --------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_STO); - - } elsif ($cmd =~ /^cont/) { # cont -------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_CONT); - - } elsif ($cmd =~ /^step/) { # step -------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_STEP); - - } elsif ($cmd =~ /^rst/) { # rst --------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_RST); - - } elsif ($cmd =~ /^wibrb/) { # wibrb ------------------------- - $cmd_rest = $'; - pdpcp_cmd_wreg($aname, PDPCP_ADDR_IBRB); - - } elsif ($cmd =~ /^ribr/) { # ribr -------------------------- - $cmd_rest = $'; - my $off = cget_gdat(6,8); - pdpcp_cmd_rreg($aname, PDPCP_ADDR_IBR+int($off/2)); - - } elsif ($cmd =~ /^wibr/) { # wibr -------------------------- - $cmd_rest = $'; - my $off = cget_gdat(6,8); - pdpcp_cmd_wreg($aname, PDPCP_ADDR_IBR+int($off/2)); - - } elsif ($cmd =~ /^wtgo/) { # wtgo -------------------------- - $cmd_rest = $'; - rri_cmdlist_do(); - my $tstart = get_time(); - raw_get9_check(D9ATTN, "wtgo"); # ???FIXME this is a hack... - printf "-- wtgo # wait for %7.3f sec\n", get_time()-$tstart; - push @rri_cmdlist, {cname => "attn", - aname => ".wtgo"}; - - } elsif ($cmd =~ /^wtlam/) { # wtlam ------------------------- - $cmd_rest = $'; - my ($ref_data, $msk_data) = cget_tagval2_gdat("d",16,8); - rri_cmdlist_do(); - my $tstart = get_time(); - raw_get9_check(D9ATTN, "wtgo"); # ???FIXME this is a hack... - printf "-- wtlam # wait for %7.3f sec\n", get_time()-$tstart; - push @rri_cmdlist, {cname => "attn", - aname => ".wtlam", - ref_data => $ref_data, - msk_data => $msk_data}; - - } else { - print "pi_rri($curmode)-E: unknown command: \"$cmd_line\"\n"; - } - - cget_chkblank() unless $cmd_bad; - if ($cmd_bad) { - print "pi_rri($curmode)-E: parse error, command ignored: \"$cmd_line\"\n"; - } else { - if (scalar(@rri_cmdlist) >= $cmax || $cclast || - ($rri_ncmdmax && scalar(@rri_cmdlist) >= $rri_ncmdmax)) { - $rri_ncmdmax = undef; - rri_cmdlist_do(); - } - } -} - -#------------------------------------------------------------------------------- - -sub pdpcp_cmd_rreg { - my ($aname,$addr) = @_; - my ($ref_data,$msk_data) = cget_tagval2_gdat("d",16,8); - my ($ref_stat,$msk_stat) = rri_cget_stat; - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "rreg", - aname => $aname, - addr => $addr, - ref_data => $ref_data, - msk_data => $msk_data, - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } -} - -#------------------------------------------------------------------------------- - -sub pdpcp_cmd_wreg { - my ($aname,$addr,$data) = @_; - my $ldata = (defined $data) ? $data : cget_gdat(16,8); - my ($ref_stat,$msk_stat) = rri_cget_stat; - if (not $cmd_bad) { - push @rri_cmdlist, {cname => "wreg", - aname => $aname, - addr => $addr, - data => $ldata, - ref_stat => $ref_stat, - msk_stat => $msk_stat}; - } -} - -#------------------------------------------------------------------------------- - -sub serv11_open { - $rri_ref_sdef = 0x00; # by default check for 'hard' errors - $rri_msk_sdef = 0x70; # ignore cpuhalt,cpugo and attn - - serv11_config() unless $serv11_config_done; -} - -#------------------------------------------------------------------------------- - -sub serv11_flush { - my ($case) = @_; -} - -#------------------------------------------------------------------------------- - -sub serv11_close { -} - -#------------------------------------------------------------------------------- -# |>>)file} -# ldabs {-s} file -# exa -# dep g16 -# set ... -# sho conf -# sho att -# sho regs -# sho mmu -# sho ubm[ap] -# wtt "string" -# attn -# att file -# det |all -# init -# boot -# start g16 -# step -# stop -# cont -# reset -# server -# - -sub serv11_cexec { - my ($cmd) = @_; - - $cmd_line = $cmd; - $cmd_rest = ""; - $cmd_bad = 0; - -# -# First handle 'special syntax commands: ( and < -# - - if ($cmd =~ /^([<(])/) { # < and ( short hands ----------- - my $str = $'; - my $ucb = cget_ucb("term", "tt0"); - return if $cmd_bad or cget_chkblank(); - - my @bytes; - if ($1 eq "<") { # < command - conv_str2bytes($str, \@bytes); - push @bytes, 0015; - } else { # ( command - if ($str =~ /^\\([0-7]{3})$/) { # (\ooo escape - push @bytes, oct $1; - } elsif ($str =~ /^\\\^(.)$/) { # (^c escape - my $byt = ord($1); # to byte value - $byt -= 040 if ($byt >= 040); # map to control char - $byt -= 040 if ($byt >= 040); - $byt -= 040 if ($byt >= 040); - push @bytes, $byt; - } else { - conv_str2bytes($str, \@bytes, 1); - } - } - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - &{$ctl->{ichrhdl}}($ucb, \@bytes); - - return; - } - -# -# Now prepare normal syntax commands -# - - if ($cmd =~ /^(\w+)\b/) { # get command name - $cmd = $1; - $cmd_rest = $'; - $cmd_rest =~ s/^\s*//; - } - - if ($cmd =~ /^lspc/) { # dump pc/ps ----------------- - return if cget_chkblank(); - serv11_cexec_shoreg(0); - - } elsif ($cmd =~ /^lsmem/) { # dump memory -------------------- - my $opt_m = cget_opt("-m"); - my $opt_a = cget_opt("-a"); - my $abeg = cget_gdat(22, 8); - return if $cmd_bad; - my $aend = $abeg+64; - my $fh = *STDOUT; - my $redi = 0; - if ($cmd_rest =~ /^:n(\d*)/) { - $cmd_rest = $'; - $aend = $abeg + 2*(int $1); - } elsif ($cmd_rest =~ /^:/) { - $cmd_rest = $'; - $aend = cget_gdat(22, 8); - return if $cmd_bad; - } - if ($cmd_rest =~ /^\s*(>{1,2})([\w\/.-]+)/) { - $cmd_rest = $'; - my $oper = $1; - my $file = $2; - my $fh_new = new FileHandle; - if ($fh_new->open("$oper$file")) { - $fh = $fh_new; - $redi = 1; - } else { - print "pi_rri($curmode)-E: failed to open output file $file\n"; - } - } - - $abeg &= 0xfffffffe; - $aend &= 0xfffffffe; - my $nword = int (($aend - $abeg)/2); - $nword = 1 if $nword <= 1; - - return if cget_chkblank(); - - my @data; - my $rc = serv11_exec_rblk($abeg, 1, \@data, $nword); - - my $inst_nw = 0; - my $inst_str = ""; - printf $fh "Memory %8.8o:%8.8o:\n", $abeg, $aend; - for (my $i=0; $i<$nword; $i++) { - if ($opt_m) { - ($inst_str, $inst_nw) = - pdp11_disassemble($abeg+2*$i, $data[$i],$data[$i+1],$data[$i+2]); - printf $fh " %6.6o :", $abeg+2*$i; - for (my $j=0; $j<3; $j++) { - if ($j < $inst_nw) { - printf $fh " %6.6o", (defined $data[$i+$j]) ? $data[$i+$j] : 0; - } else { - print $fh " "; - } - } - printf $fh " # %s\n", $inst_str; - $i += $inst_nw-1; - - } elsif ($opt_a) { - my $nline = $nword - $i; - my $ascbuf; - $nline = 4 if $nline > 4; - printf $fh " %6.6o :", $abeg+2*$i; - for (my $j=0; $j<$nline; $j++) { - my $word = $data[$i+$j]; - my $bl = $word & 0377; - my $bh = ($word>>8) & 0377; - printf $fh " %3.3o %3.3o", $bl, $bh; - $ascbuf .= " " . conv_byte2ascii2($bl); - $ascbuf .= " " . conv_byte2ascii2($bh); - } - print $fh " " x (8*(4-$nline)+4); - print $fh $ascbuf; - print $fh "\n"; - $i += $nline-1; - - } else { - printf $fh " %6.6o : %6.6o\n", $abeg+2*$i, $data[$i]; - } - } - $fh->close() if $redi; - - } elsif ($cmd =~ /^ldabs/) { # load absolute loader format ---- - my $opt_s = cget_opt("-s"); - my $file = cget_file(); - return if cget_chkblank(); - serv11_cexec_ldabs($file, $opt_s); - - } elsif ($cmd =~ /^exa/) { # examine register or memory ----- - my $optset = cget_optset("ir"); - my ($ctl, $beg, $end) = cget_regrange(); - return if cget_chkblank(); - serv11_cexec_exa($optset, $ctl, $beg, $end); - - - } elsif ($cmd =~ /^dep/) { # deposit register or memory ----- - my $optset = cget_optset("ir"); - my ($ctl, $beg, $end) = cget_regrange(); - my $data = cget_gdat(16, 8); - return if cget_chkblank(); - serv11_cexec_dep($optset, $ctl, $beg, $end, $data); - - - } elsif ($cmd =~ /^set/) { # set parameter ------------------ - my $what = cget_name(); - return if $cmd_bad; - - if ($what =~ /^sim/) { # set sim[ulator] ------ - my $pnam = cget_name(); - my $val = cget_bool(); - return if $cmd_bad or cget_chkblank(); - my $ind; - $ind = 15 if $pnam eq "rlmon"; - $ind = 14 if $pnam eq "rbmon"; - $ind = 13 if $pnam eq "tmu"; - if (defined $ind) { - rri_sideband(0x00, ($ind<<8) + $val); - } else { - printf "pi_rri($curmode)-E: Invalid parameter '$pnam' for set sim\n"; - } - - } else { # set --------- - my $ctl = $serv11_ctltbl{uc($what)}; - if (defined $ctl) { - my $partbl = $ctl->{partbl}; - if (defined $partbl) { - my $pnam = cget_name(); - return if $cmd_bad; - - my $pdsc = $partbl->{$pnam}; - if (defined $pdsc) { - my $type = $pdsc->{type}; - if ($type =~ /^hval:([bdos])$/) { - my $cnv = $1; - my $val; - if ($cnv eq "b") { - $val = cget_bool(); - } elsif ($cnv eq "d") { - $val = cget_gdat(32, 10); - } elsif ($cnv eq "o") { - $val = cget_gdat(32, 8); - } elsif ($cnv eq "s") { - $val = $cmd_rest; - $val =~ s/^\s*//; - $val =~ s/\s*$//; - $cmd_rest = ""; - } - return if $cmd_bad or cget_chkblank(); - $ctl->{$pnam} = $val; - } else { - print "pi_rri($curmode)-E: unexpected type $type in partbl\n"; - } - } else { - print "pi_rri($curmode)-E: '$pnam' not valid for 'set $what'\n"; - } - } else { - print "pi_rri($curmode)-I: nothing to set for '$what'\n"; - } - } else { - print "pi_rri($curmode)-E: unknown entity for 'set': \"$what\"\n"; - } - } - - } elsif ($cmd =~ /^sho/) { # show parameters ---------------- - my $what = cget_name(); - return if $cmd_bad; - - if ($what =~ /^conf/) { # sho conf[iguration] -- - return if cget_chkblank(); - serv11_cexec_shoconf(); - - } elsif ($what =~ /^att/) { # sho att -------------- - return if cget_chkblank(); - serv11_cexec_shoatt(); - - } elsif ($what =~ /^regs/) { # sho regs ------------- - return if cget_chkblank(); - serv11_cexec_shoreg(1); - - } elsif ($what =~ /^mmu/) { # sho mmu -------------- - return if cget_chkblank(); - serv11_cexec_shommu_ssrx; - serv11_cexec_shommu_sadr(0172300, "KM"); - serv11_cexec_shommu_sadr(0172200, "SM"); - serv11_cexec_shommu_sadr(0177600, "UM"); - - } elsif ($what =~ /^ubm/) { # sho ubmap ------------ - return if cget_chkblank(); - - my @data; - my $rc = serv11_exec_rblk(0170200, 0, \@data, 64); - print "UNIBUS mapping registers:\n"; - for (my $i=0; $i<32; $i++) { - printf " [%2d]: %2.2o,%6.6o\n", $i, $data[2*$i+1], $data[2*$i]; - } - - } else { # sho --------- - my $ctl = $serv11_ctltbl{uc($what)}; - if (defined $ctl) { - my $partbl = $ctl->{partbl}; - if (defined $partbl) { - foreach my $pnam (sort keys %{$partbl}) { - my $pdsc = $partbl->{$pnam}; - my $type = $pdsc->{type}; - if ($type =~ /^hval:([bdos])$/) { - my $cnv = $1; - my $val = $ctl->{$pnam}; - my $val_str = $val; - if (defined $val) { - $val_str = ($val) ? "1 (yes)" : "0 (no)" if $cnv eq "b"; - $val_str = sprintf("%6d.", $val) if $cnv eq "d"; - $val_str = sprintf("%6.6o", $val) if $cnv eq "o"; - } else { - $val_str = ""; - } - printf "%4s %10s : %s\n", uc($what), $pnam, $val_str; - } else { - print "pi_rri($curmode)-E: unexpected type $type in partbl\n"; - } - } - } else { - print "pi_rri($curmode)-I: nothing to show for '$what'\n"; - } - } else { - print "pi_rri($curmode)-E: unknown entity for 'sho': \"$what\"\n"; - } - } - - } elsif ($cmd =~ /^wtt/) { # write to TT decives ------------- - my $ucb = cget_ucb("term"); - my $str = "\\n"; - if ($cmd_rest =~ /^\s*"(.*)"\s*/) { - $cmd_rest = $'; - $str = $1; - } - return if $cmd_bad or cget_chkblank(); - - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - my @bytes; - conv_str2bytes($str, \@bytes, 1); - &{$ctl->{ichrhdl}}($ucb, \@bytes) - - } elsif ($cmd =~ /^attn/) { # attn -------------------------- - return if cget_chkblank(); - serv11_server_attn_get(); - - } elsif ($cmd =~ /^att/) { # attach ------------------------ - my $ucb = cget_ucb(); - return if $cmd_bad; - serv11_cexec_attdet(0,$ucb); - - } elsif ($cmd =~ /^det/) { # detach ------------------------ - my $ucb = cget_ucb(); - return if cget_chkblank(); - serv11_cexec_attdet(1,$ucb); - - } elsif ($cmd =~ /^init/) { # init -------------------------- - return if cget_chkblank(); - serv11_init_dispatch() if $serv11_init_pending; - - } elsif ($cmd =~ /^boot/) { # boot -------------------------- - my $ucb = cget_ucb(); - return if $cmd_bad or cget_chkblank(); - serv11_cexec_boot($ucb); - - } elsif ($cmd =~ /^start/) { # start -------------------------- - my $addr = cget_gdat(16, 8); - return if cget_chkblank(); - my @rval; - my $rc; - serv11_rri_init(".anena", 0xff, $serv11_init_anena);# enable attn+ioto - serv11_rri_attn("attn"); # discard old attn's - serv11_rri_wreg("wpc", PDPCP_ADDR_PC, $addr); - serv11_rri_wreg("sta", PDPCP_ADDR_CNTL, PDPCP_FUNC_STA); - $rc = serv11_rri_exec(\@rval); - - } elsif ($cmd =~ /^step/) { # step -------------------------- - my @rval; - my $rc; - serv11_rri_wreg("sta", PDPCP_ADDR_CNTL, PDPCP_FUNC_STEP); - $rc = serv11_rri_exec(\@rval); - serv11_cexec_shoreg(1); - - } elsif ($cmd =~ /^stop/) { # stop -------------------------- - my @rval; - my $rc; - serv11_rri_wreg("sto", PDPCP_ADDR_CNTL, PDPCP_FUNC_STO); - $rc = serv11_rri_exec(\@rval); - serv11_cexec_shoreg(1); - - } elsif ($cmd =~ /^cont/) { # cont -------------------------- - my @rval; - my $rc; - serv11_rri_wreg("sto", PDPCP_ADDR_CNTL, PDPCP_FUNC_CONT); - $rc = serv11_rri_exec(\@rval); - - } elsif ($cmd =~ /^reset/) { # reset ------------------------- - my @rval; - my $rc; - serv11_rri_wreg("rst", PDPCP_ADDR_CNTL, PDPCP_FUNC_RST); - $rc = serv11_rri_exec(\@rval); - - } elsif ($cmd =~ /^server/) { # enter server mode -------------- - return if cget_chkblank(); - serv11_server(); - - } else { - print "pi_rri($curmode)-E: unknown command: \"$cmd_line\"\n"; - } -} - - -#------------------------------------------------------------------------------- - -sub serv11_cexec_shoreg { - my ($mode) = @_; - my $ipc; - my $ips; - my @rval; - - if ($mode > 0) { - serv11_rri_rreg("rr0", PDPCP_ADDR_R0+0); - serv11_rri_rreg("rr1", PDPCP_ADDR_R0+1); - serv11_rri_rreg("rr2", PDPCP_ADDR_R0+2); - serv11_rri_rreg("rr3", PDPCP_ADDR_R0+3); - serv11_rri_rreg("rr4", PDPCP_ADDR_R0+4); - serv11_rri_rreg("rr5", PDPCP_ADDR_R0+5); - serv11_rri_rreg("rr6", PDPCP_ADDR_R0+6); - } - $ipc = serv11_rri_rreg("rr7", PDPCP_ADDR_R0+7); - $ips = serv11_rri_rreg("rps", PDPCP_ADDR_PSW); - - my $rc = serv11_rri_exec(\@rval); - - print "Processor registers and status:\n" if ($mode > 0); - - my $ps_bin = gconv_dat16($rval[$ips],2); - - printf " PC: %6.6o ", $rval[$ipc] if ($mode == 0); - printf " PS: %6.6o", $rval[$ips]; - printf " cmo=%s",substr($ps_bin,0,2); # bit 15:14 -> 0,2 - printf " pmo=%s",substr($ps_bin,2,2); # bit 13:12 -> 2,2 - printf " set=%s",substr($ps_bin,4,1); # bit 11 -> 4 - printf " pri=%d",($rval[$ips]>>5)&0x7; # bit 07:05 - printf " t=%s", substr($ps_bin,11,1); # bit 04 -> 11,1 - printf " NZVC=%s", substr($ps_bin,12,4); # bit 03:00 -> 12,4 - print "\n"; - - if ($mode > 0) { - printf " R0: %6.6o", $rval[0]; - printf " R1: %6.6o", $rval[1]; - printf " R2: %6.6o", $rval[2]; - printf " R3: %6.6o\n", $rval[3]; - printf " R4: %6.6o", $rval[4]; - printf " R5: %6.6o", $rval[5]; - printf " SP: %6.6o", $rval[6]; - printf " PC: %6.6o\n", $rval[$ipc]; - } -} - -#------------------------------------------------------------------------------- -# ssr0 177572 -# ssr1 177574 -# ssr2 177576 -# ssr3 172516 - -sub serv11_cexec_shommu_ssrx { - my @rval; - - serv11_rri_wreg("wal", PDPCP_ADDR_AL, 0177572); - my $issr0 = serv11_rri_rreg("rmi", PDPCP_ADDR_MEMI); - my $issr1 = serv11_rri_rreg("rmi", PDPCP_ADDR_MEMI); - my $issr2 = serv11_rri_rreg("rmi", PDPCP_ADDR_MEMI); - serv11_rri_wreg("lal", PDPCP_ADDR_AL, 0172516); - my $issr3 = serv11_rri_rreg("rmi", PDPCP_ADDR_MEMI); - - my $rc = serv11_rri_exec(\@rval); - - print "MMU registers:\n"; - printf " SSR0: %6.6o\n", $rval[$issr0]; - printf " SSR1: %6.6o\n", $rval[$issr1]; - printf " SSR2: %6.6o\n", $rval[$issr2]; - printf " SSR3: %6.6o\n", $rval[$issr3]; - -} - -#------------------------------------------------------------------------------- -# -# Note: The ptape maindec's have even size records, except possibly for the -# last one, and always start at an even address. -# The lda's extracted with UPD2 PIP from the xxdp22 disk have often -# records with 503 byte payload, starting at even and odd addresses. -# Since blkw only handles even sized transfers on even addresses some -# magic with the %oddbyt hash is needed to handle this correctly. -# -sub serv11_cexec_ldabs { - my ($file,$opt_s) = @_; - if (not -r $file) { - print "pi_rri($curmode)-E: file $file not found or readable\n"; - return; - } - my $fh = new FileHandle; - - $fh->open("<$file") or die "unexpected open failure"; - - my $chrnum = 0; # char number in block - my $blknum = 0; # block number - my $bytcnt = 0; # byte count - my $ldaddr = 0; # load address - my $chksum = 0; # check sum - my $addr = 0; # current address - my @data; # data array for transfer - my %oddbyt; # odd byte cache - my $word; - - while (1) { - my $buf; - my $rc = $fh->read($buf,1); - if ($rc == 0) { - print "pi_rri($curmode)-E: unexpected EOF in $file\n" unless $chrnum == 0; - return; - } - - return if $rc != 1; - my $byt = ord($buf); - - #printf "+++1 cn=%3d byt=%3.3o cnt=%4d addr=%6.6o sum=%3.3o\n", - # $chrnum, $byt&0377, $bytcnt, $ldaddr, $chksum; - - $chksum = ($chksum + $byt) & 0377; - - if ($chrnum == 0) { # in blank tape - if ($byt == 0) { - next; - } elsif ($byt == 1) { - $chrnum += 1; - } else { - printf "pi_rri($curmode)-E: unexpected start-of-block %3.3o in $file\n", - $byt; - return; - } - - } elsif ($chrnum == 1) { # 001 frame seen - if ($byt == 0) { - $chrnum += 1; - } else { - printf "pi_rri($curmode)-E: unexpected 2nd char %3.3o in $file\n", - $byt; - return; - } - - } elsif ($chrnum == 2) { # byte count low - $bytcnt = $byt & 0377; - $chrnum += 1; - } elsif ($chrnum == 3) { # byte count high - $bytcnt |= ($byt & 0377)<<8; - $chrnum += 1; - - } elsif ($chrnum == 4) { # load address low - $ldaddr = $byt & 0377; - $chrnum += 1; - } elsif ($chrnum == 5) { # load address high - $ldaddr |= ($byt & 0377)<<8; - $chrnum += 1; - printf "pi_rri($curmode)-I: block %3d, length %5d byte,". - " address %6.6o:%6.6o\n", - $blknum, ($bytcnt-6), $ldaddr, $ldaddr+($bytcnt-6)-1; - - $addr = $ldaddr; # setup current address - $word = 0; - if (($addr & 01) == 1 && $bytcnt > 6) { # setup even byte if known... - $word = $oddbyt{sprintf("%6.6o",$addr)}; - if (not defined $word) { - printf "pi_rri($curmode)-W: no low byte data for %6.6o\n", $addr; - $word = 0; - } - } - - } elsif ($chrnum == $bytcnt) { # check sum byte - if ($chksum != 0) { - printf "pi_rri($curmode)-E: check sum error %3.3o in $file\n", - $chksum; - return; - } - if ($chrnum == 6) { - printf "pi_rri($curmode)-I: start address %6.6o\n", $ldaddr; - return; - } else { - if (($addr & 01) == 1) { # high byte not yet seen - push @data, $word; # zero fill high byte - $oddbyt{sprintf("%6.6o",$addr)} = $word; # store even byte for later - # note that address is odd here - } - serv11_exec_wblk($ldaddr, 0, \@data); - @data = (); - } - $chrnum = 0; - $blknum += 1; - - } else { # in data - if (($addr & 01) == 0) { # low byte - $word = $byt & 0377; - $addr += 1; - } else { # high byte - $word |= ($byt & 0377)<<8; - push @data, $word; - $addr += 1; - } - $chrnum += 1; - } - } - - $fh->close(); -} - -#------------------------------------------------------------------------------- -# sadr format: -# offset 0: DR[0] I space -# offset 20: DR[0] D space -# offset 40: AR[0] I space -# offset 60: AR[0] D space -# -sub serv11_cexec_shommu_sadr { - my ($base,$mode) = @_; - my @data; - my $rc = serv11_exec_rblk($base, 0, \@data, 32); - - for (my $i=0; $i<16; $i++) { - my $space = ($i<8) ? "I" : "D"; - my $ind = $i%8; - my $dr = $data[$i]; - my $ar = $data[$i+16]; - my $dr_bin = gconv_dat16($dr,2); - my $dr_acf = $dr&0xf; # bit 3:0 - - printf " %s-%s[%d]: %6.6o,%6.6o", $mode,$space,$ind, $dr, $ar; - printf " slf=%3d", ($dr>>8)&0xff; - printf " aib=%s", substr($dr_bin,8,2); # bit 7:6 -> 8,2 - printf " acf=%d", $dr_acf; - print "\n"; - } - -} - -#------------------------------------------------------------------------------- - -sub serv11_cexec_shoconf { - foreach my $ctlname (sort { $serv11_ctltbl{$b}->{base} <=> - $serv11_ctltbl{$a}->{base} } - keys %serv11_ctltbl) { - my $ctl = $serv11_ctltbl{$ctlname}; - my $mask = $ctl->{probemask}; - my $ival = $ctl->{probe_ival}; - my $rval = $ctl->{probe_rval}; - my $ib_str = ($mask =~ /i/) ? ( (defined $ival) ? "y" : "n" ) : "-"; - my $rb_str = ($mask =~ /r/) ? ( (defined $rval) ? "y" : "n" ) : "-"; - printf "%-3s %-9s %4s: %s ib=%s rb=%s lam=%s boot=%s", $ctlname, - $ctl->{ctltype}, $ctl->{type}, - ($ctl->{base} ? sprintf("%6.6o", $ctl->{base}) : "......"), - $ib_str, $rb_str, - (exists $ctl->{lam} ? sprintf("%2d",$ctl->{lam}) : " -"), - (exists $ctl->{boot_code} ? "y" : "n"); - printf " %s",$ctl->{probe_text} if $ctl->{probe_text}; - print "\n"; - } -} - -#------------------------------------------------------------------------------- - -sub serv11_cexec_shoatt { - foreach my $unitname (sort keys %serv11_unittbl) { - my $ucb = $serv11_unittbl{$unitname}; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - next unless $ctl->{probe_ok}; - next unless $ucb->{att_ok}; - printf "%-3s : ", $unitname; - if ($ctl->{type} eq "disk") { - printf "nblk=%6d wp=%s file=%s", - $ucb->{att_nblk}, - ($ucb->{att_wpro} ? "y" : "n"), - $ucb->{att_file}; - } elsif ($ctl->{type} eq "tape") { - printf "wp=%s file=%s", - ($ucb->{att_wpro} ? "y" : "n"), - $ucb->{att_file}; - } elsif ($ctl->{type} eq "term") { - printf "port=%s", - $ucb->{att_port}; - } - print "\n"; - } -} - -#------------------------------------------------------------------------------- - -sub serv11_cexec_attdet { - my ($det,$ucb) = @_; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - - my $attdethdl = $ctl->{attdethdl}; - - if (not defined $attdethdl) { - printf "pi_rri($curmode)-E: attach/detach not supported for %s\n", - $ucb->{unitname}; - return; - } - - &{$attdethdl}($det, $ucb); # call handler - -} - -#------------------------------------------------------------------------------- - -sub serv11_cexec_boot { - my ($ucb) = @_; - my @rval; - my $rc; - - my $unitname = $ucb->{unitname}; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - - if (not exists $ctl->{boot_code}) { - print "pi_rri($curmode)-E: device $unitname not bootable\n"; - return; - } - - serv11_init_dispatch() if $serv11_init_pending; - - my @boot_code = @{$ctl->{boot_code}}; - my $boot_length = scalar(@boot_code); - my $boot_mode = $ctl->{boot_mode}; - my $boot_entry = $ctl->{boot_entry}; - - $boot_mode = "disk" unless defined $boot_mode; - - if ($boot_mode eq "disk") { - my $boot_unit = $ctl->{boot_unit}; - $boot_code[int (($boot_unit-(BOOT_START))/2)] = - $ucb->{ctlunit}; # patch in unit num - $rc = serv11_exec_wblk(BOOT_START, 0, \@boot_code, $boot_length); - - } elsif ($boot_mode eq "ptape") { - my $boot_base = $ctl->{boot_base}; - my $memsize = 56 * 1024; # FIXME: check memtop !!! - $memsize = 56*1024 if ($memsize > 56*1024); - my $nblk8k = $memsize/020000; - my $offset = ($nblk8k-1) * 020000; - $boot_base += $offset; - $boot_entry += $offset; - $rc = serv11_exec_wblk($boot_base, 0, \@boot_code, $boot_length); - - } else { - print_fatal("unsupported boot mode '$boot_mode' in serv11_cexec_boot"); - } - - serv11_rri_init(".anena", 0xff, $serv11_init_anena); # enable attn+ioto - serv11_rri_attn("attn"); # discard old attn's - serv11_rri_wreg("wpc", PDPCP_ADDR_PC, $boot_entry); - serv11_rri_wreg("sta", PDPCP_ADDR_CNTL, PDPCP_FUNC_STA); - - $rc = serv11_rri_exec(\@rval); -} - -#------------------------------------------------------------------------------- - -sub serv11_cexec_exa { - my ($optset,$ctl,$beg,$end) = @_; - - if (not defined $ctl) { # numerical address - for (my $addr=$beg; $addr<=$end; $addr+=2) { - my @rval; - serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); - serv11_rri_rreg("rm", PDPCP_ADDR_MEM); - my $rc = serv11_rri_exec(\@rval); - printf "mem %6.6o : %6.6o\n", $addr, $rval[0]; - } - - } else { - - my $reglist = $ctl->{reglist}; - for (my $i=$beg; $i<=$end; $i++) { - my $dsc = $reglist->[$i]; - last if not defined $reglist->[$i]; - my $name = $dsc->{name}; - my $addr = $dsc->{addr}; - my $offset = $dsc->{offset}; - my $attr = $dsc->{attr}; - my $val; - my $addr_str = "......"; - my $acs_str = "ib"; - my $val_str = "......"; - my $com_str = ""; - - $addr = $ctl->{base} + $offset if defined $offset; - - $attr = 0 unless defined $attr; - - $acs_str = "rb" if ($attr & REGATTR_RBRD); - $acs_str = "ib" if $optset =~ /i/; - $acs_str = "rb" if $optset =~ /r/; - - if ($end > $beg && - ( ( ($attr & REGATTR_IBMBOX) && $acs_str eq "ib" ) || - ( ($attr & REGATTR_RBMBOX) && $acs_str eq "rb" ) - ) ) { - $com_str = "mailbox skipped"; - - } else { - - my $exadethdl = $dsc->{hdl}; - if (defined $dsc->{hdl}) { - $acs_str = " "; - $val = &{$dsc->{hdl}}(0, $dsc); - - } else { - if ($acs_str eq "rb") { - my $ibrbase = $addr & ~(077); - my $ibroff = $addr - $ibrbase; - serv11_rri_wreg("wibrb", PDPCP_ADDR_IBRB, $ibrbase); - serv11_rri_rreg("ribr", PDPCP_ADDR_IBR + int($ibroff/2)); - $acs_str = "rb"; - } else { - serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); - serv11_rri_rreg("rm", PDPCP_ADDR_MEM); - $acs_str = "ib"; - } - my @rval; - my $rc = serv11_rri_exec(\@rval); - $val = $rval[0]; - } - } - - $addr_str = sprintf("%6.6o", $addr) if defined $addr; - $val_str = sprintf("%6.6o", $val) if defined $val; - printf "%4s %6s %2s %6s : %6s", $ctl->{ctlname}, $name, - $acs_str, $addr_str, $val_str; - print " $com_str" if defined $com_str; - print "\n"; - } - - } -} - -#------------------------------------------------------------------------------- - -sub serv11_cexec_dep { - my ($optset,$ctl,$beg,$end,$data) = @_; - - if (not defined $ctl) { # numerical address - for (my $addr=$beg; $addr<=$end; $addr+=2) { - my @rval; - serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); - serv11_rri_wreg("wm", PDPCP_ADDR_MEM, $data); - my $rc = serv11_rri_exec(\@rval); - } - - } else { - - my $reglist = $ctl->{reglist}; - for (my $i=$beg; $i<=$end; $i++) { - my $dsc = $reglist->[$i]; - last if not defined $reglist->[$i]; - my $name = $dsc->{name}; - my $addr = $dsc->{addr}; - my $offset = $dsc->{offset}; - my $attr = $dsc->{attr}; - my $acs_str = "ib"; - - $addr = $ctl->{base} + $offset if defined $offset; - - $attr = 0 unless defined $attr; - - $acs_str = "rb" if ($attr & REGATTR_RBWR); - $acs_str = "ib" if $optset =~ /i/; - $acs_str = "rb" if $optset =~ /r/; - - my $exadethdl = $dsc->{hdl}; - if (defined $dsc->{hdl}) { - $acs_str = " "; - &{$dsc->{hdl}}(1, $dsc, $data); - - } else { - if ($acs_str eq "rb") { - my $ibrbase = $addr & ~(077); - my $ibroff = $addr - $ibrbase; - serv11_rri_wreg("wibrb", PDPCP_ADDR_IBRB, $ibrbase); - serv11_rri_wreg("wibr", PDPCP_ADDR_IBR + int($ibroff/2), $data); - $acs_str = "rb"; - } else { - serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); - serv11_rri_wreg("wm", PDPCP_ADDR_MEM, $data); - $acs_str = "ib"; - } - my @rval; - my $rc = serv11_rri_exec(\@rval); - } - - } - - } - -} - -#------------------------------------------------------------------------------- -# config is called once on the first entering of serv11 mode -# -sub serv11_config { - $serv11_config_done = 1; - - foreach my $ctlname (sort keys %serv11_ctltbl) { - my $ctl = $serv11_ctltbl{$ctlname}; - $ctl->{probemask} = "ir" unless defined $ctl->{probemask}; - &{$ctl->{probehdl}}($ctl) if exists $ctl->{probehdl}; - } - - if (not $serv11_ctltbl{CPU}->{probe_ok}) { - print_fatal("probe of CPU failed in serv11_open()"); - } - - init_regtbl(); - serv11_cexec_shoconf(); -} - -#------------------------------------------------------------------------------- - -sub serv11_init_dispatch { - foreach my $ctlname (sort keys %serv11_ctltbl) { - my $ctl = $serv11_ctltbl{$ctlname}; - &{$ctl->{inithdl}}($ctl) if (exists $ctl->{inithdl} && $ctl->{probe_ok}); - } - $serv11_init_pending = 0; -} - -#------------------------------------------------------------------------------- - -sub serv11_server { - my $old_timeout = $raw_timeout; - my $nfound; - my $fds_rd_act = ""; - my $fds_rd; - my $stat_delta = 10.; - my $stat_count = 0; - - my $fno_rcv = fileno($fh_rcv); - my $fno_stdin = fileno(STDIN); - - my @telfno2dsc; - - @serv11_attntbl = (); - foreach my $ctlname (sort keys %serv11_ctltbl) { - my $ctl = $serv11_ctltbl{$ctlname}; - if ($ctl->{probe_ok} && exists $ctl->{lam} && exists $ctl->{attnhdl}) { - push @serv11_attntbl, [1<<($ctl->{lam}), $ctl->{attnhdl}, $ctl]; - } - } - - $raw_timeout = 30.; - $serv11_active = 1; - print "pi_rri($curmode)-I: entering server mode\n"; - - my $time_stat = get_time() + $stat_delta; - - while ($serv11_active) { - my $time_now = get_time(); - if ($time_now >= $time_stat) { - ##serv11_server_attn_dispatch(1); - if ($stat_count % 20 == 0) { - printf $fh_log "stat -- "; - printf $fh_log " obyte oesc osop ibyte iesc att"; - printf $fh_log " xreg xblk rdisk wdisk"; - printf $fh_log "\n"; - } - $stat_count += 1; - my $dt = $stat_delta; - - printf $fh_log "stat -- %s", get_timestamp(); - printf $fh_log " %6.0f", ($stat_tab{obyte} - $stat_tab_last{obyte})/$dt; - printf $fh_log " %4.0f", ($stat_tab{oesc} - $stat_tab_last{oesc})/$dt; - printf $fh_log " %4.0f", ($stat_tab{osop} - $stat_tab_last{osop})/$dt; - printf $fh_log " %6.0f", ($stat_tab{ibyte} - $stat_tab_last{ibyte})/$dt; - printf $fh_log " %4.0f", ($stat_tab{iesc} - $stat_tab_last{iesc})/$dt; - printf $fh_log " %3.0f", ($stat_tab{att} - $stat_tab_last{att})/$dt; - printf $fh_log " %5.0f", ($stat_tab{xreg} - $stat_tab_last{xreg})/$dt; - printf $fh_log " %4.0f", ($stat_tab{xblk} - $stat_tab_last{xblk})/$dt; - printf $fh_log " %6.0f", ($stat_tab{rdisk} - $stat_tab_last{rdisk})/$dt; - printf $fh_log " %6.0f", ($stat_tab{wdisk} - $stat_tab_last{wdisk})/$dt; - printf $fh_log "\n"; - %stat_tab_last = %stat_tab; - - while ($time_stat < $time_now) { - $time_stat += $stat_delta; - } - } - - my $timeout = $time_stat - $time_now; - - # set timeout=0 if some unfinished business is still pending - - $timeout = 0. if $serv11_attn_mask != 0; # attn mask not yet worked down - $timeout = 0. if scalar(@serv11_icbque); # icb queue non empty - $timeout = 0. if scalar(@que_rcv); # still input chars in buffer - - if ($serv11_fds_update) { - $fds_rd_act = ""; - vec($fds_rd_act, $fno_rcv, 1) = 1; - vec($fds_rd_act, $fno_stdin, 1) = 1; - - @telfno2dsc = (); - foreach my $port_str (keys %telnettbl) { - my $teldsc = $telnettbl{$port_str}; - my $fno; - if ($teldsc->{state} == TELNET_STATE_LISTEN) { - $fno = fileno($teldsc->{fh_port}); - } else { - $fno = fileno($teldsc->{fh_data}); - } - vec($fds_rd_act, $fno, 1) = 1; - push @telfno2dsc, [$fno, $teldsc]; - } - $serv11_fds_update = 0; - } - - ##printf $fh_log "+++1 select $timeout, rcvq=%d\n", scalar(@que_rcv); - $nfound = select($fds_rd=$fds_rd_act, undef, undef, $timeout); - ##printf $fh_log "+++2 select $nfound\n"; - - if (vec($fds_rd, $fno_stdin, 1)) { - my $cmd = ; - if (defined $cmd) { - chomp $cmd; - - $cmd = "lspc" unless $cmd ne ""; - - $cmd =~ s{^\s*}{}; # remove leading blanks - $cmd =~ s{--.*}{}; # remove comments after -- - $cmd =~ s{\s*$}{}; # remove trailing blanks - - - if ($cmd eq "quit") { - $serv11_active = 0; - } else { - if ($cmd =~ m/^C/) { # ignore, but log "C ..." lines - print $fh_log "$cmd\n"; - } elsif ($cmd =~ m/^#/) { # ignore "# ...." lines - } elsif ($cmd =~ m/^;/) { # ignore "; ...." lines - } else { # otherwise execute - serv11_cexec($cmd); - } - } - } else { # handle ^D - $serv11_active = 0; - } - } - - # process next input char if read will not block (either fd ready for - # input, or still chars in queue). - - if (vec($fds_rd, $fno_rcv, 1) || scalar(@que_rcv)) { - my $dat = raw_rcv9_to(0.); - if (not defined $dat) { - print "pi_rri($curmode)-I: spurious select on rcv channel\n"; - next; - } elsif ($dat == D9IDLE) { - next; - } elsif ($dat == D9ATTN) { - serv11_server_attn_get(); - } else { - printf "pi_rri($curmode)-I: spurious char on server wait: %3.3x\n", - $dat; - next; - } - } - - # process telnet sessions - foreach (@telfno2dsc) { - my $fno = $_->[0]; - if (vec($fds_rd, $fno, 1)) { - my $teldsc = $_->[1]; - telnet_readhdl($teldsc); - } - } - - if ($serv11_attn_mask != 0) { - serv11_server_attn_dispatch(0); - } - - if (scalar(@serv11_icbque)) { - my $icb = shift @serv11_icbque; - &{$icb->{rdmahdl}}($icb); - } - - if ($serv11_attn_mask == 0 && $serv11_attn_seen) { - $serv11_attn_seen = 0; - serv11_server_attn_get(); - } - - } - - $raw_timeout = $old_timeout; - $serv11_active = 0; - print "pi_rri($curmode)-I: leaving server mode\n"; -} - -#------------------------------------------------------------------------------- - -sub serv11_server_attn_get { - my @rval; - my $rc; - - serv11_rri_attn("attn"); - $rc = serv11_rri_exec(\@rval); - - my $mask_old = $serv11_attn_mask; - $serv11_attn_mask |= $rval[0]; # or-in new attn flags - - if (exists $opts{tserv}) { - printf $fh_log "serv -- attn %s :", gconv_dat16($serv11_attn_mask, 2); - foreach my $adsc (@serv11_attntbl) { - my $msk = $adsc->[0]; - my $ctl = $adsc->[2]; - if ($serv11_attn_mask & $msk) { - my $pref = ""; - my $suff = ""; - if ($mask_old & $msk) { # old flags are in () - $pref = "("; - $suff = ")"; - } - printf $fh_log " %s%s%s", $pref, $ctl->{ctlname}, $suff; - } - } - printf $fh_log "\n"; - } - -} - -#------------------------------------------------------------------------------- - -sub serv11_server_attn_dispatch { - my ($force) = @_; - foreach my $adsc (@serv11_attntbl) { - my $msk = $adsc->[0]; - my $hdl = $adsc->[1]; - my $ctl = $adsc->[2]; - if (($serv11_attn_mask & $msk) || $force) { - $serv11_attn_mask &= ~$msk; - &{$hdl}($ctl,$force); - } - } -} - -#------------------------------------------------------------------------------- - -sub serv11_probe_gen { # generic probe handler - my ($ctl) = @_; - my $mask = $ctl->{probemask}; - my $addr = $ctl->{base}; - $addr += $ctl->{csroff} if defined $ctl->{csroff}; - my ($ival,$rval) = serv11_exec_probe($addr, $mask); - $ctl->{probe_ival} = $ival; - $ctl->{probe_rval} = $rval; - $ctl->{probe_ok} = 1; - $ctl->{probe_ok} = 0 if ($mask =~ /i/ && ! defined $ival); - $ctl->{probe_ok} = 0 if ($mask =~ /r/ && ! defined $rval); -} - -#------------------------------------------------------------------------------- - -sub serv11_init_gen { # generic controller init handler - my ($ctl) = @_; - - if (exists $ctl->{usethdl}) { - foreach my $unitname (@{$ctl->{units}}) { - my $ucb = $serv11_unittbl{$unitname}; - &{$ctl->{usethdl}}($ucb); - } - } else { - printf "pi_rri($curmode)-E: usethdl not defined for %s\n", $ctl->{ctlname}; - } -} - -#------------------------------------------------------------------------------- - -sub serv11_detach_gen { # generic detach handler - my ($ucb) = @_; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - - if ($ucb->{att_ok}) { - my $fh = $ucb->{att_fh}; - $fh->close() or die "Unexpected close error"; - $ucb->{att_ok} = 0; - delete $ucb->{att_file}; - delete $ucb->{att_nbyt}; - delete $ucb->{att_nblk}; - delete $ucb->{att_wpro}; - delete $ucb->{att_fh}; - delete $ucb->{att_eof}; - &{$ctl->{usethdl}}($ucb); # setup unit registers - - } else { - printf "pi_rri($curmode)-E: no file attached for %s\n", $ucb->{unitname}; - } -} - -#------------------------------------------------------------------------------- - -sub serv11_attdet_disk { # generic disk att/det handler - my ($det,$ucb) = @_; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - - if ($det) { # detach handling - serv11_detach_gen($ucb); - - } else { # attach handling - if (cget_opt("-w")) { # -w remount - return if $cmd_bad or cget_chkblank(); - my $fh = $ucb->{att_fh}; - if ($fh) { # mounted and open ? - if (-w $fh) { # file writable ? - $ucb->{att_wpro} = 0; # remove write protect - &{$ctl->{usethdl}}($ucb); # setup unit registers - } else { - printf "pi_rri($curmode)-E: file %s (for %s) is write protected\n", - $ucb->{att_file}, $ucb->{unitname}; - return; - } - } else { - printf "pi_rri($curmode)-E: no file attached for %s\n", - $ucb->{unitname}; - return; - } - - } else { # normal (non -w) handling - my $opt_r = cget_opt("-r"); - my $filename = cget_file(); - return if $cmd_bad or cget_chkblank(); - - if (not -e $filename) { - print "pi_rri($curmode)-E: file $filename not found\n"; - return; - } - if (not -r $filename) { - print "pi_rri($curmode)-E: file $filename is not readable\n"; - return; - } - - my $wpro = $opt_r; - if (! $wpro && ! -w $filename) { - print "pi_rri($curmode)-I: file $filename is write protected\n"; - $wpro = 1; - } - - my $filesize = -s $filename; - - if (defined $ctl->{volsize}) { - if ($filesize < $ctl->{volsize}) { - printf "pi_rri($curmode)-W: dsk file too small, %s requires %d". - " file $filename has %d bytes\n", - $ucb->{unitname}, $ctl->{volsize}, $filesize; - } - } - - my $fh = new FileHandle; - sysopen ($fh, $filename, $wpro ? O_RDONLY : O_RDWR) - or die "Unexpected sysopen error"; - - $ucb->{att_ok} = 1; - $ucb->{att_file} = $filename; - $ucb->{att_nbyt} = $filesize; - $ucb->{att_wpro} = $wpro; - $ucb->{att_fh} = $fh; - - $ucb->{att_nblk} = int ($ucb->{att_nbyt}/512); - if ($ucb->{att_nbyt}%512 != 0) { - print "pi_rri($curmode)-I: size $filename not multiple of 512\n"; - } - &{$ctl->{usethdl}}($ucb); # setup unit registers - } - } -} - -#------------------------------------------------------------------------------- - -sub serv11_attdet_ronly { # generic in only att/det handler - my ($det,$ucb) = @_; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - - if ($det) { # detach handling - serv11_detach_gen($ucb); - - } else { # attach handling - my $filename = cget_file(); - return if $cmd_bad or cget_chkblank(); - - if (not -e $filename) { - print "pi_rri($curmode)-E: file $filename not found\n"; - return; - } - if (not -r $filename) { - print "pi_rri($curmode)-E: file $filename is not readable\n"; - return; - } - - my $fh = new FileHandle; - my $rc = $fh->open("<$filename"); - if (not $rc) { - print "pi_rri($curmode)-E: failed to open file $filename\n"; - return; - } - - $ucb->{att_ok} = 1; - $ucb->{att_file} = $filename; - $ucb->{att_fh} = $fh; - delete $ucb->{att_eof}; - - &{$ctl->{usethdl}}($ucb); # setup unit registers - } -} - -#------------------------------------------------------------------------------- - -sub serv11_attdet_wonly { # generic out only att/det handler - my ($det,$ucb) = @_; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - - if ($det) { # detach handling - serv11_detach_gen($ucb); - - } else { # attach handling - my $filename = cget_file(); - return if $cmd_bad or cget_chkblank(); - - if (not -e $filename) { - print STDERR "pi_rri($curmode)-I: file $filename will be created\n"; - } elsif (not -w $filename) { - print STDERR "pi_rri($curmode)-E: file $filename is not writeable\n"; - return; - } - - my $fh = new FileHandle; - my $rc = $fh->open(">$filename"); - if (not $rc) { - print STDERR "pi_rri($curmode)-E: failed to open file $filename\n"; - return; - } - - autoflush $fh; - - $ucb->{att_ok} = 1; - $ucb->{att_file} = $filename; - $ucb->{att_fh} = $fh; - delete $ucb->{att_eof}; - - &{$ctl->{usethdl}}($ucb); # setup unit registers - } -} - -#------------------------------------------------------------------------------- - -sub serv11_attdet_term { # generic term att/det handler - my ($det,$ucb) = @_; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - - if ($det) { # detach handling - my $port_str = $ucb->{att_port}; - my $teldsc = $telnettbl{$port_str}; - close $teldsc->{fh_data} if defined $teldsc->{fh_data}; - close $teldsc->{fh_port} if defined $teldsc->{fh_port}; - delete $telnettbl{$port_str}; - delete $ucb->{att_port}; - $ucb->{att_ok} = 0; - $serv11_fds_update = 1; # request update of select mask - - } else { # attach handling - my $port = cget_gdat(16, 10); - return if $cmd_bad or cget_chkblank(); - my $port_str = sprintf("%6.6d", $port); - if (exists $telnettbl{$port_str}) { - printf STDERR "pi_rri($curmode)-E: port %d already attached\n", $port; - return; - } - my $fh_port = new FileHandle; - my $proto = getprotobyname('tcp'); - if (not socket($fh_port, PF_INET, SOCK_STREAM, $proto)) { - printf STDERR "pi_rri($curmode)-E: error in socket(): $!\n"; - return; - } - if (not setsockopt($fh_port, SOL_SOCKET, SO_REUSEADDR, 1)) { - printf STDERR "pi_rri($curmode)-E: error in setsocketopt(): $!\n"; - return; - } - - my $host = pack('C4', 0,0,0,0); - my $addr = pack('S n a4 x8', 2, $port, $host); - if (not bind($fh_port, $addr)) { - printf STDERR "pi_rri($curmode)-E: error in bind(): $!\n"; - return; - } - - if (not listen($fh_port, 1)) { - printf STDERR "pi_rri($curmode)-E: error in listen(): $!\n"; - return; - } - - $telnettbl{$port_str} = {}; - $telnettbl{$port_str}->{port} = $port; - $telnettbl{$port_str}->{state} = TELNET_STATE_LISTEN; - $telnettbl{$port_str}->{fh_port} = $fh_port; - $telnettbl{$port_str}->{ucb} = $ucb; - - $ucb->{att_ok} = 1; - $ucb->{att_port} = $port_str; - - $serv11_fds_update = 1; # request update of select mask - - } - -} - -#------------------------------------------------------------------------------- - -sub serv11_probe_cpu { # cpu: probe handler - my ($ctl) = @_; - - serv11_probe_gen($ctl); - return unless $ctl->{probe_ok}; - - my $reglist = $ctl->{reglist}; - my $partbl = $ctl->{partbl}; - my $text = ""; - - my $exadep = \&serv11_exadep_cpu; - - push @{$reglist}, {name => "r0", hdl => \&serv11_exadep_cpu}; - push @{$reglist}, {name => "r1", hdl => \&serv11_exadep_cpu}; - push @{$reglist}, {name => "r2", hdl => \&serv11_exadep_cpu}; - push @{$reglist}, {name => "r3", hdl => \&serv11_exadep_cpu}; - push @{$reglist}, {name => "r4", hdl => \&serv11_exadep_cpu}; - push @{$reglist}, {name => "r5", hdl => \&serv11_exadep_cpu}; - push @{$reglist}, {name => "sp", hdl => \&serv11_exadep_cpu}; - push @{$reglist}, {name => "pc", hdl => \&serv11_exadep_cpu}; - push @{$reglist}, {name => "psw", hdl => \&serv11_exadep_cpu}; - - push @{$reglist}, {name => "stklim", addr => CPU_STKLIM}; - push @{$reglist}, {name => "pirq" , addr => CPU_PIRQ}; - push @{$reglist}, {name => "mbrk" , addr => CPU_MBRK}; - push @{$reglist}, {name => "cpuerr", addr => CPU_CPUERR}; - push @{$reglist}, {name => "hisize", addr => CPU_HISIZE}; - push @{$reglist}, {name => "losize", addr => CPU_LOSIZE}; - - my ($ival,$rval) = serv11_exec_probe(CPU_SDREG, "ir"); - if (defined $ival && defined $rval) { - push @{$reglist}, {name => "sr", addr => CPU_SDREG, attr => REGATTR_RBWR}; - push @{$reglist}, {name => "dr", addr => CPU_SDREG, attr => REGATTR_RBRD}; - } - - push @{$reglist}, {name => "mmr0" , addr => CPU_MMR0}; - push @{$reglist}, {name => "mmr1" , addr => CPU_MMR1}; - push @{$reglist}, {name => "mmr2" , addr => CPU_MMR2}; - push @{$reglist}, {name => "mmr3" , addr => CPU_MMR3}; - - my @rval; - serv11_rri_wreg("wal", PDPCP_ADDR_AL, CPU_LOSIZE); # i/o page in 16 bit mode - serv11_rri_rreg("rm", PDPCP_ADDR_MEM); - my $rc = serv11_rri_exec(\@rval); - my $memsize = ($rval[0]+1)<<6; # memsize in bytes - $ctl->{memsize} = $memsize; - - $text .= ($text)?";":"" . sprintf("mem=%dkb",$memsize/1024.); - - $ctl->{probe_text} = $text; - -} - -#------------------------------------------------------------------------------- - -sub serv11_attn_cpu { # cpu: attention handler - my ($ctl,$force) = @_; - return if $force; - print "CPU halted\n"; - $serv11_active = 0; - serv11_cexec_shoreg(1); -} - -#------------------------------------------------------------------------------- - -sub serv11_exadep_cpu { # cpu: exa/dep handler - my ($dep,$dsc,$val) = @_; - my $name = $dsc->{name}; - my $rrireg; - - $name =~ s/^sp$/r6/; - $name =~ s/^pc$/r7/; - - if ($dep) { - if ($name =~ /^r([0-7])$/) { - $rrireg = PDPCP_ADDR_R0 + int $1; - } elsif ($name eq "psw") { - $rrireg = PDPCP_ADDR_PSW; - } else { - print_fatal("serv11_exadep_cpu() called with bad name '$name'"); - } - my @rval; - serv11_rri_wreg("r$name", $rrireg, $val); - my $rc = serv11_rri_exec(\@rval); - return; - - } else { - if ($name =~ /^r([0-7])$/) { - $rrireg = PDPCP_ADDR_R0 + int $1; - } elsif ($name eq "psw") { - $rrireg = PDPCP_ADDR_PSW; - } else { - print_fatal("serv11_exadep_cpu() called with bad name '$name'"); - } - my @rval; - serv11_rri_rreg("r$name", $rrireg); - my $rc = serv11_rri_exec(\@rval); - return $rval[0]; - } - -} - -#------------------------------------------------------------------------------- - -sub serv11_ichr_dl11 { - my ($ucb,$dref) = @_; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - my @rval; - my $rc; - - my $que_old = scalar( @{$ucb->{rcvque}} ); - push @{$ucb->{rcvque}}, @$dref; - my $que_new = scalar( @{$ucb->{rcvque}} ); - - if ($que_old == 0 && $que_new > 0) { - serv11_rri_ibrb($ctl); - serv11_rri_ribr("RCSR", $ctl, DL11_RCSR); - $rc = serv11_rri_exec(\@rval); - if (($rval[0] & DL11_RCSR_M_RDONE) == 0) { # RBUF not full - my $data = shift @{$ucb->{rcvque}}; - serv11_rri_wibr("RBUF", $ctl, DL11_RBUF, $data & 0377); - $rc = serv11_rri_exec(\@rval); - } - } -} - -#------------------------------------------------------------------------------- - -sub serv11_attn_dl11 { - my ($ctl,$force) = @_; - my $ucb = $serv11_unittbl{$ctl->{units}[0]}; - my @rval; - my $rc; - my $nxbuf = $ctl->{nxbuf_min}; - my $nxbuf_val = 0; - - $nxbuf = $ctl->{nxbuf} if defined $ctl->{nxbuf}; - - serv11_rri_ibrb($ctl); - for (my $i=0; $i<$nxbuf; $i++) { - serv11_rri_ribr("XBUF", $ctl, DL11_XBUF); - } - - # select(undef, undef, undef, 5.0); # ! hack - # printf $fh_log "HACK -- wait on DL11 attn\n"; # ! hack - - $rc = serv11_rri_exec(\@rval); - - my $rrdy; - for (my $i=0; $i<$nxbuf; $i++) { - my $ochr = $rval[$i] & DL11_XBUF_M_XBUF; - my $xval = $rval[$i] & DL11_XBUF_M_XVAL; - $rrdy = $rval[$i] & DL11_XBUF_M_RRDY; - $ochr = $ochr & 0177 if $ucb->{rcv7bit}; # drop parity bit - my $chr = chr($ochr); - my $str = ($ochr>=040 && $ochr<0177) ? "$chr" : sprintf "\\%3.3o",$ochr; - if (exists $opts{tserv} && $ctl->{trace} && - ($xval || not $force)) { - printf $fh_log - "serv -- DL11.%s xbuf=%6.6o xval=%s rrdy=%s rcvq=%3d sndq=%3d", - $ctl->{ctlname}, $rval[$i], - ($xval ? "y" : "n"), ($rrdy ? "y" : "n"), - scalar( @{$ucb->{rcvque}} ), scalar( @{$ucb->{sndque}} ); - printf $fh_log " char=\"%s\"", $str if $xval; - print $fh_log "\n"; - } - - if ($xval) { - $nxbuf_val += 1; - my $sndqueref = $ucb->{sndque}; - my $ochr_last = 0; - $ochr_last = $$sndqueref[-1] if scalar(@$sndqueref) > 0; - - push @{$ucb->{sndque}}, $ochr; - - if ($ucb->{att_ok}) { - telnet_writehdl($ucb); - } else { - if ($ctl->{ctlname} eq "TTA") { # for console - while (scalar( @{$ucb->{sndque}} )) { - my $byte = shift @{$ucb->{sndque}}; - my $str = ""; - if ($byte>=040 && $byte<0177) { - $str = chr($byte); - } elsif ($byte==011) { - $str = "\t"; - } elsif ($byte==012) { - $str = "\n"; - } elsif ($byte==015) { - $str = "\r"; - } else { - $str = sprintf "<%3.3o>", $byte if $byte!=000; - } - print $str; - } - } - - if ($ucb->{logfile}) { - my $fh = $ucb->{logfh}; - if (not defined $ucb->{logfh}) { - my $logfile = $ucb->{logfile}; - my $rc; - $fh = $ucb->{logfh} = new FileHandle; - $rc = $ucb->{logfh}->open(">$logfile"); - if (not $rc) { - printf STDERR "pi_rri-E: failed to open $logfile for write\n"; - $fh = undef; - } else { - autoflush $fh; - } - } - print $fh $str if $fh; - } - } - -# if ($ochr_last == 015 && $ochr == 012) { -# while (scalar( @{$ucb->{sndque}} )) { -# my $byte = shift @{$ucb->{sndque}}; -# my $chr = chr($byte); -# if ($byte>=040 && $byte <=177) { -# print $chr -# } else { -# if ($byte != 000 && $byte != 012 && $byte != 015) { -# printf "<%3.3o>", $byte -# } -# } -# } -# print "\n"; -# } - } - } - - if ($rrdy && scalar( @{$ucb->{rcvque}} ) ) { - my $data = shift @{$ucb->{rcvque}}; - serv11_rri_wibr("RBUF", $ctl, DL11_RBUF, $data & 0377); - $rc = serv11_rri_exec(\@rval); - } - - $ctl->{nxbuf} = next_nxbuf($ctl, $nxbuf, $nxbuf_val); -} - -#------------------------------------------------------------------------------- - -sub serv11_uset_lp11 { - my ($ucb) = @_; - my @rval; - - my $lpcs = ($ucb->{att_ok}) ? 0 : LP11_CSR_M_ERR; - - serv11_rri_uset($ucb, "LPCS", LP11_CSR, $lpcs); - - my $rc = serv11_rri_exec(\@rval); -} - -#------------------------------------------------------------------------------- - -sub serv11_attn_lp11 { - my ($ctl,$force) = @_; - my $ucb = $serv11_unittbl{$ctl->{units}[0]}; - my @rval; - my $rc; - my $nxbuf = $ctl->{nxbuf_min}; - my $nxbuf_val = 0; - - $nxbuf = $ctl->{nxbuf} if defined $ctl->{nxbuf}; - - serv11_rri_ibrb($ctl); - for (my $i=0; $i<$nxbuf; $i++) { - serv11_rri_ribr("LPBU", $ctl, LP11_BUF); - } - - $rc = serv11_rri_exec(\@rval); - - for (my $i=0; $i<$nxbuf; $i++) { - my $ochr = $rval[$i] & LP11_BUF_M_BUF; - my $oval = $rval[$i] & LP11_BUF_M_VAL; - my $chr = chr($ochr); - my $str = "$chr"; - if (exists $opts{tserv} && $ctl->{trace} && - ($oval || not $force)) { - printf $fh_log - "serv -- LP11 buf=%6.6o val=%s ", - $rval[$i], ($oval ? "y" : "n"); - printf $fh_log " char=\"%s\"", $str if $oval; - print $fh_log "\n"; - } - - if ($oval) { - $nxbuf_val += 1; - my $fh = $ucb->{att_fh}; - if ($fh) { - print $fh $str; - } else { - printf STDERR "pi_rri($curmode)-E: spurious output '%s' for %s\n", - $str, $ucb->{unitname}; - } - } - } - - $ctl->{nxbuf} = next_nxbuf($ctl, $nxbuf, $nxbuf_val); -} - -#------------------------------------------------------------------------------- - -sub serv11_uset_pc11 { - my ($ucb) = @_; - my @rval; - my $text; - my $addr; - my $data; - - if ($ucb->{unitname} eq "PTR") { # if reader - $text = "PRCS"; - $addr = PC11_RCSR; - $data = ($ucb->{att_ok}) ? 0 : PC11_RCSR_M_ERR; - } else { # if puncher - $text = "PPCS"; - $addr = PC11_PCSR; - $data = ($ucb->{att_ok}) ? 0 : PC11_PCSR_M_ERR; - } - - serv11_rri_uset($ucb, $text, $addr, $data); - - my $rc = serv11_rri_exec(\@rval); -} - -#------------------------------------------------------------------------------- - -sub serv11_attdet_pc11 { # pc11 att/det handler - my ($det,$ucb) = @_; - - if ($ucb->{unitname} eq "PTR") { # if reader - serv11_attdet_ronly($det, $ucb); # use read-only file - } else { # if puncher - serv11_attdet_wonly($det, $ucb); # use write-only file - } - -} - -#------------------------------------------------------------------------------- - -sub serv11_attn_pc11 { - my ($ctl,$force) = @_; - - my $ucb_ptr = $serv11_unittbl{$ctl->{units}[0]}; - my $ucb_ptp = $serv11_unittbl{$ctl->{units}[1]}; - my @rval; - my $rc; - my $nxbuf = $ctl->{nxbuf_min}; - my $nxbuf_val = 0; - - $nxbuf = $ctl->{nxbuf} if defined $ctl->{nxbuf}; - - serv11_rri_ibrb($ctl); - for (my $i=0; $i<$nxbuf; $i++) { - serv11_rri_ribr("PPBUF", $ctl, PC11_PBUF); - } - - $rc = serv11_rri_exec(\@rval); - - my $rrdy; - for (my $i=0; $i<$nxbuf; $i++) { - my $ochr = $rval[$i] & PC11_PBUF_M_PBUF; - my $pval = $rval[$i] & PC11_PBUF_M_PVAL; - $rrdy = $rval[$i] & PC11_PBUF_M_RBUSY; - - if (exists $opts{tserv} && $ctl->{trace} && - ($pval || not $force)) { - printf $fh_log - "serv -- PC11 pbuf=%6.6o pval=%s rrdy=%s \n", - $rval[$i], ($pval ? "y" : "n"), ($rrdy ? "y" : "n"); - } - - if ($pval) { - $nxbuf_val += 1; - my $fh = $ucb_ptp->{att_fh}; - if ($fh) { - print $fh chr($ochr); - } else { - printf STDERR "pi_rri($curmode)-E: spurious output '%3.3o' for %s\n", - $ochr, $ucb_ptp->{unitname}; - } - } - } - - if ($rrdy) { - my $fh = $ucb_ptr->{att_fh}; - if ($fh && (not $ucb_ptr->{att_eof}) ) { - my $char = getc($fh); - if (defined $char) { - serv11_rri_wibr("PRBUF", $ctl, PC11_RBUF, ord($char) & 0377); - $rc = serv11_rri_exec(\@rval); - } else { - serv11_rri_uset($ucb_ptr, "PRCS", PC11_RCSR, PC11_RCSR_M_ERR); - $rc = serv11_rri_exec(\@rval); - $ucb_ptr->{att_eof} = 1; - } - } else { - printf STDERR "pi_rri($curmode)-E: spurious reader busy for %s\n", - $ucb_ptr->{unitname}; - } - } - - $ctl->{nxbuf} = next_nxbuf($ctl, $nxbuf, $nxbuf_val); - -} - -#------------------------------------------------------------------------------- - -sub serv11_uset_rk11 { - my ($ucb) = @_; - my @rval; - - my $rkds = 0; - - $rkds = $ucb->{ctlunit}<<(RKDS_V_ID); - if ($ucb->{att_ok}) { # drive available - $rkds |= RKDS_M_HDEN; # always high density - $rkds |= RKDS_M_SOK; # always sector counter OK ?FIXME? - $rkds |= RKDS_M_DRY; # drive available - $rkds |= RKDS_M_ADRY; # access available - $rkds |= RKDS_M_WPS if $ucb->{att_wpro}; # in case write protected - } - $ucb->{rkds} = $rkds; - - serv11_rri_uset($ucb, "RKDS", RK11_RKDS, $rkds); - my $rc = serv11_rri_exec(\@rval); -} - -#------------------------------------------------------------------------------- -# geometry: c=203;h=2;s=12 ==> 4872 blocks ==> 2 494 464 bytes -# -# several error conditions are only approximately handled: -# OVR: when detected, no transfer done (should trim size) - -sub serv11_attn_rk11 { - my ($ctl,$force) = @_; - my @rval; - my $blksize = $ctl->{blksize}; - - serv11_rri_ibrb($ctl); - serv11_rri_ribr("RKWC", $ctl, RK11_RKWC); - serv11_rri_ribr("RKBA", $ctl, RK11_RKBA); - serv11_rri_ribr("RKDA", $ctl, RK11_RKDA); - serv11_rri_ribr("RKMR", $ctl, RK11_RKMR); # read to monitor CRDONE - serv11_rri_ribr("RKCS", $ctl, RK11_RKCS); - - my $rc = serv11_rri_exec(\@rval); - - my $rkwc = $rval[0]; - my $rkba = $rval[1]; - my $rkda = $rval[2]; - my $rkmr = $rval[3]; - my $rkcs = $rval[4]; - - my $se = $rkda & RKDA_B_SC; - my $hd = ($rkda>>RKDA_V_SUR ) & RKDA_B_SUR; - my $cy = ($rkda>>RKDA_V_CYL ) & RKDA_B_CYL; - my $dr = ($rkda>>RKDA_V_DRSEL) & RKDA_B_DRSEL; - - my $go = ($rkcs & RKCS_M_GO) != 0; - my $fu = ($rkcs>>RKCS_V_FUNC) & RKCS_B_FUNC; - my $mex = ($rkcs>>RKCS_V_MEX ) & RKCS_B_MEX; - - my $nwrd = ((~$rkwc) & 0xffff) + 1; # transfer size in words - my $nbyt = 2*$nwrd; # transfer size in bytes - my $nblk = int (($nbyt+$blksize-1)/$blksize);# transfer size in blocks - - my $addr = $mex<<16 | $rkba; # 18 bit memory address - my $lbn = $se + RK11_NUMSE*$hd + RK11_NUMSE*RK11_NUMHD*$cy; - - my $ucb = $serv11_unittbl{$ctl->{units}[$dr]}; - - my $rkds = $ucb->{rkds}; - if (not defined $rkds) { - printf $fh_log - "serv -- RK11 ERROR: no rri device init, assume ds=0 for drive %d\n", $dr; - $rkds = $ucb->{rkds} = $rkds = 0; - } - - if ($go == 0) { # quit here if no go bit set - if (exists $opts{tserv} && $ctl->{trace}) { - if (not $force) { - printf $fh_log "serv -- RK11 cs=%6.6o go=0, spurious attn\n", $rkcs; - } - } - return; - } - - my $rker = 0; - my $msg = ""; - - if ($fu != RKCS_CRESET && # function not control reset - (not $ucb->{att_ok})) { # and drive not attached - $rker = RKER_M_NXD; # --> abort with NXD error - serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); - if ($fu == RKCS_SEEK || $fu == RKCS_DRESET) { - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_SBCLR) | 1<<($dr)); - } - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_attn_rk11_logerr($ctl, $rker); - - } elsif ($fu != RKCS_WRITE && # function neither read - $fu != RKCS_READ && # nor write - ($rkcs & RKCS_M_FMT)) { # and FMT set - $rker = RKER_M_PGE; # --> abort with PGE error - serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); - if ($fu == RKCS_SEEK || $fu == RKCS_DRESET) { - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_SBCLR) | 1<<($dr)); - } - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_attn_rk11_logerr($ctl, $rker); - - } else { - - if ($fu == RKCS_CRESET) { # Control reset ------------------- - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_CRESET)); - - } elsif ($fu == RKCS_WRITE) { # Write --------------------------- - # Note: WRITE+FMT is just like WRITE - $rker |= RKER_M_NXS if $se >= RK11_NUMSE; - $rker |= RKER_M_NXC if $cy >= RK11_NUMCY; - $rker |= RKER_M_WLO if $ucb->{att_wpro}; - $rker |= RKER_M_DRE if $rkcs & RKCS_M_IBA; # not yet supported ! FIXME ! - $rker |= RKER_M_DRE if $rkcs & RKCS_M_RWA; # will never be supported - if ($rker) { - serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_attn_rk11_logerr($ctl, $rker); - } else { - my $icb = {rdmahdl => \&serv11_rdma_rk11, - func => "write", - ctl => $ctl, - ucb => $ucb, - lbn => $lbn, - nblk => $nblk, - nwrd => $nwrd, - addr => $addr, - nwdone => 0, - rkcs => $rkcs, # later needed for MEX update - rkda => $rkda # later needed in RKDA update - }; - push @serv11_icbque, $icb; - } - - } elsif ($fu == RKCS_READ) { # Read ---------------------------- - $rker |= RKER_M_NXS if ($se >= RK11_NUMSE); - $rker |= RKER_M_NXC if ($cy >= RK11_NUMCY); - $rker |= RKER_M_DRE if $rkcs & RKCS_M_IBA; # not yet supported ! FIXME ! - $rker |= RKER_M_DRE if $rkcs & RKCS_M_RWA; # will never be supported - if ($rker) { - serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_attn_rk11_logerr($ctl, $rker); - } else { - - if ($rkcs & RKCS_M_FMT) { - my $icb = {rdmahdl => \&serv11_rdma_rk11, - func => "rdfmt", - ctl => $ctl, - ucb => $ucb, - lbn => $lbn, - nblk => $nwrd, # #blocks == #words for RD FMT !! - nwrd => $nwrd, - addr => $addr, - nwdone => 0, - rkcs => $rkcs, # later needed for MEX update - rkda => $rkda # later needed in RKDA update - }; - push @serv11_icbque, $icb; - } else { - my $icb = {rdmahdl => \&serv11_rdma_rk11, - func => "read", - ctl => $ctl, - ucb => $ucb, - lbn => $lbn, - nblk => $nblk, - nwrd => $nwrd, - addr => $addr, - nwdone => 0, - rkcs => $rkcs, # later needed for MEX update - rkda => $rkda # later needed in RKDA update - }; - push @serv11_icbque, $icb; - } - } - - } elsif ($fu == RKCS_WCHK) { # Write Check --------------------- - $rker |= RKER_M_NXS if $se >= RK11_NUMSE; - $rker |= RKER_M_NXC if $cy >= RK11_NUMCY; - $rker |= RKER_M_DRE if $rkcs & RKCS_M_IBA; # not yet supported ! FIXME ! - $rker |= RKER_M_DRE if $rkcs & RKCS_M_RWA; # will never be supported - if ($rker) { - serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_attn_rk11_logerr($ctl, $rker); - } else { - my $icb = {rdmahdl => \&serv11_rdma_rk11, - func => "wrcheck", - ctl => $ctl, - ucb => $ucb, - lbn => $lbn, - nblk => $nblk, - nwrd => $nwrd, - addr => $addr, - nwdone => 0, - rkcs => $rkcs, # later needed for MEX update - rkda => $rkda # later needed in RKDA update - }; - push @serv11_icbque, $icb; - } - - } elsif ($fu == RKCS_SEEK) { # Seek ---------------------------- - $rker |= RKER_M_NXS if ($se >= RK11_NUMSE); - $rker |= RKER_M_NXC if ($cy >= RK11_NUMCY); - if ($rker) { - serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_SBCLR) | 1<<($dr)); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_attn_rk11_logerr($ctl, $rker); - } else { - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - $rkds &= ~(RKDS_B_SC); # replace current sector number - $rkds |= $se; - $ucb->{rkds} = $rkds; - serv11_rri_wibr("RKDS", $ctl, RK11_RKDS, $rkds); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<($dr)); # issue seek done - } - - } elsif ($fu == RKCS_RCHK) { # Read Check ---------------------- - $rker |= RKER_M_NXS if $se >= RK11_NUMSE; - $rker |= RKER_M_NXC if $cy >= RK11_NUMCY; - $rker |= RKER_M_DRE if $rkcs & RKCS_M_IBA; # not yet supported ! FIXME ! - $rker |= RKER_M_DRE if $rkcs & RKCS_M_RWA; # will never be supported - if ($rker) { - serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_attn_rk11_logerr($ctl, $rker); - } else { - my $icb = {rdmahdl => \&serv11_rdma_rk11, - func => "rdcheck", - ctl => $ctl, - ucb => $ucb, - lbn => $lbn, - nblk => $nblk, - nwrd => $nwrd, - addr => $addr, - nwdone => 0, - rkcs => $rkcs, # later needed for MEX update - rkda => $rkda # later needed in RKDA update - }; - push @serv11_icbque, $icb; - } - - } elsif ($fu == RKCS_DRESET) { # Drive Reset --------------------- - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<($dr)); # issue seek done - - } elsif ($fu == RKCS_WLOCK) { # Write Lock ---------------------- - $ucb->{rkds} |= RKDS_M_WPS; # set RKDS write protect flag - $ucb->{att_wpro} = 1; # set UCB write protect flag - serv11_rri_wibr("RKDS", $ctl, RK11_RKDS, $ucb->{rkds}); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - } - - } - - if (exists $opts{tserv} && $ctl->{trace}) { - printf $fh_log "serv -- RK11 cs=%6.6o da=%6.6o wc=%6.6o", - $rkcs, $rkda, $rkwc; - printf $fh_log " ad=%6.6o", $addr; - printf $fh_log " fu=%d dchs=%d,%3d,%d,%2d", $fu, $dr, $cy, $hd, $se; - printf $fh_log " lbn=%4d nw,nb=%5d,%2d", $lbn, $nwrd, $nblk; - print $fh_log "\n"; - } - - $rc = serv11_rri_exec(\@rval); - -} - -#------------------------------------------------------------------------------- - -sub serv11_attn_rk11_logerr { - my ($ctl,$rker) = @_; - if (exists $opts{tserv}) { - printf $fh_log "serv -- RK11 er=%6.6o ERROR ABORT\n", $rker; - } -} - -#------------------------------------------------------------------------------- - -sub serv11_rdma_rk11 { - my ($icb) = @_; - my $ctl = $icb->{ctl}; - my $ucb = $icb->{ucb}; - my $addr = $icb->{addr}; - my $blksize = $ctl->{blksize}; - my @rval; - my $rc = 1; # default ok, make code below shorter FIXME - my $rker = 0; - -# printf "+++x1 func=%5s addr=%6.6o nblk=%2d nwdone=%3d\n", -# $icb->{func}, $addr, $icb->{nblk}, $icb->{nwdone}; - - if ($icb->{func} eq "read") { # --- read function -------------- - if ($icb->{nwdone} == 0) { # new block ? - $rker |= RKER_M_OVR if $icb->{lbn} >= RK11_NUMBL; - $rc = serv11_icb_disk_read($icb) if not $rker; - $rker |= RKER_M_CSE if not $rc; # forward disk I/O error - } - - if (not $rker) { - my $nwdma = int($blksize/2) - $icb->{nwdone}; - $nwdma = $icb->{nwrd} if $nwdma > $icb->{nwrd}; - $nwdma = $serv11_rdma_chunk if $nwdma > $serv11_rdma_chunk; - my $beg = $icb->{nwdone}; - my $end = $beg + $nwdma - 1; - my $buf = $icb->{buf}; - - serv11_rri_lalh($icb->{addr}, 3); - serv11_rri_wblk($nwdma, [ @$buf[$beg..$end] ]); - $rc = serv11_rri_exec(\@rval); # FIXME: handle dma I/O error - $stat_tab{rdisk} += 2*$nwdma; - - $icb->{nwdone} += $nwdma; - $icb->{nwrd} -= $nwdma; - $icb->{addr} += 2*$nwdma; - - if ((not $rker) && # no error and - ($icb->{nwdone} == int($blksize/2) || # block done or - $icb->{nwrd} == 0) ) { # all done - $icb->{nwdone} = 0; - $icb->{lbn} += 1; - $icb->{nblk} -= 1; - } - } - - if ((not $rker) && $icb->{nwrd}) { # if no error found and not done yet - push @serv11_icbque, $icb; # requeue - return; - } - - } elsif ($icb->{func} eq "rdfmt") { # --- read format function ------- - $rker |= RKER_M_OVR if $icb->{lbn} >= RK11_NUMBL; - - if (not $rker) { - my $cy = $icb->{lbn}/(RK11_NUMHD*RK11_NUMSE); - my $da = $cy<<(RKDA_V_CYL); - my @buf = ($da); - - serv11_rri_lalh($icb->{addr}, 3); - serv11_rri_wblk(1, [ @buf ]); - $rc = serv11_rri_exec(\@rval); # FIXME: handle dma I/O error - $stat_tab{rdisk} += 2; - - $icb->{nwrd} -= 1; - $icb->{addr} += 2; - $icb->{lbn} += 1; - $icb->{nblk} -= 1; - } - - if ((not $rker) && $icb->{nwrd}) { # if no error found and not done yet - push @serv11_icbque, $icb; # requeue - return; - } - - } elsif ($icb->{func} eq "write") { # --- write function ------------- - $icb->{buf} = [] if $icb->{nwdone} == 0; - my $nwdma = int($blksize/2) - $icb->{nwdone}; - $nwdma = $icb->{nwrd} if $nwdma > $icb->{nwrd}; - $nwdma = $serv11_rdma_chunk if $nwdma > $serv11_rdma_chunk; - - serv11_rri_lalh($icb->{addr}, 3); - serv11_rri_rblk($nwdma); - $rc = serv11_rri_exec(\@rval); # FIXME: handle dma I/O error - $stat_tab{wdisk} += 2*$nwdma; - - $icb->{nwdone} += $nwdma; - $icb->{nwrd} -= $nwdma; - $icb->{addr} += 2*$nwdma; - - push @{$icb->{buf}}, @{$rval[0]}; - - if ((not $rker) && # no error and - ($icb->{nwdone} == int($blksize/2) || # block done or - $icb->{nwrd} == 0) ) { # all done - $rc = serv11_icb_disk_write($icb); # FIXME: handle file I/O error - $icb->{nwdone} = 0; - $icb->{lbn} += 1; - $icb->{nblk} -= 1; - $rker |= RKER_M_OVR if $icb->{nblk} && $icb->{lbn} >= RK11_NUMBL; - } - - if ((not $rker) && $icb->{nwrd}) { # if no error found and not done yet - push @serv11_icbque, $icb; # requeue - return; - } - - } elsif ($icb->{func} eq "wrcheck") { # --- write check function ------- - if ($icb->{nwdone} == 0) { # new block ? - $rker |= RKER_M_OVR if $icb->{lbn} >= RK11_NUMBL; - $rc = serv11_icb_disk_read($icb) if not $rker; - $rker |= RKER_M_CSE if not $rc; # forward disk I/O error - if ((not $rker)) { - $icb->{bufdsk} = $icb->{buf}; - $icb->{buf} = []; - } - } - - my $nwdma = int($blksize/2) - $icb->{nwdone}; - $nwdma = $icb->{nwrd} if $nwdma > $icb->{nwrd}; - $nwdma = $serv11_rdma_chunk if $nwdma > $serv11_rdma_chunk; - - serv11_rri_lalh($icb->{addr}, 3); - serv11_rri_rblk($nwdma); - $rc = serv11_rri_exec(\@rval); # FIXME: handle dma I/O error - $stat_tab{wdisk} += 2*$nwdma; - - $icb->{nwdone} += $nwdma; - $icb->{nwrd} -= $nwdma; - $icb->{addr} += 2*$nwdma; - - push @{$icb->{buf}}, @{$rval[0]}; - - if ((not $rker) && # no error and - ($icb->{nwdone} == int($blksize/2) || # block done or - $icb->{nwrd} == 0)) { # all done - my $bufdsk = $icb->{bufdsk}; - my $bufmem = $icb->{buf}; - my $nwmem = scalar(@{$bufmem}); - for (my $i=0; $i<$nwmem; $i++) { - $rker |= RKER_M_WCE if $bufdsk->[$i] != $bufmem->[$i]; - } - $icb->{nwdone} = 0; - $icb->{lbn} += 1; - $icb->{nblk} -= 1; - $rker |= RKER_M_OVR if $icb->{nblk} && $icb->{lbn} >= RK11_NUMBL; - } - - my $stop = ($rker & ~RKER_M_WCE) != 0 || # any hard error - (($rker & RKER_M_WCE) && $icb->{rkcs} & RKCS_M_SSE); - if ((not $stop) && $icb->{nwrd}) { # if no error found and not done yet - push @serv11_icbque, $icb; # requeue - return; - } - - } elsif ($icb->{func} eq "rdcheck") { # --- read check function -------- - $rker |= RKER_M_OVR if $icb->{lbn} >= RK11_NUMBL; - - if (not $rker) { - my $nwdma = int($blksize/2); - $nwdma = $icb->{nwrd} if $nwdma > $icb->{nwrd}; - - # Note: rkwc is decremented; rkba is untouched, no DMA transfer done - $icb->{nwrd} -= $nwdma; - $icb->{lbn} += 1; - $icb->{nblk} -= 1; - } - - if ((not $rker) && $icb->{nwrd}) { # if no error found and not done yet - push @serv11_icbque, $icb; # requeue - return; - } - - - } else { # --- unkown function ------------ - printf "pi_rri-E: unknown func=%s for serv11_rdma_rk11\n", $icb->{func}; - } - -# common handling for dma transfer completion - - my $ba = $icb->{addr} &0177776; # get lower 16 bits - my $mex = ($icb->{addr} >> 16) & 03; # get upper 2 bits - my $lbn = $icb->{lbn}; - my $nwrd = $icb->{nwrd}; - my $end = $lbn; - my $se = $end % RK11_NUMSE; - $end = int ($end / RK11_NUMSE); - my $hd = $end % RK11_NUMHD; - $end = int ($end / RK11_NUMHD); - my $cy = $end; - my $da = ($icb->{rkda} & RKDA_M_DRSEL) | - $se | $hd<<(RKDA_V_SUR) | $cy<<(RKDA_V_CYL); - my $cs = ($icb->{rkcs} & (~RKCS_M_MEX)) | ($mex << RKCS_V_MEX); - - serv11_rri_ibrb($ctl); - serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker) if $rker; - serv11_rri_wibr("RKWC", $ctl, RK11_RKWC, (-$nwrd)&0177777); - serv11_rri_wibr("RKBA", $ctl, RK11_RKBA, $ba); - serv11_rri_wibr("RKDA", $ctl, RK11_RKDA, $da); - serv11_rri_wibr("RKCS", $ctl, RK11_RKCS, $cs) if ($cs != $icb->{rkcs}); - serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); - serv11_attn_rk11_logerr($ctl, $rker) if $rker; - $rc = serv11_rri_exec(\@rval); -} - -#------------------------------------------------------------------------------- -# read one disk block at lbn, returns $icb->{buf} - -sub serv11_icb_disk_read { # read one dsk file block - my ($icb) = @_; - my $ucb = $icb->{ucb}; - my $ctl = $icb->{ctl}; - my $fh = $ucb->{att_fh}; - my $fsize = $ucb->{att_nbyt}; - my $lbn = $icb->{lbn}; - my $blksize = $ctl->{blksize}; - my $seekpos = $lbn*$blksize; - my $sysbuf; - my $msg = ""; - my $rc = 0; - - $icb->{buf} = undef; - - if ($seekpos < $fsize) { - ($rc,$sysbuf) = file_seek_read($fh, $seekpos, $blksize); - $icb->{buf} = conv_buf2wlist($sysbuf); - } else { - $rc = $blksize; # setup good rc - $msg = " past eof zero buf"; - $icb->{buf} = []; - while ($blksize > 0) { - push @{$icb->{buf}}, 0; - $blksize -= 2; - } - } - - if (exists $opts{tserv} && $ctl->{trace}) { - printf $fh_log "disk -- %3s read lbn=%5d rc=%d%s\n", - $ucb->{unitname}, $lbn, $rc, $msg; - } - - return $rc; -} - -#------------------------------------------------------------------------------- -# write one disk block at lbn, takes data from $icb->{buf} - -sub serv11_icb_disk_write { # write one dsk file block - my ($icb) = @_; - my $ucb = $icb->{ucb}; - my $ctl = $icb->{ctl}; - my $fh = $ucb->{att_fh}; - my $fsize = $ucb->{att_nbyt}; - my $lbn = $icb->{lbn}; - my $blksize = $ctl->{blksize}; - my $seekpos = $lbn*$blksize; - my $sysbuf = ""; - my $rc; - - if (scalar(@{$icb->{buf}}) > int($blksize/2)) { - print_fatal "serv11_icb_disk_write: buf too long"; - } - - while (scalar(@{$icb->{buf}}) < int($blksize/2)) { # zero pad to block size - push @{$icb->{buf}}, 0; - } - - if ($fsize <= $seekpos) { # extend dsk file ? - my $zerobuf = chr(0) x $blksize; - my $cnt = 0; - file_seek($fh, $fsize); - while ($fsize <= $seekpos) { - file_write($fh, $zerobuf); - $fsize += $blksize; - $cnt += 1; - } - if (exists $opts{tserv} && $ctl->{trace}) { - printf $fh_log "disk -- %3s extended by %d blocks\n", - $ucb->{unitname}, $cnt; - } - $ucb->{att_nbyt} = $fsize; - } - - $sysbuf = conv_wlist2buf($icb->{buf}); - $rc = file_seek_write($fh, $seekpos, $sysbuf); - - if (exists $opts{tserv} && $ctl->{trace}) { - printf $fh_log "disk -- %3s write lbn=%5d rc=%d\n", - $ucb->{unitname}, $lbn, $rc; - } - - return $rc; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_init { # issue rri init command - my ($aname,$addr,$data) = @_; - push @rri_cmdlist, {cname => "init", - aname => $aname, - addr => $addr, - data => $data, - ref_stat => $rri_ref_sdef, - msk_stat => $rri_msk_sdef}; - return undef; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_attn { # issue rri attn command - my ($aname) = @_; - push @rri_cmdlist, {cname => "attn", - aname => $aname, - ref_stat => $rri_ref_sdef, - msk_stat => $rri_msk_sdef}; - $rri_cmdlist[$#rri_cmdlist]->{get_data} = 1; - return $rri_rvalcnt++; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_stat { # issue rri stat command - my ($aname) = @_; - push @rri_cmdlist, {cname => "stat", - aname => $aname, - ref_stat => $rri_ref_sdef, - msk_stat => $rri_msk_sdef}; - $rri_cmdlist[$#rri_cmdlist]->{get_data} = 1; - return $rri_rvalcnt++; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_rreg { # issue rri rreg command - my ($aname,$addr) = @_; - push @rri_cmdlist, {cname => "rreg", - aname => $aname, - addr => $addr, - ref_stat => $rri_ref_sdef, - msk_stat => $rri_msk_sdef}; - $rri_cmdlist[$#rri_cmdlist]->{get_data} = 1; - return $rri_rvalcnt++; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_wreg { # issue rri wreg command - my ($aname,$addr,$data) = @_; - push @rri_cmdlist, {cname => "wreg", - aname => $aname, - addr => $addr, - data => $data, - ref_stat => $rri_ref_sdef, - msk_stat => $rri_msk_sdef}; - return undef; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_rblk { # issue rri rblk command - my ($nblk) = @_; - push @rri_cmdlist, {cname => "rblk", - aname => "brm", - addr => PDPCP_ADDR_MEMI, - nblk => $nblk, - ref_stat => $rri_ref_sdef, - msk_stat => $rri_msk_sdef}; - $rri_cmdlist[$#rri_cmdlist]->{get_rblk} = 1; - return $rri_rvalcnt++; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_wblk { # issue rri wblk command - my ($nblk,$dref) = @_; - push @rri_cmdlist, {cname => "wblk", - aname => "bwm", - addr => PDPCP_ADDR_MEMI, - nblk => $nblk, - dat_wblk => $dref, - ref_stat => $rri_ref_sdef, - msk_stat => $rri_msk_sdef}; - return undef; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_lalh { # issue pdpcp lal and lah commands - my ($addr,$mode) = @_; - - serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr&0xffff); # lower 16 bits - if ($mode>=1 and $mode<=3) { - my $data = ($addr>>16)&0x3f | $mode<<6; - serv11_rri_wreg("wah", PDPCP_ADDR_AH, $data); # upper 6 bits - } - if ($mode<0 or $mode>3) { - print STDERR "pi_rri($curmode)-E: bad mode $mode in serv11_exec_rblk()\n"; - } -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_ibrb { # issue rbus set base address - my ($ctl) = @_; - serv11_rri_wreg("wibrb", PDPCP_ADDR_IBRB, $ctl->{ibrb}); - return undef; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_ribr { # issue rbus read - my ($aname,$ctl,$off) = @_; - my $ibroff = $ctl->{base} + $off - $ctl->{ibrb}; - return serv11_rri_rreg($aname, PDPCP_ADDR_IBR+int($ibroff/2)); -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_wibr { # issue rbus write - my ($aname,$ctl,$off,$data) = @_; - my $ibroff = $ctl->{base} + $off - $ctl->{ibrb}; - return serv11_rri_wreg($aname, PDPCP_ADDR_IBR+int($ibroff/2), $data); -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_clear { - @rri_cmdlist = (); - $rri_rvalcnt = 0; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_exec { - my ($dref) = @_; - my $rc = 0; - - return $rc if scalar(@rri_cmdlist) == 0; - - rri_cmdlist_exec(\@rri_cmdlist); - $rc = rri_cmdlist_check_stat(\@rri_cmdlist); - - if ($rc) { - print "pi_rri($curmode)-E: serv11_rri_exec error - dump follows\n"; - if (exists $opts{log} && $opts{log} ne "") { - print $fh_log "pi_rri($curmode)-E: serv11_rri_exec error - dump follows\n"; - } - } - if ($rc || exists $opts{dserv}) { - rri_cmdlist_dump(\@rri_cmdlist, 0, $fh_log); - } - - @{$dref} = (); - foreach my $ele (@rri_cmdlist) { - push @{$dref}, $ele->{rcv_data} if $ele->{get_data}; - push @{$dref}, $ele->{rcv_rblk} if $ele->{get_rblk}; - } - - @rri_cmdlist = (); - $rri_rvalcnt = 0; - - return $rc; -} - -#------------------------------------------------------------------------------- - -sub serv11_rri_uset { # issue rbus uset writes - my $ucb = shift @_; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - my $first = 1; - - while (scalar(@_)) { - my $text = shift @_; - my $addr = shift @_; - my $data = shift @_; - my $key = "uset_" . $text; - - if ((not defined $ctl->{$key}) || $ctl->{$key} != $data) { - - serv11_rri_ibrb($ctl) if $first; - $first = 0; - - serv11_rri_wibr($text, $ctl, $addr, $data); - $ctl->{$key} = $data; - - if (exists $opts{tserv} && $ctl->{trace}) { - printf $fh_log "uset -- %s %s %6.6o\n", - $ctl->{ctltype}, $ucb->{unitname}, $data; - } - } - } - -} - -#------------------------------------------------------------------------------- - -sub serv11_exec_rblk { - my ($addr,$mode,$dref,$nword) = @_; - my @rval; - - serv11_rri_lalh($addr,$mode); - - while ($nword>0) { - my $nblk = $nword; - $nblk = 256 if $nblk > 256; - $nword -= $nblk; - - my $idref = serv11_rri_rblk($nblk); - - my $rc = serv11_rri_exec(\@rval); - return $rc if $rc; - - push @$dref, @{$rval[$idref]}; - } - - return 0; -} - -#------------------------------------------------------------------------------- - -sub serv11_exec_wblk { - my ($addr,$mode,$dref) = @_; - my @rval; - - serv11_rri_lalh($addr,$mode); - - my $nword = scalar(@$dref); - my $offset = 0; - - if ($nword == 0) { - print "pi_rri($curmode)-W: spurious serv11_exec_wblk() with 0 data length\n"; - return; - } - - while ($nword>0) { - my $nblk = $nword; - $nblk = 256 if $nblk > 256; - my $beg = $offset; - my $end = $offset+$nblk-1; - - serv11_rri_wblk($nblk, [ @$dref[$beg..$end] ]); - - $nword -= $nblk; - $offset += $nblk; - - my $rc = serv11_rri_exec(\@rval); - return $rc if $rc; - } - - return 0; -} - -#------------------------------------------------------------------------------- - -sub serv11_exec_probe { - my ($addr,$mode) = @_; - my $iib; - my $irb; - - if ($mode =~ /i/) { - serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); # i/o page in 16 bit mode - serv11_rri_rreg("rm", PDPCP_ADDR_MEM); - $iib = $#rri_cmdlist; - } - if ($mode =~ /r/) { - my $ibrbase = $addr & ~(077); # ibr-base => drop last 6 bits - my $ibroff = $addr & (077); # ibr-offset => take last 6 bits - - serv11_rri_wreg("wibrb", PDPCP_ADDR_IBRB, $ibrbase); - serv11_rri_rreg("ribr", PDPCP_ADDR_IBR + int($ibroff/2)); - $irb = $#rri_cmdlist; - } - - rri_cmdlist_exec(\@rri_cmdlist); - rri_cmdlist_dump(\@rri_cmdlist, 0) if exists $opts{dserv}; - - my $ival; - my $rval; - if (defined $iib) { - $ival =$rri_cmdlist[$iib]->{rcv_data} if not $rri_cmdlist[$iib]->{err_stat}; - } - if (defined $irb) { - $rval =$rri_cmdlist[$irb]->{rcv_data} if not $rri_cmdlist[$irb]->{err_stat}; - } - serv11_rri_clear(); - - return ($ival, $rval); -} - -#------------------------------------------------------------------------------- - -sub next_nxbuf { # calculate next nxbuf value - my ($ctl,$nxbuf,$nxbuf_val) = @_; - - if ($nxbuf_val <= $nxbuf/2) { - $nxbuf -= $ctl->{nxbuf_inc}; - } else { - $nxbuf += $ctl->{nxbuf_inc}; - } - $nxbuf = $ctl->{nxbuf_min} if $nxbuf < $ctl->{nxbuf_min}; - $nxbuf = $ctl->{nxbuf_max} if $nxbuf > $ctl->{nxbuf_max}; - - return $nxbuf; -} - -#------------------------------------------------------------------------------- - -sub telnet_readhdl { # telnet: socket read handler - my ($teldsc) = @_; - my $ucb = $teldsc->{ucb}; - - if ($teldsc->{state} == TELNET_STATE_LISTEN) { - my $fh_data = new FileHandle; - if (not accept($fh_data, $teldsc->{fh_port})) { - printf STDERR "pi_rri($curmode)-E: erro in accept(): $!\n"; - return; # FIXME: error handling ?? - } - printf "connect on port %s for %s\n", $teldsc->{port}, $ucb->{unitname}; - my $buf; - my $rc; - $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_WILL, TELNET_OPT_LINE); - $rc = syswrite($fh_data, $buf, length($buf)); - $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_WILL, TELNET_OPT_SGA); - $rc = syswrite($fh_data, $buf, length($buf)); - $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_WILL, TELNET_OPT_ECHO); - $rc = syswrite($fh_data, $buf, length($buf)); - $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_WILL, TELNET_OPT_BIN); - $rc = syswrite($fh_data, $buf, length($buf)); - $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_DO, TELNET_OPT_BIN); - $rc = syswrite($fh_data, $buf, length($buf)); - - $teldsc->{state} = TELNET_STATE_STREAM; - $teldsc->{fh_data} = $fh_data; - - $buf = sprintf("\r\nconnect on port %s for %s\r\n\r\n", - $teldsc->{port}, $ucb->{unitname}); - $rc = syswrite($fh_data, $buf, length($buf)); - - telnet_writehdl($ucb); - - $serv11_fds_update = 1; - - } else { - - my $buf; - my $rc; - $rc = sysread($teldsc->{fh_data}, $buf, 64); - - if ($rc == 0) { - printf "disconnect on port %s for %s\n", $teldsc->{port}, $ucb->{unitname}; - close ($teldsc->{fh_data}); - delete $teldsc->{fh_data}; - $teldsc->{state} = TELNET_STATE_LISTEN; - $serv11_fds_update = 1; - - } else { - my @int = unpack("C*", $buf); - foreach my $byt (@int) { - if ($teldsc->{state} == TELNET_STATE_STREAM) { # state: stream - if ($byt == TELNET_CODE_IAC) { - $teldsc->{state} = TELNET_STATE_IAC; - } else { - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - my @bytes; - push @bytes, $byt; - &{$ctl->{ichrhdl}}($ucb, \@bytes); # call ichr handler - } - } elsif ($teldsc->{state} == TELNET_STATE_IAC) { # state: IAC seen - if ($byt == TELNET_CODE_WILL || - $byt == TELNET_CODE_WONT || - $byt == TELNET_CODE_DO || - $byt == TELNET_CODE_DONT) { - $teldsc->{state} = TELNET_STATE_CMD; - } elsif ($byt == TELNET_CODE_SB) { - $teldsc->{state} = TELNET_STATE_SUBNEG; - } else { - $teldsc->{state} = TELNET_STATE_STREAM; - } - } elsif ($teldsc->{state} == TELNET_STATE_CMD) { # state: cmd seen - $teldsc->{state} = 0; - } elsif ($teldsc->{state} == TELNET_STATE_SUBNEG) { # state: subneg - if ($byt == TELNET_CODE_IAC) { - $teldsc->{state} = TELNET_STATE_SUBIAC; - } - } elsif ($teldsc->{state} == TELNET_STATE_SUBIAC) { # state: subneg+IAC - $teldsc->{state} = TELNET_STATE_STREAM; - } - } - } - } -} - -#------------------------------------------------------------------------------- - -sub telnet_writehdl { # telnet: write handler - my ($ucb) = @_; - - my $teldsc = $telnettbl{$ucb->{att_port}}; - return if $teldsc->{state} == TELNET_STATE_LISTEN; - - while (scalar( @{$ucb->{sndque}} )) { - my $byte = shift @{$ucb->{sndque}}; - syswrite($teldsc->{fh_data}, pack("C1",$byte), 1); -## FIXME: escape IAC !! -## if ($byte == TELNET_CODE_CR) { -## syswrite($teldsc->{fh_data}, pack("C1",TELNET_CODE_LF), 1); -## } - } - -} - -#------------------------------------------------------------------------------- - -sub pdp11_disassemble { - my ($pc,$d0,$d1,$d2) = @_; - my @mem = ($d0,0,0); - $mem[1] = $d1 if defined $d1; - $mem[2] = $d2 if defined $d2; - - my $code = shift @mem; - - foreach my $ele (@pdp11_opcode_tbl) { - if (($code & (~($ele->{mask})) ) == $ele->{code}) { - my $name = $ele->{name}; - my $type = $ele->{type}; - my $str = $name; - if ($type eq "0arg") { - return ($name,1); - - } elsif ($type eq "1arg" or $type eq "1fpp") { - my $dst = $code & 077; - my $pref = ($type eq "1fpp") ? "f" : "r"; - my ($dst_str,$dst_nw,$dst_ta) = - pdp11_disassemble_regmod($dst, $mem[0], $pc+2, $pref); - shift @mem if ($dst_nw); - $str = "$name $dst_str"; - if ($dst_ta) { - $str .= " " x (27-length($str)) if length($str)<27; - $str .= "; $dst_ta"; - } - return ($str, 1+$dst_nw); - - } elsif ($type eq "2arg") { - my $src = ($code>>6) & 077; - my $dst = $code & 077; - my ($src_str,$src_nw,$src_ta) = - pdp11_disassemble_regmod($src, $mem[0], $pc+2); - shift @mem if ($src_nw); - my ($dst_str,$dst_nw,$dst_ta) = - pdp11_disassemble_regmod($dst, $mem[0], $pc+2+2*$src_nw); - shift @mem if ($dst_nw); - $str = "$name $src_str,$dst_str"; - if ($src_ta or $dst_ta) { - $str .= " " x (27-length($str)) if length($str)<27; - $str .= ";"; - $str .= " $src_ta" if $src_ta; - $str .= " $dst_ta" if $dst_ta; - } - return ($str, 1+$src_nw+$dst_nw); - - } elsif ($type eq "rdst") { - my $reg = ($code>>6) & 07; - my $src = $code & 077; - my ($src_str,$src_nw,$src_ta) = - pdp11_disassemble_regmod($src, $mem[0], $pc+2); - shift @mem if ($src_nw); - $str = "$name $src_str,r$reg"; - if ($src_ta) { - $str .= " " x (27-length($str)) if length($str)<27; - $str .= "; $src_ta"; - } - return ($str, 1+$src_nw); - - } elsif ($type eq "1reg") { - my $reg = $code & 07; - my $reg_str = "r$reg"; - $reg_str = "sp" if $reg == 6; - $reg_str = "pc" if $reg == 7; - return ("$name $reg_str", 1); - - } elsif ($type eq "br") { - my $off = $code & 0177; - my $sign = "+"; - if ($code & 0200) { - $off = -(((~$off) & 0177)+1); - $sign = "-"; - } - my $str = sprintf "$name .%s%d.", $sign, abs(2*$off); - $str .= " " x (27-length($str)) if length($str)<27; - $str .= sprintf "; -> %6.6o", (($pc+2)+2*$off)&0177777; - return ($str, 1); - - } elsif ($type eq "sob") { - my $reg = ($code>>6) & 07; - my $off = $code & 077; - my $str = sprintf "$name r%d,.-%d.", $reg, 2*$off; - $str .= " " x (27-length($str)) if length($str)<27; - $str .= sprintf "; -> %6.6o", ($pc+2)-2*$off; - return ($str, 1); - - } elsif ($type eq "trap") { - my $off = $code & 0377; - my $str = sprintf "$name %3.3o", $off; - return ($str, 1); - - } elsif ($type eq "spl") { - my $off = $code & 07; - my $str = sprintf "$name %d", $off; - return ($str, 1); - - } elsif ($type eq "ccop") { - my $cc = $code & 017; - return ("nop",1) if ($cc == 0); - return ("ccc",1) if ($code == 0257); - return ("scc",1) if ($code == 0277); - my $str = ""; - my $del = ""; - if ($code & 010) { $str .= $del . $name . "n", $del = "+" } - if ($code & 004) { $str .= $del . $name . "z", $del = "+" } - if ($code & 002) { $str .= $del . $name . "v", $del = "+" } - if ($code & 001) { $str .= $del . $name . "c", $del = "+" } - return ($str, 1); - - } elsif ($type eq "jsr") { - my $reg = ($code>>6) & 07; - my $dst = $code & 077; - my ($dst_str,$dst_nw,$dst_ta) = - pdp11_disassemble_regmod($dst, $mem[0], $pc+2); - shift @mem if ($dst_nw); - $str = "$name r$reg,$dst_str"; - if ($dst_ta) { - $str .= " " x (27-length($str)) if length($str)<27; - $str .= "; $dst_ta"; - } - return ($str, 1+$dst_nw); - - } elsif ($type eq "mark") { - my $off = $code & 077; - my $str = sprintf "$name %3.3o", $off; - return ($str, 1); - - } elsif ($type eq "rfpp") { - my $reg = ($code>>6) & 03; - my $dst = $code & 077; - my ($dst_str,$dst_nw,$dst_ta) = - pdp11_disassemble_regmod($dst, $mem[0], $pc+2, "f"); - shift @mem if ($dst_nw); - $str = "$name f$reg,$dst_str"; - if ($dst_ta) { - $str .= " " x (27-length($str)) if length($str)<27; - $str .= "; $dst_ta"; - } - return ($str, 1+$dst_nw); - - } else { - return ("?type?",1); - } - } - } - return ("=inval=",1); -} - -#------------------------------------------------------------------------------- - -sub pdp11_disassemble_regmod { - my ($regmod,$data,$pc,$pref) = @_; - my $mod = ($regmod>>3) & 07; - my $reg = $regmod & 07; - - $pref = "r" if not defined $pref or $reg>5; - - my $reg_str = "r$reg"; - $reg_str = "sp" if $reg == 6; - $reg_str = "pc" if $reg == 7; - - if ($mod == 0) { # mode 0: Rx { Fx for float } - $reg_str = "f$reg" if defined $pref && $pref eq "f" && $reg<=5; - return ($reg_str, 0, ""); - } elsif ($mod == 1) { # mode 1: (Rx) - return ("($reg_str)", 0, ""); - } elsif ($mod == 2 || $mod == 3) { # mode 2/3: (Rx)+ @(Rx)+ - my $ind = ($mod == 3) ? "@" : ""; - if ($reg != 7) { # if reg != pc - return ("$ind($reg_str)+", 0, ""); - } else { # if reg == pc - my $str = sprintf "$ind#%6.6o", $data; # 27 -> #nnn; 37 -> @#nnn - return ($str, 1, ""); - } - } elsif ($mod == 4 || $mod == 5) { # mode 4/5: -(Rx) @-(Rx) - my $ind = ($mod == 5) ? "@" : ""; - return ("$ind-($reg_str)", 0, ""); - } elsif ($mod == 6 || $mod == 7) { # mode 6/7: nn(Rx) @nn(Rx) - my $ind = ($mod == 7) ? "@" : ""; - my $data_str = sprintf "%o", $data; - my $ta_str = ""; - $ta_str = sprintf "%6.6o",($pc+2+$data)&0177777 if ($reg==7); - return ("$ind$data_str($reg_str)", 1, $ta_str); - } -} - -#------------------------------------------------------------------------------- - -sub file_seek { # fseek wrapper - my ($fh,$pos) = @_; - my $rc; - my $offset = $pos; - my $whence = 0; - if ($pos < 0) { # if offset<0 -> seek to EOF - $offset = 0; - $whence = 2; - } - $rc = $fh->seek($offset, $whence); - if (not $rc) { - print "pi_rri($curmode)-E: file_seek failed\n"; - $rc = 0; - } - return $rc; -} - -#------------------------------------------------------------------------------- - -sub file_read { # fread wrapper - my ($fh,$nbyte) = @_; - my $rc; - my $buf = ""; - - $rc = $fh->read($buf, $nbyte); - if ($rc != $nbyte) { - print "pi_rri($curmode)-E: file_read failed, got $rc, expectd $nbyte\n"; - $rc = 0; - } - return ($rc, $buf); -} - -#------------------------------------------------------------------------------- - -sub file_seek_read { # fseek+fread wrapper - my ($fh,$pos,$nbyte) = @_; - my $rc; - my $buf; - $rc = file_seek($fh, $pos); - ($rc,$buf) = file_read($fh, $nbyte) if $rc; - return ($rc, $buf); -} - -#------------------------------------------------------------------------------- - -sub file_write { # fwrite wrapper - my ($fh,$buf) = @_; - my $rc; - $rc = print $fh $buf; - if (not $rc) { - print "pi_rri($curmode)-E: file_write failed\n"; - $rc = 0; - } - return $rc; -} - -#------------------------------------------------------------------------------- - -sub file_seek_write { # fseek+fwrite wrapper - my ($fh,$pos,$buf) = @_; - my $rc; - $rc = file_seek($fh, $pos); - $rc = file_write($fh, $buf) if $rc; - return $rc; -} - -#------------------------------------------------------------------------------- - -sub raw_get9_crc_16bit { # read 16 bit value - my ($dref) = @_; - my $idl = raw_get9_crc(); - my $idh = undef; - $idh = raw_get9_crc() if defined $idl; - - if (defined $idh) { - my $idat = $idl | ($idh<<8); - $$dref = $idat; - return 1; - } - print "pi_rri($curmode)-E: receive time out\n"; - print $fh_log "ERR -- receive time out in raw_get9_crc_16bit\n"; - return 0; -} - -#------------------------------------------------------------------------------- - -sub raw_get9_crc_8bit { # read 8bit value - my ($dref) = @_; - my $idat = raw_get9_crc(); - if (defined $idat) { - $$dref = $idat; - return 1; - } - return 0; -} - -#------------------------------------------------------------------------------- - -sub raw_get9_crc_check { # get 9bit, block, crc, ref value - my ($ref,$case) = @_; - my $dat = raw_get9_crc(); - if (defined $dat) { - return 1 if ($dat == $ref); - printf "pi_rri($curmode)-E: receive $case mismatch" . - " found=0x%3.3x expect=0x%3.3x\n", - $dat, $ref; - return 0; - } - return 0; -} - -#------------------------------------------------------------------------------- - -sub raw_get9_check { # get 9bit, block, expect ref value - my ($ref,$case) = @_; - my $dat = raw_get9(); - if (defined $dat) { - return 1 if ($dat == $ref); - printf "pi_rri($curmode)-E: receive $case mismatch" . - " found=0x%3.3x expect=0x%3.3x\n", - $dat, $ref; - return 0; - } - return 0; -} - -#------------------------------------------------------------------------------- - -sub raw_get9_checksop { # get 9bit, block, expect SOP - my $dat; - while(1) { - $dat = raw_get9(); - last unless defined $dat; - last if ($dat != D9ATTN); - if ($serv11_active) { - $serv11_attn_seen = 1; - } else { - printf "pi_rri($curmode)-W: unexpected ATTN comma dropped\n"; - } - } - if (defined $dat) { - return 1 if ($dat == D9SOP); - printf "pi_rri($curmode)-E: expect sop, but found=0x%3.3x\n", $dat; - } - return 0; -} - -#------------------------------------------------------------------------------- - -sub raw_get9_checkeop { # get 9bit, block, expect EOP - my $dat; - $dat = raw_get9(); - if (defined $dat) { - return 1 if ($dat == D9EOP); - printf "pi_rri($curmode)-E: expect eop, but found=0x%3.3x\n", $dat; - } - return 0; -} - -#------------------------------------------------------------------------------- - -sub raw_get9_crc { # get 9bit, block, update crc - my $dat = raw_get9(); - $icrc = $crc8_tbl[$icrc ^ $dat] if (defined $dat && $dat < 0x100); - return $dat; -} - -#------------------------------------------------------------------------------- - -sub raw_get9 { # get 9bit, block - my $nidle = 0; - my $dat = undef; - while (1) { - $dat = raw_rcv9_to($raw_timeout); - last unless defined $dat; - last if $dat != D9IDLE; - $nidle += 1; - } -## print "pi_rri($curmode)-I: dropped $nidle idle commas\n" if $nidle; - print "pi_rri($curmode)-E: receive time out\n" unless defined $dat; - print $fh_log "ERR -- receive time out in raw_get9\n" unless defined $dat; - return $dat; -} - -#------------------------------------------------------------------------------- - -sub raw_snd9_crc { # put 9bit to RX, update crc - my ($dat) = @_; - raw_snd9($dat); - $ocrc = $crc8_tbl[$ocrc ^ $dat] if ($dat < 0x100); -} - -#------------------------------------------------------------------------------- - -sub raw_snd9 { # put 9bit to RX - my ($dat) = @_; - - if (exists $opts{tio9}) { - print $fh_log conv_etime(\$tlast_tio9), - "[$curchan] snd9 ", conv_dat9($dat); - printf $fh_log " sndq=%3d", scalar(@que_snd); - print $fh_log " -- idle" if $dat == D9IDLE; - print $fh_log " -- sop " if $dat == D9SOP; - print $fh_log " -- eop " if $dat == D9EOP; - print $fh_log " -- nak " if $dat == D9NAK; - print $fh_log " -- attn" if $dat == D9ATTN; - print $fh_log "\n"; - } - $stat_tab{osop} += 1 if $dat == D9SOP; - - if ($dat >= 0x100) { - raw_snd8(CPREF | ($dat & 0x0f)); - } else { - if ( $dat == CESC || - ($dat >= CPREF && $dat <= (CPREF+NCOMM)) ) { - raw_snd8(CESC); - raw_snd8(CEN1 | ($dat & 0x0f)); - $stat_tab{oesc} += 1; - } else { - raw_snd8($dat); - } - } -} - -#------------------------------------------------------------------------------- - -sub raw_snd8 { # put 8bit to RX - my ($dat) = @_; - if (exists $opts{tio8}) { - print $fh_log conv_etime(\$tlast_tio8), - "[$curchan] snd8 ", conv_dat8($dat),"\n"; - } - $stat_tab{obyte} += 1; - - push @que_snd, int $dat; -} - -#------------------------------------------------------------------------------- - -sub raw_rcv9 { # get 9bit from TX, non-blocking - return raw_rcv9_to(0.); -} - -#------------------------------------------------------------------------------- - -sub raw_rcv8 { # get 8bit from TX, non-blocking - return raw_rcv8_to(0.); -} - -#------------------------------------------------------------------------------- - -sub raw_rcv9_to { - my ($timeout) = @_; - my $dat8 = raw_rcv8_to($timeout); - my $dat9 = undef; - - if (defined $dat8) { - if ($dat8 == CESC) { - $stat_tab{iesc} += 1; - $raw_rcv_esc = 1; - $dat8 = raw_rcv8_to($timeout); - return $dat8 unless defined $dat8; - } - if ($raw_rcv_esc) { - $dat9 = CPREF | ($dat8 & 0x0f); - $raw_rcv_esc = 0; - } else { - if ($dat8>= CPREF && $dat8<=(CPREF+NCOMM) ) { - $dat9 = 0x100 | ($dat8 & 0x0f); - } else { - $dat9 = $dat8; - } - } - } - - if (defined $dat9) { - $stat_tab{att} += 1 if $dat9 == D9ATTN; - ##print "+++9 attn seen\n" if $dat9==D9ATTN; - - if (exists $opts{tio9}) { - print $fh_log conv_etime(\$tlast_tio9), - "[$curchan] rcv9 ", conv_dat9($dat9); - printf $fh_log " rcvq=%3d", scalar(@que_rcv); - print $fh_log " -- idle" if $dat9 == D9IDLE; - print $fh_log " -- sop " if $dat9 == D9SOP; - print $fh_log " -- eop " if $dat9 == D9EOP; - print $fh_log " -- nak " if $dat9 == D9NAK; - print $fh_log " -- attn" if $dat9 == D9ATTN; - print $fh_log "\n"; - } - } - - return $dat9; -} - -#------------------------------------------------------------------------------- - -sub raw_rcv8_to { # get 8bit from TX, expl. time-out - my ($timeout) = @_; - my $buf; - my $dat; - - &{$chan_tab{$curchan}{write}}(); # flush write queue before read - - &{$chan_tab{$curchan}{read}}($timeout) unless @que_rcv; - if ($xesc_enable) { - &{$chan_tab{$curchan}{read}}($timeout) unless @que_rcv; - } - - $dat = shift @que_rcv; - - if (exists $opts{tio8} and defined $dat) { - print $fh_log conv_etime(\$tlast_tio8), - "[$curchan] rcv8 ", conv_dat8($dat),"\n"; - } - $stat_tab{ibyte} += 1; - - return $dat; -} - -#------------------------------------------------------------------------------- - -sub wait_sel_filercv { # poll/wait for TX to be ready - my ($timeout) = @_; - my $nfound=-1; - my $fds_rd; - - while ($nfound<0) { - $nfound = select($fds_rd=$fdset_filercv, undef, undef, $timeout); - next if ($nfound == -1) and $! == EINTR; - die "select error: $!" unless $nfound >= 0; - } - return $nfound; - } - -#------------------------------------------------------------------------------- - -sub fifo_open { # chan fifo: open handler - my ($arg) = @_; - my ($file,$keep) = split /,/,$arg; - my $file_base = $file ? $file : "rlink_cext_fifo"; - my $file_snd = $file_base . "_rx"; - my $file_rcv = $file_base . "_tx"; - - $fifo_keep = $keep; - $fdset_filercv = ""; - - print_fatal("I/O mode already set to --$curchan") if ($curchan); - - if (-e $file_snd) { - print_fatal("$file_snd exists but is not a pipe") unless (-p $file_snd); - } else { - mkfifo($file_snd, 0666) || die "can't mkfifo $file_snd: $!"; - print "pi_rri[fifo]-I: created fifo $file_snd\n"; - } - - if (-e $file_rcv) { - print_fatal("$file_rcv exists but is not a pipe") unless (-p $file_rcv); - } else { - mkfifo($file_rcv, 0666) || die "can't mkfifo $file_rcv: $!"; - print "pi_rri[fifo]-I: created fifo $file_rcv\n"; - } - - $fh_snd = new FileHandle; - $fh_rcv = new FileHandle; - - print "pi_rri[fifo]-I: wait to connect to $file_snd\n"; - sysopen ($fh_snd, $file_snd, O_WRONLY) || die "can't open $file_snd: $!"; - print "pi_rri[fifo]-I: connected to $file_snd\n"; - sysopen ($fh_rcv, $file_rcv, O_RDONLY) || die "can't open $file_rcv: $!"; - print "pi_rri[fifo]-I: connected to $file_rcv\n"; - vec($fdset_filercv, fileno($fh_rcv), 1) = 1; - - $curchan = "fifo"; -} - -#------------------------------------------------------------------------------- - -sub fifo_close { # chan fifo: close handler - if ($fifo_keep) { - print "pi_rri[fifo]-I: signal 'keep-alive' to tb\n"; - raw_snd8(CESC); - raw_snd8(CESC); - &{$chan_tab{$curchan}{write}}(); - } - close $fh_snd; - close $fh_rcv; - $fh_snd = undef; - $fh_rcv = undef; - $curchan = undef; -} - -#------------------------------------------------------------------------------- -# -sub term_open { # term fifo: open handler - my ($arg) = @_; - my ($dev,$baud,$break,$flow) = split /,/,$arg; - $dev = "/dev/ttyS0" unless defined $dev; - $baud = 115200 unless defined $baud; - $break = 0 unless defined $break; # default: no break - $flow = 1 unless defined $flow; # default: cts - - $fdset_filercv = ""; - - print_fatal("I/O mode already set to --$curchan") if ($curchan); - - $fh_snd = new FileHandle; - $fh_rcv = $fh_snd; # same file handle for read and write - - sysopen ($fh_snd, $dev, O_RDWR|O_NOCTTY) || # read/write, not control TTY - die "can't open $dev: $!"; - my $fd = fileno($fh_snd); - vec($fdset_filercv, $fd, 1) = 1; - $curchan = "term"; - - print_fatal("$dev is not a TTY") unless isatty($fd); - - $term_oldtios = new POSIX::Termios; - $term_oldtios->getattr($fd) || die "getattr failed: $!"; - - print_fatal("flow attribute must be 0(none),1(cts), or 2(xon)") - unless ($flow>=0 && $flow<=2); - - $xesc_enable = ($flow == 2); # enable/disable xesc escaping - $xesc_pending = 0; - -## term_tios_print($term_oldtios); - - my $newtios = new POSIX::Termios; - $newtios->getattr($fd) || die "getattr failed: $!"; ## hack for cygwin !! - - my $c_iflag = &POSIX::BRKINT; # ignore parity errors (??? WRONG??) - if ($flow == 2) { - $c_iflag |= &POSIX::IXON | # XON/XOFF flow control output - &POSIX::IXOFF; # XON/XOFF flow control input - } - - my $c_oflag = 0; - - my $c_cflag = &POSIX::CS8 | # 8 bit chars - &POSIX::CSTOPB | # 2 stop bits - &POSIX::CREAD | # enable receiver - &POSIX::CLOCAL; # ignore modem control - if ($flow == 1) { # if cts/rts flow control - $c_cflag |= LINUX_CRTSCTS; # enable hardware flow control - } - - my $c_lflag = 0; - - my $speed = 0; - $speed = &POSIX::B9600 if $baud == 9600; - $speed = &POSIX::B19200 if $baud == 19200; - $speed = &POSIX::B38400 if $baud == 38400; - $speed = LINUX_B57600 if $baud == 57600; # hack, only for linux - $speed = LINUX_B115200 if $baud == 115200; # hack, only for linux - $speed = LINUX_B230400 if $baud == 230400; # hack, only for linux - $speed = LINUX_B460800 if $baud == 460800; # hack, only for linux - $speed = LINUX_B500000 if $baud == 500000; # hack, only for linux - $speed = LINUX_B921600 if $baud == 921600; # hack, only for linux - $speed = LINUX_B1000000 if $baud ==1000000; # hack, only for linux - $speed = LINUX_B2000000 if $baud ==2000000; # hack, only for linux - $speed = LINUX_B3000000 if $baud ==3000000; # hack, only for linux - - print_fatal("speed $baud not supported") unless $speed != 0; - - $c_cflag |= $speed; - - $newtios->setiflag($c_iflag); - $newtios->setoflag($c_oflag); - $newtios->setcflag($c_cflag); - $newtios->setlflag($c_lflag); - $newtios->setcc(&POSIX::VEOF, 0); # undef - $newtios->setcc(&POSIX::VEOL, 0); # undef - $newtios->setcc(&POSIX::VERASE, 0); # undef - $newtios->setcc(&POSIX::VINTR, 0); # undef - $newtios->setcc(&POSIX::VKILL, 0); # undef - $newtios->setcc(&POSIX::VQUIT, 0); # undef - $newtios->setcc(&POSIX::VSUSP, 0); # undef - $newtios->setcc(&POSIX::VSTART, 0); # undef - $newtios->setcc(&POSIX::VSTOP, 0); # undef - $newtios->setcc(&POSIX::VMIN, 1); # wait for 1 char - $newtios->setcc(&POSIX::VTIME, 0); # - - if ($flow == 2) { - $newtios->setcc(&POSIX::VSTART, KC_XON); # setup XON -> ^Q - $newtios->setcc(&POSIX::VSTOP, KC_XOFF); # setup XOFF -> ^S - } - -## term_tios_print($newtios); - - $newtios->setattr($fd) || die "setattr failed: $!"; - - if ($break) { - tcsendbreak($fd, 0) || die "tcsendbreak failed: $!"; - raw_snd8 (0x80); - &{$chan_tab{$curchan}{write}}(); # write 10000000 for autobaud - } - -} - -#------------------------------------------------------------------------------- - -sub term_close { # chan term: close handler - $term_oldtios->setattr(fileno($fh_snd)) || die "setattr failed: $!"; - close $fh_snd; - $fh_snd = undef; - $fh_rcv = undef; - $curchan = undef; -} - -#------------------------------------------------------------------------------- - -sub term_tios_print { - my ($tios) = @_; - - my $iflag = $tios->getiflag; - my $oflag = $tios->getoflag; - my $cflag = $tios->getcflag; - my $lflag = $tios->getlflag; - - printf "iflag = %8.8x:", $iflag; - print " BRKINT" if $iflag & &POSIX::BRKINT; - print " ICRNL " if $iflag & &POSIX::ICRNL; - print " IGNBRK" if $iflag & &POSIX::IGNBRK; - print " IGNCR " if $iflag & &POSIX::IGNCR; - print " IGNPAR" if $iflag & &POSIX::IGNPAR; - print " INLCR " if $iflag & &POSIX::INLCR; - print " INPCK " if $iflag & &POSIX::INPCK; - print " ISTRIP" if $iflag & &POSIX::ISTRIP; - print " IXOFF " if $iflag & &POSIX::IXOFF; - print " IXON " if $iflag & &POSIX::IXON; - print " PARMRK" if $iflag & &POSIX::PARMRK; - print "\n"; - printf "oflag = %8.8x:", $oflag; - print " OPOST " if $oflag & &POSIX::OPOST; - print "\n"; - - printf "cflag = %8.8x:", $cflag; - print " CLOCAL" if $cflag & &POSIX::CLOCAL; - print " CREAD " if $cflag & &POSIX::CREAD; - print " CS5 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS5; - print " CS6 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS6; - print " CS7 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS7; - print " CS8 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS8; - print " CSTOPB" if $cflag & &POSIX::CSTOPB; - print " HUPCL " if $cflag & &POSIX::HUPCL; - print " PARENB" if $cflag & &POSIX::PARENB; - print " PARODD" if $cflag & &POSIX::PARODD; - - my $sbits = &POSIX::B50 | &POSIX::B75 | &POSIX::B110 | &POSIX::B134 | - &POSIX::B150 | &POSIX::B200 | &POSIX::B300 | &POSIX::B600 | - &POSIX::B1200 | &POSIX::B1800 | &POSIX::B2400 | &POSIX::B4800 | - &POSIX::B9600 | &POSIX::B19200 | &POSIX::B38400; - print " B0 " if ($cflag & $sbits) == &POSIX::B0; - print " B50 " if ($cflag & $sbits) == &POSIX::B50; - print " B75 " if ($cflag & $sbits) == &POSIX::B75; - print " B110 " if ($cflag & $sbits) == &POSIX::B110; - print " B134 " if ($cflag & $sbits) == &POSIX::B134; - print " B150 " if ($cflag & $sbits) == &POSIX::B150; - print " B200 " if ($cflag & $sbits) == &POSIX::B200; - print " B300 " if ($cflag & $sbits) == &POSIX::B300; - print " B600 " if ($cflag & $sbits) == &POSIX::B600; - print " B1200 " if ($cflag & $sbits) == &POSIX::B1200; - print " B1800 " if ($cflag & $sbits) == &POSIX::B1800; - print " B2400 " if ($cflag & $sbits) == &POSIX::B2400; - print " B4800 " if ($cflag & $sbits) == &POSIX::B4800; - print " B9600 " if ($cflag & $sbits) == &POSIX::B9600; - print " B19200" if ($cflag & $sbits) == &POSIX::B19200; - print " B38400" if ($cflag & $sbits) == &POSIX::B38400; - print "\n"; - - printf "lflag = %8.8x:", $lflag; - print " ECHO " if $lflag & &POSIX::ECHO; - print " ECHOE " if $lflag & &POSIX::ECHOE; - print " ECHOK " if $lflag & &POSIX::ECHOK; - print " ECHONL" if $lflag & &POSIX::ECHONL; - print " ICANON" if $lflag & &POSIX::ICANON; - print " IEXTEN" if $lflag & &POSIX::IEXTEN; - print " ISIG " if $lflag & &POSIX::ISIG; - print " NOFLSH" if $lflag & &POSIX::NOFLSH; - print " TOSTOP" if $lflag & &POSIX::TOSTOP; - print "\n"; - - printf "cc(VEOF) = %3.3o\n", $tios->getcc(&POSIX::VEOF); - printf "cc(VEOL) = %3.3o\n", $tios->getcc(&POSIX::VEOL); - printf "cc(VERASE)= %3.3o\n", $tios->getcc(&POSIX::VERASE); - printf "cc(VINTR) = %3.3o\n", $tios->getcc(&POSIX::VINTR); - printf "cc(VKILL) = %3.3o\n", $tios->getcc(&POSIX::VKILL); - printf "cc(VQUIT) = %3.3o\n", $tios->getcc(&POSIX::VQUIT); - printf "cc(VSUSP) = %3.3o\n", $tios->getcc(&POSIX::VSUSP); - printf "cc(VSTART)= %3.3o\n", $tios->getcc(&POSIX::VSTART); - printf "cc(VSTOP) = %3.3o\n", $tios->getcc(&POSIX::VSTOP); - printf "cc(VMIN) = %3.3o\n", $tios->getcc(&POSIX::VMIN); - printf "cc(VTIME) = %3.3o\n", $tios->getcc(&POSIX::VTIME); -# printf "cc(NCCS) = %3.3o\n", $tios->getcc(&POSIX::NCCS); -} - -#------------------------------------------------------------------------------- - -sub genio_read { # generic io: read handler - my ($timeout) = @_; - my $tstart; - my $rc; - - $tstart = get_time() if exists $opts{tiob}; - if (wait_sel_filercv($timeout)) { - my $buf; - - while (not defined $rc) { - $rc = sysread($fh_rcv, $buf, 64); - next if (not defined $rc) and $! == EINTR; - die "sysread fifo error: $!" unless defined $rc; - } - - if (exists $opts{tiob}) { - printf $fh_log "%s[$curchan] read %3d bytes in %8.6f sec\n", - conv_etime(\$tlast_tiob), $rc, get_time()-$tstart; - } - if ($rc) { - if ($xesc_enable) { - my @que_rcv_xesc = unpack("C*", $buf); - foreach my $char (@que_rcv_xesc) { - if ($xesc_pending) { - push @que_rcv, (~$char) & 0xff; - $xesc_pending = 0; - } elsif ($char == KC_XESC) { - $xesc_pending = 1; - } else { - push @que_rcv, $char; - } - } - - } else { - push @que_rcv, unpack("C*", $buf); - } - } - } -### if (defined $rc) { -### printf "+++1 _read $timeout rc=%d\n", $rc; -### } else { -### printf "+++1 _read $timeout rc=undef\n"; -### } - return $rc; -} - -#------------------------------------------------------------------------------- - -sub genio_write { # generic io: write handler -## printf "+++2 _write q=%d\n", scalar @que_snd; - if (scalar @que_snd) { - - my $buf; - - if ($xesc_enable) { # handle xon,xoff,xesc escaping - my @que_snd_xesc; - foreach my $char (@que_snd) { - if ($char==KC_XON || $char==KC_XOFF || $char==KC_XESC) { - push @que_snd_xesc, KC_XESC; - push @que_snd_xesc, (~$char) & 0xff; - } else { - push @que_snd_xesc, $char; - } - } - $buf = pack("C*", @que_snd_xesc); - - } else { - $buf = pack("C*", @que_snd); - } - - while (length($buf)) { - while(1) { # read rcv fifo before writing - my $rc = genio_read(0.); # to avoid blocking under cygwin - last unless defined $rc and $rc > 0; - } - my $nwrite = length($buf); -### $nwrite = 1; # <-- when is this really needed ??? -### printf "+++2a _write nw=%d\n", $nwrite; - my $rc = syswrite($fh_snd, $buf, $nwrite); - next if (not defined $rc) and $! == EINTR; - die "syswrite fifo error: $!" unless defined $rc; - if (exists $opts{tiob}) { - printf $fh_log "%s[$curchan] write %3d bytes", conv_etime(\$tlast_tiob), $rc; - printf $fh_log " of %3d in queue", length($buf) if $rc < length($buf); - print $fh_log "\n"; - } - last if $rc == length($buf); - $buf = substr($buf, $rc); - } - - @que_snd = (); - } -} - -#------------------------------------------------------------------------------- - -sub cget_chkblank { # check for unused chars in cmd line - $cmd_rest =~ s/^\s*//; - if ($cmd_rest ne "") { - print "pi_rri($curmode)-E: extra data ignored: \"$cmd_rest\"\n"; - print " for command: \"$cmd_line\"\n"; - $cmd_bad = 1; - } - return $cmd_bad; -} - -#------------------------------------------------------------------------------- - -sub cget_tagval2_gdat { # get tag=v1[,v2], generic base - my ($tag,$nbit,$dbase) = @_; - my $dat; - my $msk = undef; - $cmd_rest =~ s/^\s*//; -### print "+++2 |$cmd_rest|$tag|$nbit|$dbase|\n"; - if ($cmd_rest =~ /^$tag=/) { - $cmd_rest = $'; - if ($cmd_rest =~ /^-/) { - $cmd_rest = $'; - return (0,0xffff); - } else { - $dat = cget_gdat($nbit, $dbase); - if ($cmd_rest =~ /^,/) { - $cmd_rest = $'; - $msk = cget_gdat($nbit, $dbase); - } - return ($dat, $msk); - } - } - return (undef, undef); -} - -#------------------------------------------------------------------------------- - -sub cget_tagval_gdat { # get tag=val, generic base - my ($tag,$nbit,$dbase,$min,$max) = @_; - $cmd_rest =~ s/^\s*//; - if ($cmd_rest =~ /^$tag=/) { - $cmd_rest = $'; - return cget_gdat($nbit, $dbase,$min,$max); - } - return undef; -} - -#------------------------------------------------------------------------------- - -sub cget_gdat { # get generic base value - my ($nbit,$dbase,$min,$max) = @_; - my $dat; - - $cmd_rest =~ s/^\s*//; -### print "+++1 |$nbit|$dbase|$cmd_rest|\n"; - if ($cmd_rest =~ /^[xXoObBdD]"/) { - if ($cmd_rest =~ /^[xX]"([0-9a-fA-F]+)"/) { - $cmd_rest = $'; - $dat = hex $1; - } elsif ($cmd_rest =~ /^[oO]"([0-7]+)"/) { - $cmd_rest = $'; - $dat = oct $1; - } elsif ($cmd_rest =~ /^[bB]"([01]+)"/) { - $cmd_rest = $'; - my $odat = sget_bdat($nbit, $1); - $dat = $odat if defined $odat; - } elsif ($cmd_rest =~ /^[dD]"([+-]?[0-9]+)"/) { - $cmd_rest = $'; - my $odat = (int $1) & ((1<<$nbit)-1); - $dat = $odat; - } - } else { - if ($cmd_rest =~ /^([+-]?[0-9]+)\./) { - $cmd_rest = $'; - my $odat = (int $1) & ((1<<$nbit)-1); - $dat = $odat; - } elsif ($dbase == 16 && $cmd_rest =~ /^([0-9a-fA-F]+)/) { - $cmd_rest = $'; - $dat = hex $1; - } elsif ($dbase == 8 && $cmd_rest =~ /^([0-7]+)/) { - $cmd_rest = $'; - $dat = oct $1; - } elsif ($dbase == 2 && $cmd_rest =~ /^([01]+)/) { - $cmd_rest = $'; - my $odat = sget_bdat($nbit, $1); - $dat = $odat if defined $odat; - } elsif ($dbase == 10 && $cmd_rest =~ /^([0-9]+)/) { - $cmd_rest = $'; - $dat = int $1; - } - } - - if (not defined $dat) { - $cmd_bad = 1; - print "pi_rri($curmode)-E: cget_gdat error in \"$cmd_rest\" (base=$dbase)\n"; - return undef; - } - - if (defined $min && $dat < $min) { - $cmd_bad = 1; - print "pi_rri($curmode)-E: cget_gdat range error, $dat < $min\n"; - return undef; - } - if (defined $max && $dat > $max) { - $cmd_bad = 1; - print "pi_rri($curmode)-E: cget_gdat range error, $dat > $max\n"; - return undef; - } - - return $dat; -} - -#------------------------------------------------------------------------------- - -sub cget_name { # get name \w+ - - $cmd_rest =~ s/^\s*//; - if ($cmd_rest =~ /^(\w+)/) { - $cmd_rest = $'; - return $1; - } - - $cmd_bad = 1; - print "pi_rri($curmode)-E: cget_name error in \"$cmd_rest\"\n"; - return undef; -} - -#------------------------------------------------------------------------------- - -sub cget_bool { # get boolean [01] - $cmd_rest =~ s/^\s*//; - if ($cmd_rest =~ /^([01])/) { - $cmd_rest = $'; - return int($1); - } - - $cmd_bad = 1; - print "pi_rri($curmode)-E: cget_name error in \"$cmd_rest\"\n"; - return undef; -} - -#------------------------------------------------------------------------------- - -sub cget_file { # get filename [\w\/.]+ - - $cmd_rest =~ s/^\s*//; - if ($cmd_rest =~ /^([\w\/.-]+)/) { - $cmd_rest = $'; - return $1; - } - - $cmd_bad = 1; - print "pi_rri($curmode)-E: cget_file error in \"$cmd_rest\"\n"; - return undef; -} - -#------------------------------------------------------------------------------- - -sub cget_ucb { # get ucb (read name, return ucb) - my ($type,$name) = @_; - - $name = cget_name() unless defined $name; - return undef if not defined $name; - - $name = uc($name); - $name .= "0" if length($name)==2; - if (not exists $serv11_unittbl{$name}) { - $cmd_bad = 1; - print "pi_rri($curmode)-E: unknown device unit $name\n"; - return undef; - } - - my $ucb = $serv11_unittbl{$name}; - my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; - - if (not $ctl->{probe_ok}) { - $cmd_bad = 1; - print "pi_rri($curmode)-E: device controller $name not available\n"; - return undef; - } - - if (defined $type) { - if ($ctl->{type} ne $type) { - $cmd_bad = 1; - print "pi_rri($curmode)-E: $name is not type=$type\n"; - return undef; - } - } - - return $ucb; -} - -#------------------------------------------------------------------------------- - -sub cget_opt { # get option - my ($opt) = @_; - if ($cmd_rest =~ /^\s*$opt\b/) { # opt found, followed by non \w - $cmd_rest = $'; - return 1; - } - return 0; -} - -#------------------------------------------------------------------------------- - -sub cget_optset { # get option set - my ($optset) = @_; - my $optout = ""; - while ($cmd_rest =~ /\s*-([a-zA-Z])\b/) { # any -x found - $cmd_rest = $'; - my $optchar = $1; - if ($optset =~ /$optchar/) { # char in optset ? - $optout .= $optchar; - } else { - $cmd_bad = 1; - print "pi_rri($curmode)-E: unexpected option -$optchar\n"; - } - } - return $optout; -} - -#------------------------------------------------------------------------------- -sub cget_regrange { # get register/memory range - my $ctl; - my $beg; - my $end; - - if (cchk_number()) { # numerical address - $beg = cget_gdat(22,8); - $end = $beg; - if ($cmd_rest =~ m{^:}) { - $cmd_rest =~ s{^:}{}; - $end = cget_gdat(22,8); - } elsif ($cmd_rest =~ m{^/}) { - $cmd_rest =~ s{^/}{}; - $end = $beg + cget_gdat(22,8) - 2; - } - - } else { # symbolical address - my $regtbl; - my $ctlnam = uc(cget_name()); - my $begnam = lc($ctlnam); - my $endnam; - if (exists $serv11_ctltbl{CPU}->{regtbl}->{$begnam}) { - $ctlnam = "CPU"; - $regtbl = $serv11_ctltbl{CPU}->{regtbl}; - } elsif (exists $serv11_ctltbl{$ctlnam}->{regtbl}) { - $regtbl = $serv11_ctltbl{$ctlnam}->{regtbl}; - $begnam = lc(cget_name()); - } else { - print "pi_rri($curmode)-E: '$begnam' neither controller nor" . - " cpu register name\n"; - $cmd_bad = 1; - return (undef, undef, undef); - } - - $ctl = $serv11_ctltbl{$ctlnam}; - - if (not $ctl->{probe_ok}) { - print "pi_rri($curmode)-E: '$ctlnam' not available\n"; - $cmd_bad = 1; - return (undef, undef, undef); - } - - my $reglist = $ctl->{reglist}; - $beg = 0; - $end = scalar @{$reglist}-1; - - if ($begnam ne "state") { - - $endnam = $begnam; - if ($cmd_rest =~ m{^:}) { - $cmd_rest =~ s{^:}{}; - $endnam = lc(cget_name()); - } - - if (not exists $regtbl->{$begnam}) { - print "pi_rri($curmode)-E: '$begnam' not register in '$ctlnam'\n"; - $cmd_bad = 1; - return (undef, undef, undef); - } - if (not exists $regtbl->{$endnam}) { - print "pi_rri($curmode)-E: '$endnam' not register in '$ctlnam'\n"; - $cmd_bad = 1; - return (undef, undef, undef); - } - - $beg = $regtbl->{$begnam}; - $end = $regtbl->{$endnam}; - } - } - - if (defined $beg && defined $end && $beg > $end) { - my $tmp = $beg; - $beg = $end; - $end = $tmp; - } - - return ($ctl, $beg, $end); -} - -#------------------------------------------------------------------------------- - -sub cchk_number { # check for number. any gdat value - # except for plain hex (e.g. 'dead') - return 1 if $cmd_rest =~ /^\s*([0-9]+)/; - return 1 if $cmd_rest =~ /^\s*([+-]?[0-9]+)\./; - return 1 if $cmd_rest =~ /^\s*[xX]"([0-9a-fA-F]+)"/; - return 1 if $cmd_rest =~ /^\s*[oO]"([0-9]+)"/; - return 1 if $cmd_rest =~ /^\s*[bB]"([01]+)"/; - return 1 if $cmd_rest =~ /^\s*[dD]"([+-]?[0-9]+)"/; - return 0; -} - -#------------------------------------------------------------------------------- - -sub sget_bdat { # convert 01 string -> binary value - my ($nbit,$str) = @_; - my $nchar = length($str); - my $odat = 0; - my $i; - - return undef if ($nchar != $nbit); - - for ($i = 0; $i < $nchar; $i++) { - $odat *= 2; - $odat += 1 if substr($str, $i, 1) eq "1"; - } - return $odat; -} - -#------------------------------------------------------------------------------- - -sub conv_etime { # generate timestamp string - my ($ref_elast) = @_; - my $etime = get_time()-$time0; - my $str = sprintf "%12.6f ", $etime; - if (defined $ref_elast) { - my $dt = $etime - $$ref_elast; - $$ref_elast = $etime; - $str .= sprintf "(%10.6f) ", $dt; - } - return $str; -} - -#------------------------------------------------------------------------------- - -sub conv_dat9 { - my ($dat9) = @_; - return (($dat9 & 0x100) ? "1" : "0") . " " . conv_dat8($dat9); -} - -#------------------------------------------------------------------------------- - -sub conv_dat8 { - my ($dat8) = @_; - my $buf = ""; - vec($buf,0,8) = int $dat8; - return unpack("B8",$buf); -} - -#------------------------------------------------------------------------------- - -sub conv_str2bytes { # string to bytelist; handle \n\r - my ($str,$dref,$esc) = @_; - - while (length($str)) { - if ($esc && $str =~ /^\\n/) { - push @{$dref}, 0015; # send CR - $str = $'; - } elsif ($esc && $str =~ /^\\r/) { - push @{$dref}, 0013; # send LF - $str = $'; - } else { - my $chr = substr($str,0,1); - push @{$dref}, ord($chr); - $str = substr($str,1); - } - } -} - -#------------------------------------------------------------------------------- - -sub conv_buf2wlist { # string buffer -> word list - my ($buf) = @_; - my @sysbyt; - my $nw = int(length($buf)/2); - my $dref = []; - my $i; - - push @sysbyt, unpack("C*", $buf); - for ($i=0; $i<$nw; $i++) { - my $bl = shift @sysbyt; # lsb is first - my $bh = shift @sysbyt; - push @{$dref}, 256*$bh + $bl; - } - return $dref; -} - -#------------------------------------------------------------------------------- - -sub conv_wlist2buf { # word list -> string buffer - my ($dref) = @_; - my @sysbyt; - my $buf; - - foreach my $word (@{$dref}) { - my $bl = $word & 0xff; - my $bh = ($word>>8) & 0xff; - push @sysbyt, $bl; # lsb is first - push @sysbyt, $bh; - } - - $buf = pack("C*", @sysbyt); - return $buf; -} - -#------------------------------------------------------------------------------- - -sub conv_byte2ascii2 { # byte -> 2 charcter ASCII display - my ($byte) = @_; - if ($byte >= 32 && $byte < 128) { - return chr($byte) . " "; - } else { - my $str = ".."; - $str = "\\0" if $byte == 000; # NUL 000 -> \0 - $str = "\\a" if $byte == 007; # BEL 007 -> \a - $str = "\\b" if $byte == 010; # BS 010 -> \b - $str = "\\t" if $byte == 011; # TAB 011 -> \t - $str = "\\n" if $byte == 012; # LF 012 -> \n - $str = "\\v" if $byte == 013; # VT 013 -> \v - $str = "\\f" if $byte == 014; # FF 014 -> \f - $str = "\\r" if $byte == 015; # CR 015 -> \r - return $str; - } -} - -#------------------------------------------------------------------------------- - -sub gconv_dat16 { - my ($dat,$dbase) = @_; - if ($dbase == 2) { - my $bufl = ""; - my $bufh = ""; - vec($bufl,0,8) = int ($dat & 0xff); - vec($bufh,0,8) = int (($dat>>8) & 0xff); - return unpack("B8",$bufh) . unpack("B8",$bufl); - } elsif ($dbase == 8) { - return sprintf "%6.6o", int $dat; - } elsif ($dbase == 16) { - return sprintf "%4.4x", int $dat; - } else { - return "??dbase??"; - } -} -#------------------------------------------------------------------------------- - -sub hdl_sigint { # SIGINT handler - if ($sigint_count == 1) { - print STDERR "\a"; # send beep - } elsif ($sigint_count == 2) { - print STDERR "pi_rri($curmode)-W: not responding on ^C, next will abort\n"; - } elsif ($sigint_count == 3) { - print STDERR "pi_rri($curmode)-E: ^C abort\n"; - exit(1); - } - $sigint_count += 1; -} - -#------------------------------------------------------------------------------- - -sub get_time { - my ($sec, $usec) = gettimeofday(); - return $sec + 1.e-6 * $usec; -} - -#------------------------------------------------------------------------------- - -sub get_timestamp { - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); - return sprintf "%2.2d:%2.2d:%2.2d", $hour, $min, $sec; -} - -#------------------------------------------------------------------------------- - -sub filename_expand { # expand $nnn in name - my ($file) = @_; - my $fileexp = $file; - - while($fileexp =~ /\$(\w+)/) { - if (exists $ENV{$1}) { - $fileexp = $` . $ENV{$1} . $'; - } else { - printf "pi_rri-E: environment variable \$%s not defined\n", $1; - $fileexp = $` . "\$?" . $1 . "?" . $'; - } - } - - return $fileexp; -} - -#------------------------------------------------------------------------------- - -sub print_fatal { - my ($msg) = @_; - print STDERR "pi_rri($curmode)-F: $msg\n"; - exit 1; -} - -#------------------------------------------------------------------------------- - -sub print_help { - print "usage: pi_rri\n"; - print " --help this message\n"; - print " --int force interactive mode\n"; - print " --trace trace\n"; - - printf "CPREF %2.2x\n", CPREF; - printf "NCOMM %2.2x\n", NCOMM; - printf "CESC %2.2x\n", CESC; - printf "CEN1 %2.2x\n", CEN1; - -} diff --git a/tools/bin/telnet_wrapper b/tools/bin/telnet_wrapper index e1929593..0dcf2ddf 100755 --- a/tools/bin/telnet_wrapper +++ b/tools/bin/telnet_wrapper @@ -1,7 +1,7 @@ #!/usr/bin/perl -w -# $Id: telnet_wrapper 314 2010-07-09 17:38:41Z mueller $ +# $Id: telnet_wrapper 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2009- by Walter F.J. Mueller +# Copyright 2009-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -37,7 +37,7 @@ while(1) { if ($rc != 0) { print STDERR "telnet failed with rc=$rc\n"; } - print "enter q or <^D> to quit, otherwise reconnect: "; + print "enter q or <^D> to quit, otherwise hit to reconnect: "; my $buf; my $nc = read STDIN, $buf, 1; if (not defined $nc) { diff --git a/rtl/sys_gen/w11a/tb/torri b/tools/bin/ti_w11 similarity index 85% rename from rtl/sys_gen/w11a/tb/torri rename to tools/bin/ti_w11 index d4ba2031..56746580 100755 --- a/rtl/sys_gen/w11a/tb/torri +++ b/tools/bin/ti_w11 @@ -1,8 +1,9 @@ #!/usr/bin/perl -w -# $Id: torri 511 2013-04-27 13:51:46Z mueller $ +# $Id: ti_w11 516 2013-05-05 21:24:52Z mueller $ # # Revision History: # Date Rev Version Comment +# 2013-05-05 516 1.1 renamed to ti_w11 # 2013-04-26 510 1.0 Initial version (derived from dorri) # @@ -14,22 +15,24 @@ sub print_usage; autoflush STDOUT 1; # autoflush, so noting lost on exec later +my $sysbase = "$ENV{RETROBASE}/rtl/sys_gen/w11a"; + my $opt_b; my $opt_io = ''; my $opt_f = ''; my $opt_tmu; my $tirri; my $val_term; -my $val_tb_s3='tbw ../s3board/tb/tb_w11a_s3'; -my $val_tb_n2='tbw ../nexys2/tb/tb_w11a_n2'; -my $val_tb_n3='tbw ../nexys3/tb/tb_w11a_n3'; +my $val_tb_s3 = "tbw $sysbase/s3board/tb/tb_w11a_s3"; +my $val_tb_n2 = "tbw $sysbase/nexys2/tb/tb_w11a_n2"; +my $val_tb_n3 = "tbw $sysbase/nexys3/tb/tb_w11a_n3"; my $val_tb; my $val_e; my @arglist; # -# process torri options +# process ti_w11 options # while (scalar(@ARGV)) { my $curarg = $ARGV[0]; @@ -68,7 +71,7 @@ while (scalar(@ARGV)) { $baud = '115k' unless defined $baud; if ($baud !~ m{^\d*k?$}) { - print STDERR "torri-E: invalid format of -ts or -tu option\n"; + print STDERR "ti_w11-E: invalid format of -ts or -tu option\n"; exit 1; } @@ -83,16 +86,16 @@ while (scalar(@ARGV)) { shift @ARGV; } elsif ($curarg =~ m{^-e$} ) { # -e - print STDERR "torri-W: multiple -e options, only last taken\n" + print STDERR "ti_w11-W: multiple -e options, only last taken\n" if defined $val_e; shift @ARGV; if (scalar(@ARGV) == 0 || $ARGV[0] =~ m{^-}) { - print STDERR "torri-E: no file name after -e option\n"; + print STDERR "ti_w11-E: no file name after -e option\n"; exit 1; } else { $val_e = shift @ARGV; if (not -r $val_e) { - print STDERR "torri-E: file '$val_e' not found\n"; + print STDERR "ti_w11-E: file '$val_e' not found\n"; exit 1; } } @@ -114,7 +117,7 @@ if ($opt_io eq 'f') { } elsif ($opt_io eq 'u') { push @arglist, '--cuff'; } else { - print STDERR "torri-E: neither -s3/-n2/-n3 nor -t or -u specified\n"; + print STDERR "ti_w11-E: neither -s3/-n2/-n3 nor -t or -u specified\n"; print_usage(); exit 1; } @@ -171,7 +174,7 @@ if (defined $val_e) { while (scalar(@ARGV)) { my $curarg = shift @ARGV; if ($curarg =~ m{^@(.*)$} && ! -r $1) { - print STDERR "torri-E: file '$1' not found\n"; + print STDERR "ti_w11-E: file '$1' not found\n"; exit 1; } push @arglist,$curarg; @@ -184,7 +187,7 @@ while (scalar(@ARGV)) { $tirri=`which ti_rri`; chomp $tirri; if ($tirri eq '' || ! -e $tirri) { - print STDERR "torri-E: failed to locate ti_rri\n"; + print STDERR "ti_w11-E: failed to locate ti_rri\n"; exit 1; } @@ -205,7 +208,7 @@ exit 1; # ---------------------------------------------------------------------------- sub print_usage { - print "usage: torri ...\n"; + print "usage: ti_w11 ...\n"; print " setup options for ghdl simulation runs:\n"; print " -s3 start tb_w11a_s3 simulation\n"; print " -n2 start tb_w11a_n2 simulation\n"; diff --git a/tools/bin/vbomconv b/tools/bin/vbomconv index ac8d9918..20086b9c 100755 --- a/tools/bin/vbomconv +++ b/tools/bin/vbomconv @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# $Id: vbomconv 456 2012-02-05 22:19:44Z mueller $ +# $Id: vbomconv 518 2013-05-12 16:45:02Z mueller $ # # Copyright 2007-2012 by Walter F.J. Mueller # @@ -251,7 +251,7 @@ if (exists $opts{ghdl_i} || exists $opts{ghdl_i_cmd}) { # architecture of at nn( nn) + nn on nn; if (-r "work-obj93.cf") { - open (WFILE, "work-obj93.cf") or + open (WFILE, "work-obj93.cf") or die "can't open for read work-obj93.cf: $!"; while () { if (m{^file \. \"(.*?)\"}) { diff --git a/tools/make/generic_so.mk b/tools/make/generic_so.mk index 8c5ac9ec..18e04976 100644 --- a/tools/make/generic_so.mk +++ b/tools/make/generic_so.mk @@ -1,7 +1,8 @@ -# $Id: generic_so.mk 354 2011-01-09 22:38:53Z mueller $ +# $Id: generic_so.mk 515 2013-05-04 17:28:59Z mueller $ # # Revision History: # Date Rev Version Comment +# 2013-05-03 515 1.0.1 use 'mkdir -p' to prevent aborts with -j 4 # 2011-01-09 354 1.0 Initial version (from wrepo/make/generic_so.mk) #--- # @@ -28,7 +29,7 @@ libs : $(SOPATH)/$(AFILE) $(SOPATH)/$(SOFILEVV) # Build the sharable library # $(SOPATH)/$(SOFILEVV) : $(OBJ_all) - if [ ! -d $(SOPATH) ]; then mkdir $(SOPATH); fi + if [ ! -d $(SOPATH) ]; then mkdir -p $(SOPATH); fi $(CXX) -shared -Wl,-soname,$(SOFILEV) -o $(SOPATH)/$(SOFILEVV) \ $(OBJ_all) $(LDLIBS) (cd $(SOPATH); rm -f $(SOFILE) $(SOFILEV)) @@ -38,6 +39,6 @@ $(SOPATH)/$(SOFILEVV) : $(OBJ_all) # Build an archive # $(SOPATH)/$(AFILE) : $(OBJ_all) - if [ ! -d $(SOPATH) ]; then mkdir $(SOPATH); fi + if [ ! -d $(SOPATH) ]; then mkdir -p $(SOPATH); fi ar -scruv $(SOPATH)/$(AFILE) $? # diff --git a/tools/oskit/211bsd_rk/.cvsignore b/tools/oskit/211bsd_rk/.cvsignore new file mode 100644 index 00000000..d9d13510 --- /dev/null +++ b/tools/oskit/211bsd_rk/.cvsignore @@ -0,0 +1,5 @@ +*.dat +*.dsk +*.log +*license.txt +*license.pdf diff --git a/tools/oskit/211bsd_rk/211bsd_rk_boot.scmd b/tools/oskit/211bsd_rk/211bsd_rk_boot.scmd new file mode 100644 index 00000000..7a87de29 --- /dev/null +++ b/tools/oskit/211bsd_rk/211bsd_rk_boot.scmd @@ -0,0 +1,19 @@ +; $Id: 211bsd_rk_boot.scmd 517 2013-05-09 21:34:45Z mueller $ +; +; Setup file for 211bsd RK based system +; +; Usage: +; +; pdp11 211bsd_rk_boot.scmd +; +do ../../simh/setup_w11a_max.scmd +set tto 7b +set dlo0 7b +; +att rk0 211bsd_rk_root.dsk +att rk1 211bsd_rk_swap.dsk +att rk2 211bsd_rk_tmp.dsk +att rk3 211bsd_rk_bin.dsk +att rk4 211bsd_rk_usr.dsk +; +boo rk0 diff --git a/tools/oskit/211bsd_rk/211bsd_rk_boot.tcl b/tools/oskit/211bsd_rk/211bsd_rk_boot.tcl new file mode 100644 index 00000000..4080b50a --- /dev/null +++ b/tools/oskit/211bsd_rk/211bsd_rk_boot.tcl @@ -0,0 +1,29 @@ +# $Id: 211bsd_rk_boot.tcl 517 2013-05-09 21:34:45Z mueller $ +# +# Setup file for 211bsd RK05 based system +# +# Usage: +# +# telnet_starter -d DL0 & +# telnet_starter -d DL1 & +# ti_w11 -xxx @211bsd_rk_boot.tcl ( -xxx depends on sim or fpga connect) +# + +# setup w11 cpu +puts [rlw] + +# setup tt,lp (211bsd uses parity -> use 7 bit mode) +rw11::setup_tt "cpu0" {to7bit 1} +rw11::setup_lp + +# mount disks +cpu0rka0 att 211bsd_rk_root.dsk +cpu0rka1 att 211bsd_rk_swap.dsk +cpu0rka2 att 211bsd_rk_tmp.dsk +cpu0rka3 att 211bsd_rk_bin.dsk +cpu0rka4 att 211bsd_rk_usr.dsk + +# and boot +rw11::cpumon +rw11::cpucons +cpu0 boot rka0 diff --git a/tools/oskit/211bsd_rk/README_211bsd_rkset.txt b/tools/oskit/211bsd_rk/README_211bsd_rkset.txt new file mode 100644 index 00000000..2dae9276 --- /dev/null +++ b/tools/oskit/211bsd_rk/README_211bsd_rkset.txt @@ -0,0 +1,123 @@ +# $Id: README_211bsd_rkset.txt 518 2013-05-12 16:45:02Z mueller $ + +Notes on oskit: 2.11BSD system on RK05 volumes + + Table of content: + + 1. General remarks + 2. Installation + 3. Usage + +1. General remarks --------------------------------------------------- + + See notes on + + 1. I/O emulation setup + 2. FPGA Board setup + 3. Rlink and Backend Server setup + 4. Legal terms + + in $RETROBASE/doc/w11a_os_guide.txt + +2. Installation ------------------------------------------------------ + + - A disk set is available from + http://www.retro11.de/data/oc_w11/211bsd_rkset.tgz + Download, unpack and copy the disk images (*.dsk), e.g. + + cd $RETROBASE/tools/oskit/211bsd_rk/ + wget http://www.retro11.de/data/oc_w11/211bsd_rkset.tgz + tar -xzf 211bsd_rkset.tgz + +3. Usage ------------------------------------------------------------- + + - Start backend server and boot system (see section 3 in w11a_os_guide.txt) + boot script: 211bsd_rk_boot.tcl + example: ti_w11 -u @211bsd_rk_boot.tcl + + - Hit in the xterm window to connnect to backend server. + The boot dialog in the console xterm window will look like + (required input is in {..}, with {} denoting a carriage return: + + 70Boot from rk(0,0,0) at 0177404 + : {} + : rk(0,0,0)unix + Boot: bootdev=03000 bootcsr=0177404 + + 2.11 BSD UNIX #26: Thu Jan 1 19:49:13 PST 2009 + root@curly.2bsd.com:/usr/src/sys/RETRONFPRK + + phys mem = 3932160 + avail mem = 3577856 + user mem = 307200 + + January 4 16:45:33 init: configure system + + dz ? csr 160100 vector 310 skipped: No CSR. + lp 0 csr 177514 vector 200 attached + rk ? csr 177400 vector 220 didn't interrupt. + rl ? csr 174400 vector 160 skipped: No CSR. + tm ? csr 172520 vector 224 skipped: No CSR. + xp ? csr 176700 vector 254 skipped: No CSR. + cn 1 csr 176500 vector 300 attached + erase, kill ^U, intr ^C + + In first '#' prompt the system is in single-user mode. Just enter a ^D + to continue the system startup to multi-user mode: + + #^D + checking quotas: done. + Assuming non-networking system ... + checking for core dump... + preserving editor files + clearing /tmp + standard daemons: update cron accounting. + starting lpd + starting local daemons:Sun Jan 4 16:46:37 PST 2009 + January 4 16:46:37 init: kernel security level changed from 0 to 1 + January 4 16:46:40 getty: /dev/tty01: Device not configured + ... + + 2.11 BSD UNIX (curly.2bsd.com) (console) + + login: + + The login prompt is sometimes mangled with the 'Device not configured' + system messages, if its not visible just hit to get a fresh one. + + login: {root} + erase, kill ^U, intr ^C + + Now the system is in multi-user mode, daemons runnng. You can explore + the system, e.g. with a 'pstat -T' or a 'mount' command. The second + xterm can be activated too, it will connect to a second emulated DL11. + At the end is important to shutdown properly with a 'halt': + + # {pstat -T} + 7/186 files + 39/208 inodes + 11/150 processes + 6/ 46 texts active, 28 used + 2/135 swapmap entries, 366 kB used, 2069 kB free, 2063 kB max + 33/150 coremap entries, 2960 kB free, 2867 kB max + 1/ 10 ub_map entries, 10 free, 10 max + # {mount} + /dev/rk0h on / + /dev/rk2h on /tmp + /dev/rk3h on /bin + /dev/rk4h on /usr + # {halt} + syncing disks... done + halting + + While the system was running the server process display the + cpumon> + prompt. When the w11 has halted after 211bsd shutdown a message like + + CPU down attention + Processor registers and status: + PS: 030350 cm,pm=k,u s,p,t=0,7,0 NZVC=1000 rust: 01 HALTed + R0: 177560 R1: 161322 R2: 053436 R3: 000010 + R4: 003000 R5: 147510 SP: 147466 PC: 000014 + + will be visible. Now the server process can be stopped with ^D. diff --git a/tools/oskit/rsx11m-31_rk/.cvsignore b/tools/oskit/rsx11m-31_rk/.cvsignore new file mode 100644 index 00000000..19315df3 --- /dev/null +++ b/tools/oskit/rsx11m-31_rk/.cvsignore @@ -0,0 +1,4 @@ +*.dat +*.dsk +*.log +*license.txt diff --git a/tools/oskit/rsx11m-31_rk/README_rsx11m-31_rkset.txt b/tools/oskit/rsx11m-31_rk/README_rsx11m-31_rkset.txt new file mode 100644 index 00000000..2a5e0f70 --- /dev/null +++ b/tools/oskit/rsx11m-31_rk/README_rsx11m-31_rkset.txt @@ -0,0 +1,93 @@ +# $Id: README_rsx11m-31_rkset.txt 518 2013-05-12 16:45:02Z mueller $ + +Notes on oskit: RSX-11M V3.1 system on RK05 volumes + + Table of content: + + 1. General remarks + 2. Installation + 3. Usage + +1. General remarks --------------------------------------------------- + + See notes, especially on legal terms, in $RETROBASE/doc/w11a_os_guide.txt + + Also read README_license.txt !! + +2. Installation ------------------------------------------------------ + + - A disk set is available from + http://www.retro11.de/data/oc_w11/rsx11m-31_rkset.tgz + Download, unpack and copy the disk images (*.dsk), e.g. + + cd $RETROBASE/tools/oskit/rsx11m-31_rk + wget http://www.retro11.de/data/oc_w11/rsx11m-31_rkset.tgz + tar -xzf rsx11m-31_rkset.tgz + +3. Usage ------------------------------------------------------------- + + - Start them in simulator + pdp11 rsx11m-31_rk_boot.scmd + or ONLY IF YOU HAVE A VALID LICENSE on w11a + ti_w11 -u @rsx11m-31_rk_boot.tcl + + - Hit in the xterm window to connect to simh or backend server. + The boot dialog in the console xterm window will look like + (required input is in {..}, with {} denoting a carriage return: + + RSX-11M V3.1 BL22 65408K MAPPED + >RED DK0:=SY0: + >RED DK0:=LB0: + >MOU DK0:SYSTEM0 + >@[1,2]STARTUP + + That RSX shows '65408K' is a bug in V3.1. It should be 1920K' the + size of accessible memory in words. For configurations with 1 MByte + and below the correct value is displayed, above a wrong one. + + This os version was released in December 1977, so it's no suprise + that it is not y2k ready. So enter a date before prior to 2000. + + >* PLEASE ENTER TIME AND DATE (HR:MN DD-MMM-YY) [S]: {<.. see above ..>} + >TIM 17:18 12-may-83 + >; + >RUN ERRLOG + > + ;ERL -- ERROR LOG INITIALIZED + >MOU DK1:SYSTEM1 + >; + >INS DK1:[1,54]BIGMAC/PAR=GEN + >INS DK1:[1,54]BIGTKB/PAR=GEN + >INS DK1:[1,54]CDA + >INS DK1:[1,54]DSC/PAR=GEN + >INS DK1:[1,54]EDT/PAR=GEN + >INS DK1:[1,54]FLX + >INS DK1:[1,54]FOR + >INS DK1:[1,54]FTB + >INS DK1:[1,54]LBR + >INS DK1:[1,54]PSE + >INS DK1:[1,54]RNO + >INS DK1:[1,54]SRD + >INS DK1:[1,54]SYE + >; + >INS DK1:[1,54]TEC + >INS DK1:[1,54]TEC/TASK=...MAK + >INS DK1:[1,54]TEC/TASK=...MUN + >; + >INS DK1:[1,54]VTEC + >; + >; + >SET /UIC=[1,6] + >PSE = + >SET /UIC=[200,200] + >; + >ACS DK1:/BLKS=512. + >; + >@ + > + + Now you are at the MCR prompt and can exercise the system. + + At the end is important to shutdown properly with a 'run $shutup'. + The simululaor (or the rlink backend) can be stopped when the + CPU has halted. diff --git a/tools/oskit/rsx11m-31_rk/rsx11m-31_rk_boot.scmd b/tools/oskit/rsx11m-31_rk/rsx11m-31_rk_boot.scmd new file mode 100644 index 00000000..f7b442aa --- /dev/null +++ b/tools/oskit/rsx11m-31_rk/rsx11m-31_rk_boot.scmd @@ -0,0 +1,15 @@ +; $Id: rsx11m-31_rk_boot.scmd 517 2013-05-09 21:34:45Z mueller $ +; +; Setup file for RSX11-M V3.1 RK05 based system +; +; Usage: +; +; pdp11 rsx11m-31_rk_boot.scmd +; +do ../../simh/setup_w11a_max.scmd +; +att rk0 RSX11M_V3.1_SYSTEM0.dsk +att rk1 RSX11M_V3.1_SYSTEM1.dsk +att rk2 RSX11M_USER.dsk +; +boo rk0 diff --git a/tools/oskit/rsx11m-31_rk/rsx11m-31_rk_boot.tcl b/tools/oskit/rsx11m-31_rk/rsx11m-31_rk_boot.tcl new file mode 100644 index 00000000..f67a608d --- /dev/null +++ b/tools/oskit/rsx11m-31_rk/rsx11m-31_rk_boot.tcl @@ -0,0 +1,28 @@ +# $Id: rsx11m-31_rk_boot.tcl 517 2013-05-09 21:34:45Z mueller $ +# +# Setup file for RSX11-M V3.1 RK05 based system +# +# Usage: +# +# telnet_starter -d DL0 & +# telnet_starter -d DL1 & +# ti_w11 -xxx @rsx11m-31_rk_boot.tcl ( -xxx depends on sim or fpga connect) +# + +# setup w11 cpu +puts [rlw] + +# setup tt,lp,pp (enable rx rate limiter on old DEC OS) +rw11::setup_tt "cpu0" {dlrlim 5} +rw11::setup_lp +rw11::setup_pp + +# mount disks +cpu0rka0 att RSX11M_V3.1_SYSTEM0.dsk +cpu0rka1 att RSX11M_V3.1_SYSTEM1.dsk +cpu0rka2 att RSX11M_USER.dsk + +# and boot +rw11::cpumon +rw11::cpucons +cpu0 boot rka0 diff --git a/tools/oskit/rsx11m-40_rk/.cvsignore b/tools/oskit/rsx11m-40_rk/.cvsignore new file mode 100644 index 00000000..19315df3 --- /dev/null +++ b/tools/oskit/rsx11m-40_rk/.cvsignore @@ -0,0 +1,4 @@ +*.dat +*.dsk +*.log +*license.txt diff --git a/tools/oskit/rsx11m-40_rk/README_rsx11m-40_rkset.txt b/tools/oskit/rsx11m-40_rk/README_rsx11m-40_rkset.txt new file mode 100644 index 00000000..7327199b --- /dev/null +++ b/tools/oskit/rsx11m-40_rk/README_rsx11m-40_rkset.txt @@ -0,0 +1,83 @@ +# $Id: README_rsx11m-40_rkset.txt 518 2013-05-12 16:45:02Z mueller $ + +Notes on oskit: RSX-11M V4.0 system on RK05 volumes + + Table of content: + + 1. General remarks + 2. Installation + 3. Usage + +1. General remarks --------------------------------------------------- + + See notes, especially on legal terms, in $RETROBASE/doc/w11a_os_guide.txt + + Also read README_license.txt !! + +2. Installation ------------------------------------------------------ + + - A disk set is available from + http://www.retro11.de/data/oc_w11/rsx11m-40_rkset.tgz + Download, unpack and copy the disk images (*.dsk), e.g. + + cd $RETROBASE/tools/oskit/rsx11m-40_rk + wget http://www.retro11.de/data/oc_w11/rsx11m-40_rkset.tgz + tar -xzf rsx11m-40_rkset.tgz + +3. Usage ------------------------------------------------------------- + + - Start them in simulator + pdp11 rsx11m-40_rk_boot.scmd + or ONLY IF YOU HAVE A VALID LICENSE on w11a + ti_w11 -u @rsx11m-40_rk_boot.tcl + + - Hit in the xterm window to connect to simh or backend server. + The boot dialog in the console xterm window will look like + (required input is in {..}, with {} denoting a carriage return: + + RSX-11M V4.0 BL32 1920.K MAPPED + >RED DK:=SY: + >RED DK:=LB: + >MOU DK:SYSM40RKV0 + >@DK:[1,2]STARTUP + + This os version was released in November 1981, so it's no suprise + that it is not y2k ready. So enter a date before prior to 2000. + + >* PLEASE ENTER TIME AND DATE (HR:MN DD-MMM-YY) [S]: {<.. see above ..>} + >TIM 18:17 12-may-83 + >* ENTER LINE WIDTH OF THIS TERMINAL [D D:132.]: {} + >SET /BUF=TI:132. + >ACS SY:/BLKS=512. + >CLI /INIT=DCL/TASK=...DCL + >; + >; mount 2nd system disk + >; + >mou dk1:SYSM40RKV1/pub + >; + >; installing tasks from 2nd system disk + >; + >INS DK1:$BRU + >INS DK1:$DMP + >INS DK1:$DSC + >INS DK1:$EDT + >INS DK1:$FLX + >INS DK1:$K11RSX/TASK=...KER + >INS DK1:$LBR + >INS DK1:$MAC + >INS DK1:$RMD + >INS DK1:$SLP + >INS DK1:$SRD + >INS DK1:$TEC + >INS DK1:$TEC/TASK=...MAK + >INS DK1:$TKB + >INS DK1:$VFY + >INS DK1:$VTEC + >@ + > + + Now you are at the MCR prompt and can exercise the system. + + At end is important to shutdown properly with a 'run $shutup'. + The simululaor (or the rlink backend) can be stopped when the + CPU has halted. diff --git a/tools/oskit/rsx11m-40_rk/rsx11m-40_rk_boot.scmd b/tools/oskit/rsx11m-40_rk/rsx11m-40_rk_boot.scmd new file mode 100644 index 00000000..b8e3b93c --- /dev/null +++ b/tools/oskit/rsx11m-40_rk/rsx11m-40_rk_boot.scmd @@ -0,0 +1,15 @@ +; $Id: $ +; +; Setup file for RSX11-M V4.0 RK05 based system +; +; Usage: +; +; pdp11 rsx11m-40_rk_boot.scmd +; +do ../../simh/setup_w11a_max.scmd +; +att rk0 RSX11M_V4.0_SYSTEM0.dsk +att rk1 RSX11M_V4.0_SYSTEM1.dsk +att rk2 RSX11M_USER.dsk +; +boo rk0 diff --git a/tools/oskit/rsx11m-40_rk/rsx11m-40_rk_boot.tcl b/tools/oskit/rsx11m-40_rk/rsx11m-40_rk_boot.tcl new file mode 100644 index 00000000..f286920c --- /dev/null +++ b/tools/oskit/rsx11m-40_rk/rsx11m-40_rk_boot.tcl @@ -0,0 +1,28 @@ +# $Id: $ +# +# Setup file for RSX11-M V4.0 RK05 based system +# +# Usage: +# +# telnet_starter -d DL0 & +# telnet_starter -d DL1 & +# ti_w11 -xxx @rsx11m-40_rk_boot.tcl ( -xxx depends on sim or fpga connect) +# + +# setup w11 cpu +puts [rlw] + +# setup tt,lp,pp (enable rx rate limiter on old DEC OS) +rw11::setup_tt "cpu0" {dlrlim 5} +rw11::setup_lp +rw11::setup_pp + +# mount disks +cpu0rka0 att RSX11M_V4.0_SYSTEM0.dsk +cpu0rka1 att RSX11M_V4.0_SYSTEM1.dsk +cpu0rka2 att RSX11M_USER.dsk + +# and boot +rw11::cpumon +rw11::cpucons +cpu0 boot rka0 diff --git a/tools/oskit/rt11-40_rk/.cvsignore b/tools/oskit/rt11-40_rk/.cvsignore new file mode 100644 index 00000000..19315df3 --- /dev/null +++ b/tools/oskit/rt11-40_rk/.cvsignore @@ -0,0 +1,4 @@ +*.dat +*.dsk +*.log +*license.txt diff --git a/tools/oskit/rt11-40_rk/README_rt11-40_rkset.txt b/tools/oskit/rt11-40_rk/README_rt11-40_rkset.txt new file mode 100644 index 00000000..a475839c --- /dev/null +++ b/tools/oskit/rt11-40_rk/README_rt11-40_rkset.txt @@ -0,0 +1,61 @@ +# $Id: $ + +Notes on oskit: RT-11 V4.0 system on RK05 volumes + + Table of content: + + 1. General remarks + 2. Installation + 3. Usage + +1. General remarks --------------------------------------------------- + + See notes, especially on legal terms, in $RETROBASE/doc/w11a_os_guide.txt + + Also read README_license.txt !! + +2. Installation ------------------------------------------------------ + + - A disk set is available from + http://www.retro11.de/data/oc_w11/rsx11m-31_rkset.tgz + Download, unpack and copy the disk images (*.dsk), e.g. + + cd $RETROBASE/tools/oskit/rt11-40_rk + wget http://www.retro11.de/data/oc_w11/rt11-40_rkset.tgz + tar -xzf rt11-40_rkset.tgz + +3. Usage ------------------------------------------------------------- + + - Start them in simulator + pdp11 rt11-40_rk_boot.scmd + or ONLY IF YOU HAVE A VALID LICENSE on w11a + ti_w11 -u @rt11-40_rk_boot.tcl + + - Hit in the xterm window to connect to simh or backend server. + The boot dialog in the console xterm window will look like + (required input is in {..}, with {} denoting a carriage return: + + RT-11SJ V04.00C + + .D 56=5015 + + .TYPE V4USER.TXT + Welcome to RT-11 Version 4. RT-11 V04 provides new hardware support + and some major enhancements over Version 3B. + + Please use the HELP command; it describes the new options in many + of the utilities. + + If you are using a terminal that requires fill characters, + modify location 56 with a Deposit command before proceeding with + system installation. LA36 DECwriter II and VT52 DECscope terminals + do NOT require such modification. + + .D 56=0 + + . + + Now you are at the RT-11 prompt and can exercise the system. + + There is no 'halt' or 'shutdown' command, just terminate the + simulator or backend server session. diff --git a/tools/oskit/rt11-40_rk/rt11-40_rk_boot.scmd b/tools/oskit/rt11-40_rk/rt11-40_rk_boot.scmd new file mode 100644 index 00000000..10ec633e --- /dev/null +++ b/tools/oskit/rt11-40_rk/rt11-40_rk_boot.scmd @@ -0,0 +1,13 @@ +; $Id: rt11-40_rk_boot.scmd 517 2013-05-09 21:34:45Z mueller $ +; +; Setup file for RT-11 V4.0 RK05 based system +; +; Usage: +; +; pdp11 rt11-40_rk_boot.scmd +; +do ../../simh/setup_w11a_min.scmd +; +att rk0 rtv4_rk.dsk +; +boo rk0 diff --git a/tools/oskit/rt11-40_rk/rt11-40_rk_boot.tcl b/tools/oskit/rt11-40_rk/rt11-40_rk_boot.tcl new file mode 100644 index 00000000..5344eb7f --- /dev/null +++ b/tools/oskit/rt11-40_rk/rt11-40_rk_boot.tcl @@ -0,0 +1,25 @@ +# $Id: rt11-40_rk_boot.tcl 517 2013-05-09 21:34:45Z mueller $ +# +# Setup file for RT-11 V4.0 RK05 based system +# +# Usage: +# +# telnet_starter -d DL0 & +# ti_w11 -xxx @rt11-40_rk_boot.tcl ( -xxx depends on sim or fpga connect) +# + +# setup w11 cpu +puts [rlw] + +# setup tt,lp,pp (single console; enable rx rate limiter on old DEC OS) +rw11::setup_tt "cpu0" {ndl 1 dlrlim 5} +rw11::setup_lp +rw11::setup_pp + +# mount disks +cpu0rka0 att rtv4_rk.dsk + +# and boot +rw11::cpumon +rw11::cpucons +cpu0 boot rka0 diff --git a/tools/oskit/unix-v5_rk/.cvsignore b/tools/oskit/unix-v5_rk/.cvsignore new file mode 100644 index 00000000..d9d13510 --- /dev/null +++ b/tools/oskit/unix-v5_rk/.cvsignore @@ -0,0 +1,5 @@ +*.dat +*.dsk +*.log +*license.txt +*license.pdf diff --git a/tools/oskit/unix-v5_rk/README_unix_v5_rkset.txt b/tools/oskit/unix-v5_rk/README_unix_v5_rkset.txt new file mode 100644 index 00000000..fd00f09a --- /dev/null +++ b/tools/oskit/unix-v5_rk/README_unix_v5_rkset.txt @@ -0,0 +1,64 @@ +# $Id: README_unix_v5_rkset.txt 518 2013-05-12 16:45:02Z mueller $ + +Notes on oskit: Unix V5 system on RK05 volumes + + Table of content: + + 1. General remarks + 2. Installation + 3. Usage + +1. General remarks --------------------------------------------------- + + See notes on + + 1. I/O emulation setup + 2. FPGA Board setup + 3. Rlink and Backend Server setup + 4. Legal terms + + in $RETROBASE/doc/w11a_os_guide.txt + +2. Installation ------------------------------------------------------ + + - A disk set is available from + http://www.retro11.de/data/oc_w11/unix_v5_rkset.tgz + Download, unpack and copy the disk images (*.dsk), e.g. + + cd $RETROBASE/tools/oskit/unix-v5_rk + wget http://www.retro11.de/data/oc_w11/unix_v5_rkset.tgz + tar -xzf unix_v5_rkset.tgz + +3. Usage ------------------------------------------------------------- + + - Start backend server and boot system (see section 3 in w11a_os_guide.txt) + boot script: uv5_rk_boot.tcl + example: ti_w11 -u @uv5_rk_boot.tcl + + - Hit in the xterm window to connect to backend server. + The boot dialog in the console xterm window will look like + (required input is in {..}, with {} denoting a carriage return: + + @{unix} + + login: {root} + + Now you are at the shell prompt and can exercise the system, e.g. + + # {ls -al} + total 62 + drwxr-xr-x 9 bin 160 Jan 29 16:14 . + drwxr-xr-x 9 bin 160 Jan 29 16:14 .. + drwxr-xr-x 2 bin 944 Nov 26 18:13 bin + drwxr-xr-x 2 bin 80 Nov 26 18:13 dev + drwxr-xr-x 2 bin 240 Mar 21 12:07 etc + drwxr-xr-x 2 bin 224 Nov 26 18:13 lib + drwxr-xr-x 2 bin 32 Nov 26 18:13 mnt + drwxrwxrwx 2 bin 32 Nov 26 18:13 tmp + -rwxrwxrwx 1 bin 25802 Mar 21 12:07 unix + drwxr-xr-x 14 bin 224 Nov 26 18:13 usr + + There is no 'halt' or 'shutdown' command, just terminate the server + session with a + tirri_exit + command. The disks aren't cached, so no need to sync either. diff --git a/tools/oskit/unix-v5_rk/uv5_rk_boot.scmd b/tools/oskit/unix-v5_rk/uv5_rk_boot.scmd new file mode 100644 index 00000000..8eb01fcc --- /dev/null +++ b/tools/oskit/unix-v5_rk/uv5_rk_boot.scmd @@ -0,0 +1,15 @@ +; $Id: uv5_rk_boot.scmd 517 2013-05-09 21:34:45Z mueller $ +; +; Setup file for Unix V5 RK05 based system +; +; Usage: +; +; pdp11 uv5_rk_boot.scmd +; +do ../../simh/setup_w11a_min.scmd +set tto 7b +set dlo0 7b +; +att rk0 unix_v5_rk.dsk +; +boo rk0 diff --git a/tools/oskit/unix-v5_rk/uv5_rk_boot.tcl b/tools/oskit/unix-v5_rk/uv5_rk_boot.tcl new file mode 100644 index 00000000..82156d02 --- /dev/null +++ b/tools/oskit/unix-v5_rk/uv5_rk_boot.tcl @@ -0,0 +1,23 @@ +# $Id: uv5_rk_boot.tcl 517 2013-05-09 21:34:45Z mueller $ +# +# Setup file for Unix V5 RK05 based system +# +# Usage: +# +# telnet_starter -d DL0 & +# ti_w11 -xxx @uv5_boot.tcl ( -xxx depends on sim or fpga connect) + +# setup w11 cpu +puts [rlw] + +# setup tt,lp (uses only 1 console; uses parity -> use 7 bit mode) +rw11::setup_tt "cpu0" {ndl 1 to7bit 1} +rw11::setup_lp + +# mount disks +cpu0rka0 att unix_v5_rk.dsk + +# and boot +rw11::cpumon +rw11::cpucons +cpu0 boot rka0 diff --git a/tools/simh/setup_w11a_max.scmd b/tools/simh/setup_w11a_max.scmd new file mode 100644 index 00000000..26d8df48 --- /dev/null +++ b/tools/simh/setup_w11a_max.scmd @@ -0,0 +1,97 @@ +; $Id: setup_w11a_max.scmd 518 2013-05-12 16:45:02Z mueller $ +; +; Setup file for 'maximal' w11a configuration under simh 3.8 and above +; +; This setup reflects the planned w11a system on a Nexys[234] board +; --> 4 MByte, 2 DL11, DZ+LP+PC, RK05+RL02+RP06+TM11, DEUNA +; +; 11/70 CPU no FPP, 1 MByte memory +; 2 DL11 +; 1 DZ11 +; 1 LP11 +; 1 PC11 +; 1 RK11 + 8 RK05 drives +; 1 RL11 + 4 RL01/02 drives +; 1 RH70 + 4 RP06 drives +; 1 TM11 + 4 drives +; 1 DEUNA +; +; processor options +; +set cpu 11/70 +set cpu nofpp +set cpu 4m +set cpu oct +set cpu idle +; +; clock options +; +set clk 50hz +; +; terminal interface options +; the default tti time=0 setting gives 50 chars/sec, slow +; setting time=50000 (means 1 char every 50000 instructions) is much +; faster and seems still save for old DEC OS like XXDP, RT-11, RXS11-M +; +set cons log=simh_dl0.log +dep tti time 50000 +set tto 8b +; +; 2nd DL11 interface options +; Note: set dli vector=300 not allowed, rely on autoconf to set vec->300 +; Note: default for DLO's is UC ! -> set to 8bit +; +set dli enabled +set dli lines=1 +att dli 5670 +set dlo0 log=simh_dl1.log +set dlo0 8b +; +set dz enabled +set dz lines=8 +set dz vector=310 +att dz -m 5671 +set dz log=0=simh_dz0.log +set dz log=1=simh_dz1.log +set dz log=2=simh_dz2.log +; dz log file names must be quoted, otherwise they'll be uppercased ! +; +; line printer +; +set lpt enabled +att lpt simh_lpt.dat +; +; paper tape read/punch +; +set ptr enabled +set ptp enabled +att ptp simh_ptp.dat +; +; disk drives +; +set rk enabled +; +set rl enabled +; +set rha enabled +set rp enabled +; +; tape drives +; +set tm enabled +; +; ethernet interfaces +; +set xu enabled +; +; DISABLE all else +; +set cr disabled +set vh disabled +set hk disabled +set rx disabled +set rq disabled +set tq disabled +; +;sho conf +; diff --git a/tools/simh/setup_w11a_min.scmd b/tools/simh/setup_w11a_min.scmd new file mode 100644 index 00000000..1c508d3f --- /dev/null +++ b/tools/simh/setup_w11a_min.scmd @@ -0,0 +1,85 @@ +; $Id: setup_w11a_min.scmd 518 2013-05-12 16:45:02Z mueller $ +; +; Setup file for 'minimal' w11a configuration under simh 3.8 and above +; +; This setup reflects the current w11a system on a S3BOARD +; --> 1MByte, 2 DL11, LP+PC, RK05 +; +; 11/70 CPU no FPP, 1 MByte memory +; 2 DL11 +; 0 DZ11 +; 1 LP11 +; 1 PC11 +; 1 RK11 + 8 RK05 drives +; 0 RL11 + 0 RL01/02 drives +; 0 RH70 + 0 RP06 drives +; 0 TM11 + 0 drives +; 0 DEUNA +; +; processor options +; +set cpu 11/70 +set cpu nofpp +set cpu 1m +set cpu oct +set cpu idle +; +; clock options +; +set clk 50hz +; +; terminal interface options +; the default tti time=0 setting gives 50 chars/sec, slow +; setting time=50000 (means 1 char every 50000 instructions) is much +; faster and seems still save for old DEC OS like XXDP, RT-11, RXS11-M +; +set cons log=simh_dl0.log +dep tti time 50000 +set tto 8b +; +; 2nd DL11 interface options +; Note: set dli vector=300 not allowed, rely on autoconf to set vec->300 +; Note: default for DLO's is UC ! -> set to 8bit +; +set dli enabled +set dli lines=1 +att dli 5670 +set dlo0 log=simh_dl1.log +set dlo0 8b +; +; line printer +; +set lpt enabled +att lpt simh_lpt.dat +; +; paper tape read/punch +; +set ptr enabled +set ptp enabled +att ptp simh_ptp.dat +; +; disk drives +; +set rk enabled +; +; tape drives (none) +; ethernet interfaces (none) +; +; DISABLE all else +; +set dz disabled +set rl disabled +set rha disabled +set rp disabled +set tm disabled +set xu disabled +; +set cr disabled +set vh disabled +set hk disabled +set rx disabled +set rq disabled +set tq disabled +; +;sho conf +; diff --git a/tools/src/librlink/ReventLoop.hpp b/tools/src/librlink/ReventLoop.hpp index bed26dcd..ee986dcf 100644 --- a/tools/src/librlink/ReventLoop.hpp +++ b/tools/src/librlink/ReventLoop.hpp @@ -1,4 +1,4 @@ -// $Id: ReventLoop.hpp 494 2013-03-03 21:50:07Z mueller $ +// $Id: ReventLoop.hpp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.1.1 fTraceLevel now uint32_t // 2013-02-22 491 1.1 use new RlogFile/RlogMsg interfaces // 2013-01-11 473 1.0 Initial version // --------------------------------------------------------------------------- @@ -20,7 +21,7 @@ /*! \file - \version $Id: ReventLoop.hpp 494 2013-03-03 21:50:07Z mueller $ + \version $Id: ReventLoop.hpp 513 2013-05-01 14:02:06Z mueller $ \brief Declaration of class \c ReventLoop. */ @@ -55,8 +56,8 @@ namespace Retro { void RemovePollHandler(int fd); void SetLogFile(const boost::shared_ptr& splog); - void SetTraceLevel(size_t level); - size_t TraceLevel() const; + void SetTraceLevel(uint32_t level); + uint32_t TraceLevel() const; void Stop(); virtual void EventLoop(); @@ -84,7 +85,7 @@ namespace Retro { std::vector fPollDsc; std::vector fPollFd; std::vector fPollHdl; - size_t fTraceLevel; //!< trace level + uint32_t fTraceLevel; //!< trace level boost::shared_ptr fspLog; //!< log file ptr }; diff --git a/tools/src/librlink/ReventLoop.ipp b/tools/src/librlink/ReventLoop.ipp index 7edb87e3..cf48c6e1 100644 --- a/tools/src/librlink/ReventLoop.ipp +++ b/tools/src/librlink/ReventLoop.ipp @@ -1,4 +1,4 @@ -// $Id: ReventLoop.ipp 491 2013-02-23 12:41:18Z mueller $ +// $Id: ReventLoop.ipp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.1.1 fTraceLevel now uint32_t // 2013-02-22 491 1.1 use new RlogFile/RlogMsg interfaces // 2013-01-11 473 1.0 Initial version // --------------------------------------------------------------------------- /*! \file - \version $Id: ReventLoop.ipp 491 2013-02-23 12:41:18Z mueller $ + \version $Id: ReventLoop.ipp 513 2013-05-01 14:02:06Z mueller $ \brief Implemenation (inline) of class ReventLoop. */ @@ -47,7 +48,7 @@ inline void ReventLoop::SetLogFile(const boost::shared_ptr& splog) //------------------------------------------+----------------------------------- //! FIXME_docs -inline void ReventLoop::SetTraceLevel(size_t level) +inline void ReventLoop::SetTraceLevel(uint32_t level) { fTraceLevel = level; return; @@ -56,7 +57,7 @@ inline void ReventLoop::SetTraceLevel(size_t level) //------------------------------------------+----------------------------------- //! FIXME_docs -inline size_t ReventLoop::TraceLevel() const +inline uint32_t ReventLoop::TraceLevel() const { return fTraceLevel; } diff --git a/tools/src/librlink/RlinkPort.hpp b/tools/src/librlink/RlinkPort.hpp index c208b0ed..bf4f4dd4 100644 --- a/tools/src/librlink/RlinkPort.hpp +++ b/tools/src/librlink/RlinkPort.hpp @@ -1,4 +1,4 @@ -// $Id: RlinkPort.hpp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RlinkPort.hpp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2011-2013 by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.2.1 fTraceLevel now uint32_t // 2013-02-23 492 1.2 use RparseUrl // 2013-02-22 491 1.1 use new RlogFile/RlogMsg interfaces // 2013-01-27 477 1.0.3 add RawRead(),RawWrite() methods @@ -25,7 +26,7 @@ /*! \file - \version $Id: RlinkPort.hpp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RlinkPort.hpp 513 2013-05-01 14:02:06Z mueller $ \brief Declaration of class RlinkPort. */ @@ -69,8 +70,8 @@ namespace Retro { int FdWrite() const; void SetLogFile(const boost::shared_ptr& splog); - void SetTraceLevel(size_t level); - size_t TraceLevel() const; + void SetTraceLevel(uint32_t level); + uint32_t TraceLevel() const; const Rstats& Stats() const; @@ -101,7 +102,7 @@ namespace Retro { int fFdRead; //!< fd for read int fFdWrite; //!< fd for write boost::shared_ptr fspLog; //!< log file ptr - size_t fTraceLevel; //!< trace level + uint32_t fTraceLevel; //!< trace level Rstats fStats; //!< statistics }; diff --git a/tools/src/librlink/RlinkPort.ipp b/tools/src/librlink/RlinkPort.ipp index 93e29613..6e282915 100644 --- a/tools/src/librlink/RlinkPort.ipp +++ b/tools/src/librlink/RlinkPort.ipp @@ -1,4 +1,4 @@ -// $Id: RlinkPort.ipp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RlinkPort.ipp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2011-2013 by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.2.1 fTraceLevel now uint32_t // 2013-02-23 492 1.2 use RparseUrl // 2013-02-22 491 1.1 use new RlogFile/RlogMsg interfaces // 2011-03-27 375 1.0 Initial version @@ -21,7 +22,7 @@ /*! \file - \version $Id: RlinkPort.ipp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RlinkPort.ipp 513 2013-05-01 14:02:06Z mueller $ \brief Implemenation (inline) of RlinkPort. */ @@ -72,7 +73,7 @@ inline void RlinkPort::SetLogFile(const boost::shared_ptr& splog) //------------------------------------------+----------------------------------- //! FIXME_docs -inline void RlinkPort::SetTraceLevel(size_t level) +inline void RlinkPort::SetTraceLevel(uint32_t level) { fTraceLevel = level; return; @@ -81,7 +82,7 @@ inline void RlinkPort::SetTraceLevel(size_t level) //------------------------------------------+----------------------------------- //! FIXME_docs -inline size_t RlinkPort::TraceLevel() const +inline uint32_t RlinkPort::TraceLevel() const { return fTraceLevel; } diff --git a/tools/src/librlink/RlinkPortCuff.cpp b/tools/src/librlink/RlinkPortCuff.cpp index c9ab92de..e507b1a4 100644 --- a/tools/src/librlink/RlinkPortCuff.cpp +++ b/tools/src/librlink/RlinkPortCuff.cpp @@ -1,4 +1,4 @@ -// $Id: RlinkPortCuff.cpp 504 2013-04-13 15:37:24Z mueller $ +// $Id: RlinkPortCuff.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2012-2013 by Walter F.J. Mueller // @@ -22,7 +22,7 @@ /*! \file - \version $Id: RlinkPortCuff.cpp 504 2013-04-13 15:37:24Z mueller $ + \version $Id: RlinkPortCuff.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of RlinkPortCuff. */ @@ -126,10 +126,10 @@ bool RlinkPortCuff::Open(const std::string& url, RerrMsg& emsg) char* env_pid = ::getenv("RETRO_FX2_PID"); if (env_vid && ::strlen(env_vid) == 4 && env_pid && ::strlen(env_pid) == 4) { - fUrl.SetPath(string(env_vid) + string(":") + string(env_pid)); + fUrl.SetPath(string(env_vid) + ":" + string(env_pid)); } else { emsg.Init("RlinkPortCuff::Open()", - string("RETRO_FX2_VID/PID not or ill defined")); + "RETRO_FX2_VID/PID not or ill defined"); Cleanup(); return false; } @@ -302,9 +302,7 @@ bool RlinkPortCuff::OpenPipe(int& fdread, int& fdwrite, RerrMsg& emsg) irc = ::pipe(pipefd); if (irc < 0) { - emsg.InitErrno("RlinkPortCuff::OpenPipe()", - string("pipe() failed: "), - errno); + emsg.InitErrno("RlinkPortCuff::OpenPipe()", "pipe() failed: ", errno); return false; } @@ -501,7 +499,7 @@ void RlinkPortCuff::BadSysCall(const char* meth, const char* text, int rc) { stringstream ss; ss << rc; - throw Rexception(meth, string(text)+string(" failed with rc=")+ss.str(), + throw Rexception(meth, string(text) + " failed with rc=" + ss.str(), errno); } @@ -512,8 +510,8 @@ void RlinkPortCuff::BadUSBCall(const char* meth, const char* text, int rc) { stringstream ss; ss << rc; - throw Rexception(meth, string(text)+string(" failed with rc=")+ss.str()+ - string(" : ")+string(USBErrorName(rc))); + throw Rexception(meth, string(text) + " failed with rc=" + ss.str() + + " : " + string(USBErrorName(rc))); } //------------------------------------------+----------------------------------- diff --git a/tools/src/librlink/RlinkPortFactory.cpp b/tools/src/librlink/RlinkPortFactory.cpp index 0a44af81..b94abc3a 100644 --- a/tools/src/librlink/RlinkPortFactory.cpp +++ b/tools/src/librlink/RlinkPortFactory.cpp @@ -1,4 +1,4 @@ -// $Id: RlinkPortFactory.cpp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RlinkPortFactory.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2011-2013 by Walter F.J. Mueller // @@ -21,7 +21,7 @@ /*! \file - \version $Id: RlinkPortFactory.cpp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RlinkPortFactory.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of RlinkPortFactory. */ @@ -52,7 +52,7 @@ RlinkPort* Retro::RlinkPortFactory::New(const std::string& url, RerrMsg& emsg) if (scheme.length() == 0) { emsg.Init("RlinkPortFactory::New()", - string("no scheme specified in url '" + url + string("'"))); + string("no scheme specified in url '" + url + "'")); return 0; } diff --git a/tools/src/librlink/RlinkPortFifo.cpp b/tools/src/librlink/RlinkPortFifo.cpp index 7f26b448..25915994 100644 --- a/tools/src/librlink/RlinkPortFifo.cpp +++ b/tools/src/librlink/RlinkPortFifo.cpp @@ -1,4 +1,4 @@ -// $Id: RlinkPortFifo.cpp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RlinkPortFifo.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2011-2013 y Walter F.J. Mueller // @@ -20,7 +20,7 @@ /*! \file - \version $Id: RlinkPortFifo.cpp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RlinkPortFifo.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of RlinkPortFifo. */ @@ -97,7 +97,7 @@ int RlinkPortFifo::OpenFifo(const std::string& name, bool snd, RerrMsg& emsg) if (irc == 0) { if ((stat_fifo.st_mode & S_IFIFO) == 0) { emsg.Init("RlinkPortFifo::OpenFiFo()", - string("'") + name + string("' exists but is not a pipe")); + string("'") + name + "' exists but is not a pipe"); return -1; } } else { @@ -105,7 +105,7 @@ int RlinkPortFifo::OpenFifo(const std::string& name, bool snd, RerrMsg& emsg) irc = mkfifo(name.c_str(), mode); if (irc != 0) { emsg.InitErrno("RlinkPortFifo::OpenFifo()", - string("mkfifo() for '") + name + string("' failed: "), + string("mkfifo() for '") + name + "' failed: ", errno); return -1; } @@ -114,7 +114,7 @@ int RlinkPortFifo::OpenFifo(const std::string& name, bool snd, RerrMsg& emsg) irc = open(name.c_str(), snd ? O_WRONLY : O_RDONLY); if (irc < 0) { emsg.InitErrno("RlinkPortFifo::OpenFifo()", - string("open() for '") + name + string("' failed: "), + string("open() for '") + name + "' failed: ", errno); return -1; } diff --git a/tools/src/librlink/RlinkPortTerm.cpp b/tools/src/librlink/RlinkPortTerm.cpp index 71a5ca66..7ba6dafb 100644 --- a/tools/src/librlink/RlinkPortTerm.cpp +++ b/tools/src/librlink/RlinkPortTerm.cpp @@ -1,4 +1,4 @@ -// $Id: RlinkPortTerm.cpp 494 2013-03-03 21:50:07Z mueller $ +// $Id: RlinkPortTerm.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2011-2013 by Walter F.J. Mueller // @@ -25,7 +25,7 @@ /*! \file - \version $Id: RlinkPortTerm.cpp 494 2013-03-03 21:50:07Z mueller $ + \version $Id: RlinkPortTerm.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of RlinkPortTerm. */ @@ -114,7 +114,7 @@ bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg) if (baud=="4000000" || baud=="4000k" || baud=="4M") speed = B4000000; if (speed == B0) { emsg.Init("RlinkPortTerm::Open()", - string("invalid baud rate '") + baud + string("' specified")); + string("invalid baud rate '") + baud + "' specified"); return false; } } @@ -124,23 +124,22 @@ bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg) fd = open(fUrl.Path().c_str(), O_RDWR|O_NOCTTY); if (fd < 0) { emsg.InitErrno("RlinkPortTerm::Open()", - string("open() for '") + fUrl.Path() + string("' failed: "), + string("open() for '") + fUrl.Path() + "' failed: ", errno); return false; } if (!isatty(fd)) { emsg.Init("RlinkPortTerm::Open()", - string("isatty() check for '") + fUrl.Path() + - string("' failed: not a TTY")); + string("isatty() check for '") + fUrl.Path() + + "' failed: not a TTY"); close(fd); return false; } if (tcgetattr(fd, &fTiosOld) != 0) { emsg.InitErrno("RlinkPortTerm::Open()", - string("tcgetattr() for '") + fUrl.Path() + - string("' failed: "), + string("tcgetattr() for '") + fUrl.Path() + "' failed: ", errno); close(fd); return false; @@ -174,7 +173,7 @@ bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg) if (cfsetspeed(&fTiosNew, speed) != 0) { emsg.InitErrno("RlinkPortTerm::Open()", - string("cfsetspeed() for '") + baud + string("' failed: "), + string("cfsetspeed() for '") + baud + "' failed: ", errno); close(fd); return false; @@ -198,8 +197,7 @@ bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg) if (tcsetattr(fd, TCSANOW, &fTiosNew) != 0) { emsg.InitErrno("RlinkPortTerm::Open()", - string("tcsetattr() for '") + fUrl.Path() + - string("' failed: "), + string("tcsetattr() for '") + fUrl.Path() + "' failed: ", errno); close(fd); return false; @@ -212,9 +210,8 @@ bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg) struct termios tios; if (tcgetattr(fd, &tios) != 0) { emsg.InitErrno("RlinkPortTerm::Open()", - string("2nd tcgetattr() for '") + fUrl.Path() + - string("' failed: "), - errno); + string("2nd tcgetattr() for '") + fUrl.Path() + + "' failed: ", errno); close(fd); return false; } @@ -232,8 +229,7 @@ bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg) if (pmsg) { emsg.Init("RlinkPortTerm::Open()", - string("tcsetattr() failed to set") + - string(pmsg)); + string("tcsetattr() failed to set") + string(pmsg)); close(fd); return false; } @@ -246,7 +242,7 @@ bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg) if (tcsendbreak(fd, 0) != 0) { emsg.InitErrno("RlinkPortTerm::Open()", string("tcsendbreak() for '") + fUrl.Path() + - string("' failed: "), errno); + "' failed: ", errno); Close(); return false; } diff --git a/tools/src/librlink/RlinkServer.cpp b/tools/src/librlink/RlinkServer.cpp index c02f76a1..06250c23 100644 --- a/tools/src/librlink/RlinkServer.cpp +++ b/tools/src/librlink/RlinkServer.cpp @@ -1,4 +1,4 @@ -// $Id: RlinkServer.cpp 509 2013-04-21 20:46:20Z mueller $ +// $Id: RlinkServer.cpp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.0.2 fTraceLevel now uint32_t // 2013-04-21 509 1.0.1 add Resume(), reorganize server start handling // 2013-03-06 495 1.0 Initial version // 2013-01-12 474 0.5 First draft @@ -20,7 +21,7 @@ /*! \file - \version $Id: RlinkServer.cpp 509 2013-04-21 20:46:20Z mueller $ + \version $Id: RlinkServer.cpp 513 2013-05-01 14:02:06Z mueller $ \brief Implemenation of RlinkServer. */ @@ -295,7 +296,7 @@ bool RlinkServer::IsActiveOutside() const //------------------------------------------+----------------------------------- //! FIXME_docs -void RlinkServer::SetTraceLevel(size_t level) +void RlinkServer::SetTraceLevel(uint32_t level) { fTraceLevel = level; fELoop.SetTraceLevel(level); diff --git a/tools/src/librlink/RlinkServer.hpp b/tools/src/librlink/RlinkServer.hpp index 43147843..a6a6d8c0 100644 --- a/tools/src/librlink/RlinkServer.hpp +++ b/tools/src/librlink/RlinkServer.hpp @@ -1,4 +1,4 @@ -// $Id: RlinkServer.hpp 509 2013-04-21 20:46:20Z mueller $ +// $Id: RlinkServer.hpp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.0.2 fTraceLevel now uint32_t // 2013-04-21 509 1.0.1 add Resume(), reorganize server start handling // 2013-03-06 495 1.0 Initial version // 2013-01-12 474 0.5 First draft @@ -20,7 +21,7 @@ /*! \file - \version $Id: RlinkServer.hpp 509 2013-04-21 20:46:20Z mueller $ + \version $Id: RlinkServer.hpp 513 2013-05-01 14:02:06Z mueller $ \brief Declaration of class \c RlinkServer. */ @@ -99,8 +100,8 @@ namespace Retro { bool IsActiveInside() const; bool IsActiveOutside() const; - void SetTraceLevel(size_t level); - size_t TraceLevel() const; + void SetTraceLevel(uint32_t level); + uint32_t TraceLevel() const; const Rstats& Stats() const; @@ -169,7 +170,7 @@ namespace Retro { boost::thread fServerThread; bool fAttnSeen; uint16_t fAttnPatt; - size_t fTraceLevel; //!< trace level + uint32_t fTraceLevel; //!< trace level Rstats fStats; //!< statistics }; diff --git a/tools/src/librlink/RlinkServer.ipp b/tools/src/librlink/RlinkServer.ipp index 7eed7767..506f6de3 100644 --- a/tools/src/librlink/RlinkServer.ipp +++ b/tools/src/librlink/RlinkServer.ipp @@ -1,4 +1,4 @@ -// $Id: RlinkServer.ipp 495 2013-03-06 17:13:48Z mueller $ +// $Id: RlinkServer.ipp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.0.1 fTraceLevel now uint32_t // 2013-03-06 495 1.0 Initial version // 2013-01-12 474 0.5 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: RlinkServer.ipp 495 2013-03-06 17:13:48Z mueller $ + \version $Id: RlinkServer.ipp 513 2013-05-01 14:02:06Z mueller $ \brief Implemenation (inline) of RlinkServer. */ @@ -77,7 +78,7 @@ inline bool RlinkServer::Exec(RlinkCommandList& clist) //------------------------------------------+----------------------------------- //! FIXME_docs -inline size_t RlinkServer::TraceLevel() const +inline uint32_t RlinkServer::TraceLevel() const { return fTraceLevel; } diff --git a/tools/src/librlinktpp/RtclRlinkServer.cpp b/tools/src/librlinktpp/RtclRlinkServer.cpp index e526512e..431dbfd9 100644 --- a/tools/src/librlinktpp/RtclRlinkServer.cpp +++ b/tools/src/librlinktpp/RtclRlinkServer.cpp @@ -1,4 +1,4 @@ -// $Id: RtclRlinkServer.cpp 510 2013-04-26 16:14:57Z mueller $ +// $Id: RtclRlinkServer.cpp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.0.5 TraceLevel now uint32_t // 2013-04-26 510 1.0.4 change M_attn, now -info instead of -show // 2013-04-21 509 1.0.3 add server -resume // 2013-02-05 483 1.0.2 ClassCmdConfig: use RtclArgs @@ -22,7 +23,7 @@ /*! \file - \version $Id: RtclRlinkServer.cpp 510 2013-04-26 16:14:57Z mueller $ + \version $Id: RtclRlinkServer.cpp 513 2013-05-01 14:02:06Z mueller $ \brief Implemenation of class RtclRlinkServer. */ @@ -125,10 +126,10 @@ int RtclRlinkServer::M_server(RtclArgs& args) if (!args.AllDone()) return kERR; args.SetResult(Obj().IsActive()); } else if (opt == "-trace") { // server -trace ... - int level; + uint32_t level; if (!args.GetArg("?level", level)) return kERR; if (args.NOptMiss()==0) { // server -trace level - Obj().SetTraceLevel((size_t)level); + Obj().SetTraceLevel(level); } else { // server -trace args.SetResult((int)Obj().TraceLevel()); } diff --git a/tools/src/librtcltools/RtclCmdBase.cpp b/tools/src/librtcltools/RtclCmdBase.cpp index f627dceb..e2bd62d0 100644 --- a/tools/src/librtcltools/RtclCmdBase.cpp +++ b/tools/src/librtcltools/RtclCmdBase.cpp @@ -1,4 +1,4 @@ -// $Id: RtclCmdBase.cpp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RtclCmdBase.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2011-2013 by Walter F.J. Mueller // @@ -20,7 +20,7 @@ /*! \file - \version $Id: RtclCmdBase.cpp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RtclCmdBase.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of RtclCmdBase. */ @@ -132,8 +132,8 @@ void RtclCmdBase::AddMeth(const std::string& name, const methfo_t& methfo) { mmap_ins_t ret = fMapMeth.insert(mmap_val_t(name, methfo)); if (ret.second == false) // or use !(ret.second) - throw Rexception("RtclCmdBase::AddMeth:", "Bad args: " + - string("duplicate name: ") + name); + throw Rexception("RtclCmdBase::AddMeth:", + string("Bad args: duplicate name: '") + name + "'"); return; } diff --git a/tools/src/librtcltools/RtclGetList.cpp b/tools/src/librtcltools/RtclGetList.cpp index 4728c962..01b9f8c0 100644 --- a/tools/src/librtcltools/RtclGetList.cpp +++ b/tools/src/librtcltools/RtclGetList.cpp @@ -1,4 +1,4 @@ -// $Id: RtclGetList.cpp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RtclGetList.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -18,7 +18,7 @@ /*! \file - \version $Id: RtclGetList.cpp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RtclGetList.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of class RtclGetList. */ @@ -64,8 +64,8 @@ void RtclGetList::Add(const std::string& name, RtclGetBase* pget) typedef std::pair map_ins_t; map_ins_t ret = fMap.insert(map_val_t(name, pget)); if (ret.second == false) - throw Rexception("RtclGetList::Add:", "Bad args: " + - string("duplicate name: ") + name); + throw Rexception("RtclGetList::Add:", + string("Bad args: duplicate name: '") + name + "'"); return; } diff --git a/tools/src/librtcltools/RtclNameSet.cpp b/tools/src/librtcltools/RtclNameSet.cpp index 968ace6f..5ceb4020 100644 --- a/tools/src/librtcltools/RtclNameSet.cpp +++ b/tools/src/librtcltools/RtclNameSet.cpp @@ -1,4 +1,4 @@ -// $Id: RtclNameSet.cpp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RtclNameSet.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2011-2013 by Walter F.J. Mueller // @@ -19,7 +19,7 @@ /*! \file - \version $Id: RtclNameSet.cpp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RtclNameSet.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of RtclNameSet. */ @@ -64,7 +64,7 @@ RtclNameSet::RtclNameSet(const std::string& nset) if (ret.second == false) // or use !(ret.second) throw Rexception("RtclNameSet::", "Bad args: " + string("duplicate name '") + name + - string("' in set '") + nset + string("'")); + "' in set '" + nset + "'"); } if (iend == string::npos) break; ibeg = iend+1; diff --git a/tools/src/librtcltools/RtclSetList.cpp b/tools/src/librtcltools/RtclSetList.cpp index 10ea7362..786281e6 100644 --- a/tools/src/librtcltools/RtclSetList.cpp +++ b/tools/src/librtcltools/RtclSetList.cpp @@ -1,4 +1,4 @@ -// $Id: RtclSetList.cpp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RtclSetList.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -18,7 +18,7 @@ /*! \file - \version $Id: RtclSetList.cpp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RtclSetList.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of class RtclSetList. */ @@ -64,8 +64,8 @@ void RtclSetList::Add(const std::string& name, RtclSetBase* pset) typedef std::pair map_ins_t; map_ins_t ret = fMap.insert(map_val_t(name, pset)); if (ret.second == false) - throw Rexception("RtclSetList::Add:", "Bad args: " + - string("duplicate name: ") + name); + throw Rexception("RtclSetList::Add:", + string("Bad args: duplicate name: '") + name + "'"); return; } diff --git a/tools/src/librtools/RparseUrl.cpp b/tools/src/librtools/RparseUrl.cpp index d29c8265..671c4cb7 100644 --- a/tools/src/librtools/RparseUrl.cpp +++ b/tools/src/librtools/RparseUrl.cpp @@ -1,4 +1,4 @@ -// $Id: RparseUrl.cpp 492 2013-02-24 22:14:47Z mueller $ +// $Id: RparseUrl.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -19,7 +19,7 @@ /*! \file - \version $Id: RparseUrl.cpp 492 2013-02-24 22:14:47Z mueller $ + \version $Id: RparseUrl.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of RparseUrl. */ @@ -97,8 +97,7 @@ bool RparseUrl::Set(const std::string& url, const std::string& optlist, if (c == '\\') { if (i+1 >= url.length()) { emsg.Init("RparseUrl::ParseUrl()", - string("invalid trailing \\ in url '") + url + - string("'")); + string("invalid trailing \\ in url '") + url + "'"); return false; } i += 1; @@ -107,7 +106,7 @@ bool RparseUrl::Set(const std::string& url, const std::string& optlist, case ';' : c = ';'; break; default : emsg.Init("RparseUrl::ParseUrl()", string("invalid \\ escape in url '") + - url + string("'")); + url + "'"); return false; } } @@ -208,7 +207,8 @@ bool RparseUrl::AddOpt(const std::string& key, const std::string& val, lkey += "|"; if (optlist.find(lkey) == string::npos) { emsg.Init("RparseUrl::AddOpt()", - string("invalid field name '") + lkey + string("'")); + string("invalid field name '") + lkey + "'; allowed: '" + + optlist + "'"); return false; } diff --git a/tools/src/librtools/Rtools.cpp b/tools/src/librtools/Rtools.cpp index 44b2d780..fbcb10a1 100644 --- a/tools/src/librtools/Rtools.cpp +++ b/tools/src/librtools/Rtools.cpp @@ -1,4 +1,4 @@ -// $Id: Rtools.cpp 493 2013-03-01 21:02:33Z mueller $ +// $Id: Rtools.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2011-2013 by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-04 516 1.0.3 add CreateBackupFile() // 2013-02-13 481 1.0.2 remove Throw(Logic|Runtime)(); use Rexception // 2011-04-10 376 1.0.1 add ThrowLogic(), ThrowRuntime() // 2011-03-12 368 1.0 Initial version @@ -20,13 +21,19 @@ /*! \file - \version $Id: Rtools.cpp 493 2013-03-01 21:02:33Z mueller $ + \version $Id: Rtools.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of Rtools . */ #include +#include +#include +#include +#include + +#include +#include -#include "RerrMsg.hpp" #include "Rexception.hpp" #include "Rtools.hpp" @@ -40,12 +47,12 @@ using namespace std; // all method definitions in namespace Retro namespace Retro { +namespace Rtools { //------------------------------------------+----------------------------------- //! FIXME_docs -std::string Rtools::Flags2String(uint32_t flags, const RflagName* fnam, - char delim) +std::string Flags2String(uint32_t flags, const RflagName* fnam, char delim) { if (fnam == 0) throw Rexception("Rtools::Flags2String()","Bad args: fnam==NULL"); @@ -61,4 +68,105 @@ std::string Rtools::Flags2String(uint32_t flags, const RflagName* fnam, return rval; } +//------------------------------------------+----------------------------------- +//! FIXME_docs +bool String2Long(const std::string& str, long& res, RerrMsg& emsg, int base) +{ + char* endptr; + res = ::strtol(str.c_str(), &endptr, base); + if (*endptr == 0) return true; + + emsg.Init("Rtools::String2Long", + string("conversion error in '") + str +"'"); + res = 0; + return false; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs +bool String2Long(const std::string& str, unsigned long& res, + RerrMsg& emsg, int base) +{ + char* endptr; + res = ::strtoul(str.c_str(), &endptr, base); + if (*endptr == 0) return true; + + emsg.Init("Rtools::String2Long", + string("conversion error in '") + str +"'"); + res = 0; + return false; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +bool CreateBackupFile(const std::string& fname, size_t nbackup, RerrMsg& emsg) +{ + if (nbackup == 0) return true; + + size_t dotpos = fname.find_last_of('.'); + string fbase = fname.substr(0,dotpos); + string fext = fname.substr(dotpos); + + if (nbackup > 99) { + emsg.Init("Rtools::CreateBackupFile", + "only up to 99 backup levels supported"); + return false; + } + + vector fnames; + fnames.push_back(fname); + for (size_t i=1; i<=nbackup; i++) { + char fnum[4]; + snprintf(fnum, 4, "%d", i); + fnames.push_back(fbase + "_" + fnum + fext); + } + + for (size_t i=nbackup; i>0; i--) { + string fnam_new = fnames[i]; + string fnam_old = fnames[i-1]; + + struct stat sbuf; + int irc = ::stat(fnam_old.c_str(), &sbuf); + if (irc < 0) { + if (errno == ENOENT) continue; + emsg.InitErrno("Rtools::CreateBackupFile", + string("stat() for '") + fnam_old + "'failed: ", errno); + return false; + } + if (S_ISREG(sbuf.st_mode) == 0) { + emsg.Init("Rtools::CreateBackupFile", + "backups only supported for regular files"); + return false; + } + // here we know old file exists and is a regular file + irc = ::rename(fnam_old.c_str(), fnam_new.c_str()); + if (irc < 0) { + emsg.InitErrno("Rtools::CreateBackupFile", + string("rename() for '") + fnam_old + "' -> '" + + fnam_new + "'failed: ", errno); + return false; + } + } + + return true; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +bool CreateBackupFile(const RparseUrl& purl, RerrMsg& emsg) +{ + string bck; + if (!purl.FindOpt("app") && purl.FindOpt("bck", bck)) { + unsigned long nbck; + if (!Rtools::String2Long(bck, nbck, emsg)) return false; + if (nbck > 0) { + if (!Rtools::CreateBackupFile(purl.Path(), nbck, emsg)) return false; + } + } + return true; +} + +} // end namespace Rtools } // end namespace Retro diff --git a/tools/src/librtools/Rtools.hpp b/tools/src/librtools/Rtools.hpp index 734c05a0..e02f29bc 100644 --- a/tools/src/librtools/Rtools.hpp +++ b/tools/src/librtools/Rtools.hpp @@ -1,4 +1,4 @@ -// $Id: Rtools.hpp 486 2013-02-10 22:34:43Z mueller $ +// $Id: Rtools.hpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2011-2013 by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-04 516 1.0.3 add CreateBackupFile(), String2Long() // 2013-02-13 481 1.0.2 remove ThrowLogic(), ThrowRuntime() // 2011-04-10 376 1.0.1 add ThrowLogic(), ThrowRuntime() // 2011-03-12 368 1.0 Initial version @@ -20,7 +21,7 @@ /*! \file - \version $Id: Rtools.hpp 486 2013-02-10 22:34:43Z mueller $ + \version $Id: Rtools.hpp 516 2013-05-05 21:24:52Z mueller $ \brief Declaration of class Rtools . */ @@ -30,6 +31,9 @@ #include #include +#include "RerrMsg.hpp" +#include "RparseUrl.hpp" + namespace Retro { struct RflagName { @@ -40,6 +44,15 @@ namespace Retro { namespace Rtools { std::string Flags2String(uint32_t flags, const RflagName* fnam, char delim='|'); + + bool String2Long(const std::string& str, long& res, + RerrMsg& emsg, int base=10); + bool String2Long(const std::string& str, unsigned long& res, + RerrMsg& emsg, int base=10); + + bool CreateBackupFile(const std::string& fname, size_t nbackup, + RerrMsg& emsg); + bool CreateBackupFile(const RparseUrl& purl, RerrMsg& emsg); }; } // end namespace Retro diff --git a/tools/src/librw11/Makefile b/tools/src/librw11/Makefile index 6497e254..83bce00a 100644 --- a/tools/src/librw11/Makefile +++ b/tools/src/librw11/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 504 2013-04-13 15:37:24Z mueller $ +# $Id: Makefile 515 2013-05-04 17:28:59Z mueller $ # # Revision History: # Date Rev Version Comment @@ -26,11 +26,15 @@ OBJ_all += Rw11Probe.o OBJ_all += Rw11Cntl.o Rw11Unit.o OBJ_all += Rw11UnitTerm.o OBJ_all += Rw11UnitDisk.o +OBJ_all += Rw11UnitStream.o OBJ_all += Rw11CntlDL11.o Rw11UnitDL11.o OBJ_all += Rw11CntlRK11.o Rw11UnitRK11.o +OBJ_all += Rw11CntlLP11.o Rw11UnitLP11.o +OBJ_all += Rw11CntlPC11.o Rw11UnitPC11.o OBJ_all += Rw11Virt.o OBJ_all += Rw11VirtTerm.o Rw11VirtTermPty.o Rw11VirtTermTcp.o OBJ_all += Rw11VirtDisk.o Rw11VirtDiskFile.o +OBJ_all += Rw11VirtStream.o # DEP_all = $(OBJ_all:.o=.dep) # diff --git a/tools/src/librw11/Rw11CntlDL11.cpp b/tools/src/librw11/Rw11CntlDL11.cpp index 870a4fce..d5fc6b59 100644 --- a/tools/src/librw11/Rw11CntlDL11.cpp +++ b/tools/src/librw11/Rw11CntlDL11.cpp @@ -1,4 +1,4 @@ -// $Id: Rw11CntlDL11.cpp 508 2013-04-20 18:43:28Z mueller $ +// $Id: Rw11CntlDL11.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-04 516 1.0.2 add RxRlim support (receive interrupt rate limit) // 2013-04-20 508 1.0.1 add trace support // 2013-03-06 495 1.0 Initial version // 2013-02-05 483 0.1 First draft @@ -20,7 +21,7 @@ /*! \file - \version $Id: Rw11CntlDL11.cpp 508 2013-04-20 18:43:28Z mueller $ + \version $Id: Rw11CntlDL11.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of Rw11CntlDL11. */ @@ -59,6 +60,9 @@ const uint16_t Rw11CntlDL11::kProbeOff; const bool Rw11CntlDL11::kProbeInt; const bool Rw11CntlDL11::kProbeRem; +const uint16_t Rw11CntlDL11::kRCSR_M_RXRLIM; +const uint16_t Rw11CntlDL11::kRCSR_V_RXRLIM; +const uint16_t Rw11CntlDL11::kRCSR_B_RXRLIM; const uint16_t Rw11CntlDL11::kRCSR_M_RDONE; const uint16_t Rw11CntlDL11::kXCSR_M_XRDY; const uint16_t Rw11CntlDL11::kXBUF_M_RRDY; @@ -70,7 +74,8 @@ const uint16_t Rw11CntlDL11::kXBUF_M_XBUF; Rw11CntlDL11::Rw11CntlDL11() : Rw11CntlBase("dl11"), - fPC_xbuf(0) + fPC_xbuf(0), + fRxRlim(0) { // must here because Unit have a back-pointer (not available at Rw11CntlBase) for (size_t i=0; iRcvQueueEmpty()) { @@ -141,11 +160,33 @@ void Rw11CntlDL11::Wakeup() //------------------------------------------+----------------------------------- //! FIXME_docs +void Rw11CntlDL11::SetRxRlim(uint16_t rlim) +{ + if (rlim > kRCSR_B_RXRLIM) + throw Rexception("Rw11CntlDL11::SetRxRlim","Bad args: rlim too large"); + + fRxRlim = rlim; + UnitSetup(0); + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +uint16_t Rw11CntlDL11::RxRlim() const +{ + return fRxRlim; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + void Rw11CntlDL11::Dump(std::ostream& os, int ind, const char* text) const { RosFill bl(ind); os << bl << (text?text:"--") << "Rw11CntlDL11 @ " << this << endl; os << bl << " fPC_xbuf: " << fPC_xbuf << endl; + os << bl << " fRxRlim: " << fRxRlim << endl; Rw11CntlBase::Dump(os, ind, " ^"); return; diff --git a/tools/src/librw11/Rw11CntlDL11.hpp b/tools/src/librw11/Rw11CntlDL11.hpp index a6a6772b..30f66e7e 100644 --- a/tools/src/librw11/Rw11CntlDL11.hpp +++ b/tools/src/librw11/Rw11CntlDL11.hpp @@ -1,4 +1,4 @@ -// $Id: Rw11CntlDL11.hpp 504 2013-04-13 15:37:24Z mueller $ +// $Id: Rw11CntlDL11.hpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-04 516 1.0.1 add RxRlim support (receive interrupt rate limit) // 2013-03-06 495 1.0 Initial version // 2013-02-05 483 0.1 First draft // --------------------------------------------------------------------------- @@ -20,7 +21,7 @@ /*! \file - \version $Id: Rw11CntlDL11.hpp 504 2013-04-13 15:37:24Z mueller $ + \version $Id: Rw11CntlDL11.hpp 516 2013-05-05 21:24:52Z mueller $ \brief Declaration of class Rw11CntlDL11. */ @@ -42,13 +43,17 @@ namespace Retro { virtual void Start(); + virtual void UnitSetup(size_t ind); void Wakeup(); + void SetRxRlim(uint16_t rlim); + uint16_t RxRlim() const; + virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; // some constants (also defined in cpp) - static const uint16_t kIbaddr = 0177560; //!< RK11 default address - static const int kLam = 1; //!< RK11 default lam + static const uint16_t kIbaddr = 0177560; //!< DL11 default address + static const int kLam = 1; //!< DL11 default lam static const uint16_t kRCSR = 000; //!< RCSR register address offset static const uint16_t kRBUF = 002; //!< RBUF register address offset @@ -59,17 +64,21 @@ namespace Retro { static const bool kProbeInt = true; //!< probe int active static const bool kProbeRem = true; //!< probr rem active - static const uint16_t kRCSR_M_RDONE = kWBit07; - static const uint16_t kXCSR_M_XRDY = kWBit07; - static const uint16_t kXBUF_M_RRDY = kWBit09; - static const uint16_t kXBUF_M_XVAL = kWBit08; - static const uint16_t kXBUF_M_XBUF = 0xff; + static const uint16_t kRCSR_M_RXRLIM = 0070000; + static const uint16_t kRCSR_V_RXRLIM = 12; + static const uint16_t kRCSR_B_RXRLIM = 007; + static const uint16_t kRCSR_M_RDONE = kWBit07; + static const uint16_t kXCSR_M_XRDY = kWBit07; + static const uint16_t kXBUF_M_RRDY = kWBit09; + static const uint16_t kXBUF_M_XVAL = kWBit08; + static const uint16_t kXBUF_M_XBUF = 0xff; protected: int AttnHandler(const RlinkServer::AttnArgs& args); protected: size_t fPC_xbuf; //!< PrimClist: xbuf index + uint16_t fRxRlim; //!< rx interrupt rate limit }; } // end namespace Retro diff --git a/tools/src/librw11/Rw11CntlLP11.cpp b/tools/src/librw11/Rw11CntlLP11.cpp new file mode 100644 index 00000000..8c1e7dfb --- /dev/null +++ b/tools/src/librw11/Rw11CntlLP11.cpp @@ -0,0 +1,195 @@ +// $Id: Rw11CntlLP11.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-04 515 1.0 Initial version +// 2013-05-01 513 0.1 First draft +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rw11CntlLP11.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of Rw11CntlLP11. +*/ + +#include "boost/bind.hpp" + +#include "librtools/RosFill.hpp" +#include "librtools/RosPrintBvi.hpp" +#include "librtools/RosPrintf.hpp" +#include "librtools/Rexception.hpp" +#include "librtools/RlogMsg.hpp" + +#include "Rw11CntlLP11.hpp" + +using namespace std; + +/*! + \class Retro::Rw11CntlLP11 + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +// constants definitions + +const uint16_t Rw11CntlLP11::kIbaddr; +const int Rw11CntlLP11::kLam; + +const uint16_t Rw11CntlLP11::kCSR; +const uint16_t Rw11CntlLP11::kBUF; + +const uint16_t Rw11CntlLP11::kProbeOff; +const bool Rw11CntlLP11::kProbeInt; +const bool Rw11CntlLP11::kProbeRem; + +const uint16_t Rw11CntlLP11::kCSR_M_ERROR; +const uint16_t Rw11CntlLP11::kBUF_M_VAL; +const uint16_t Rw11CntlLP11::kBUF_M_BUF; + +//------------------------------------------+----------------------------------- +//! Default constructor + +Rw11CntlLP11::Rw11CntlLP11() + : Rw11CntlBase("lp11"), + fPC_buf(0) +{ + // must here because Unit have a back-pointer (not available at Rw11CntlBase) + for (size_t i=0; i::Dump(os, ind, " ^"); + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +int Rw11CntlLP11::AttnHandler(const RlinkServer::AttnArgs& args) +{ + RlinkCommandList* pclist; + size_t off; + + GetPrimInfo(args, pclist, off); + + uint16_t buf = (*pclist)[off+fPC_buf].Data(); + bool val = buf & kBUF_M_VAL; + uint8_t ochr = buf & kBUF_M_BUF; + + if (fTraceLevel>0) { + RlogMsg lmsg(LogFile()); + lmsg << "-I LP11." << Name() + << " buf=" << RosPrintBvi(buf,8) + << " val=" << val; + if (val) { + lmsg << " char="; + if (ochr>=040 && ochr<0177) { + lmsg << "'" << char(ochr) << "'"; + } else { + lmsg << RosPrintBvi(ochr,8); + } + } + } + + if (val) { + RerrMsg emsg; + bool rc = fspUnit[0]->VirtWrite(&ochr, 1, emsg); + if (!rc) { + RlogMsg lmsg(LogFile()); + lmsg << emsg; + SetOnline(false); + } + if (ochr == 014) { // ^L = FF = FormFeed seen ? + rc = fspUnit[0]->VirtFlush(emsg); + } + } + + return 0; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11CntlLP11::SetOnline(bool online) +{ + Rw11Cpu& cpu = Cpu(); + uint16_t csr = online ? 0 : kCSR_M_ERROR; + RlinkCommandList clist; + cpu.AddIbrb(clist, fBase); + cpu.AddWibr(clist, fBase+kCSR, csr); + Server().Exec(clist); + return; +} + +} // end namespace Retro diff --git a/tools/src/librw11/Rw11CntlLP11.hpp b/tools/src/librw11/Rw11CntlLP11.hpp new file mode 100644 index 00000000..0ee07cd2 --- /dev/null +++ b/tools/src/librw11/Rw11CntlLP11.hpp @@ -0,0 +1,75 @@ +// $Id: Rw11CntlLP11.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: Rw11CntlLP11.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class Rw11CntlLP11. +*/ + +#ifndef included_Retro_Rw11CntlLP11 +#define included_Retro_Rw11CntlLP11 1 + +#include "Rw11CntlBase.hpp" +#include "Rw11UnitLP11.hpp" + +namespace Retro { + + class Rw11CntlLP11 : public Rw11CntlBase { + public: + + Rw11CntlLP11(); + ~Rw11CntlLP11(); + + void Config(const std::string& name, uint16_t base, int lam); + + virtual void Start(); + + virtual void UnitSetup(size_t ind); + + virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; + + // some constants (also defined in cpp) + static const uint16_t kIbaddr = 0177514; //!< LP11 default address + static const int kLam = 8; //!< LP11 default lam + + static const uint16_t kCSR = 000; //!< CSR register address offset + static const uint16_t kBUF = 002; //!< BUF register address offset + + static const uint16_t kProbeOff = kCSR; //!< probe address offset (rcsr) + static const bool kProbeInt = true; //!< probe int active + static const bool kProbeRem = true; //!< probr rem active + + static const uint16_t kCSR_M_ERROR = kWBit15; + static const uint16_t kBUF_M_VAL = kWBit08; + static const uint16_t kBUF_M_BUF = 0177; + + protected: + int AttnHandler(const RlinkServer::AttnArgs& args); + void SetOnline(bool online); + + protected: + size_t fPC_buf; //!< PrimClist: buf index + }; + +} // end namespace Retro + +//#include "Rw11CntlLP11.ipp" + +#endif diff --git a/tools/src/librw11/Rw11CntlPC11.cpp b/tools/src/librw11/Rw11CntlPC11.cpp new file mode 100644 index 00000000..e74e3e95 --- /dev/null +++ b/tools/src/librw11/Rw11CntlPC11.cpp @@ -0,0 +1,316 @@ +// $Id: Rw11CntlPC11.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-03 515 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rw11CntlPC11.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of Rw11CntlPC11. +*/ + +#include "boost/bind.hpp" +#include "boost/foreach.hpp" +#define foreach_ BOOST_FOREACH + +#include "librtools/RosFill.hpp" +#include "librtools/RosPrintBvi.hpp" +#include "librtools/RosPrintf.hpp" +#include "librtools/Rexception.hpp" +#include "librtools/RlogMsg.hpp" + +#include "Rw11CntlPC11.hpp" + +using namespace std; + +/*! + \class Retro::Rw11CntlPC11 + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +// constants definitions + +const uint16_t Rw11CntlPC11::kIbaddr; +const int Rw11CntlPC11::kLam; + +const uint16_t Rw11CntlPC11::kRCSR; +const uint16_t Rw11CntlPC11::kRBUF; +const uint16_t Rw11CntlPC11::kPCSR; +const uint16_t Rw11CntlPC11::kPBUF; + +const uint16_t Rw11CntlPC11::kUnit_PR; +const uint16_t Rw11CntlPC11::kUnit_PP; + +const uint16_t Rw11CntlPC11::kProbeOff; +const bool Rw11CntlPC11::kProbeInt; +const bool Rw11CntlPC11::kProbeRem; + +const uint16_t Rw11CntlPC11::kRCSR_M_ERROR; +const uint16_t Rw11CntlPC11::kPCSR_M_ERROR; +const uint16_t Rw11CntlPC11::kPBUF_M_RBUSY; +const uint16_t Rw11CntlPC11::kPBUF_M_PVAL; +const uint16_t Rw11CntlPC11::kPBUF_M_BUF; + +//------------------------------------------+----------------------------------- +//! Default constructor + +Rw11CntlPC11::Rw11CntlPC11() + : Rw11CntlBase("pc11"), + fPC_pbuf(0) +{ + // must here because Unit have a back-pointer (not available at Rw11CntlBase) + for (size_t i=0; i& code, + uint16_t& aload, uint16_t& astart) +{ + uint16_t kBOOT_START = 0017476; + uint16_t bootcode[] = { // papertape lda loader, from dec-11-l2pc-po + 0000000, // C000: halt + 0010706, // astart: mov pc,sp + 0024646, // cmp -(sp),-(sp) + 0010705, // mov pc,r5 + 0062705, 0000112, // add #000112,r5 + 0005001, // clr r1 + 0013716, 0177570, // B000: mov @#cp.dsr,(sp) + 0006016, // ror (sp) + 0103402, // bcs B001 + 0005016, // clr (sp) + 0000403, // br B002 + 0006316, // B001: asl (sp) + 0001001, // bne B002 + 0010116, // mov r1,(sp) + 0005000, // B002: clr r0 + 0004715, // jsr pc,(r5) + 0105303, // decb r3 + 0001374, // bne B002 + 0004715, // jsr pc,(r5) + 0004767, 0000074, // jsr pc,R000 + 0010402, // mov r4,r2 + 0162702, 0000004, // sub #000004,r2 + 0022702, 0000002, // cmp #000002,r2 + 0001441, // beq B007 + 0004767, 0000054, // jsr pc,R000 + 0061604, // add (sp),r4 + 0010401, // mov r4,r1 + 0004715, // B003: jsr pc,(r5) + 0002004, // bge B005 + 0105700, // tstb r0 + 0001753, // beq B002 + 0000000, // B004: halt + 0000751, // br B002 + 0110321, // B005: movb r3,(r1)+ + 0000770, // br B003 + 0016703, 0000152, // ldchr: mov p.prcs,r3 + 0105213, // incb (r3) + 0105713, // B006: tstb (r3) + 0100376, // bpl B006 + 0116303, 0000002, // movb 000002(r3),r3 + 0060300, // add r3,r0 + 0042703, 0177400, // bic #177400,r3 + 0005302, // dec r2 + 0000207, // rts pc + 0012667, 0000046, // R000: mov (sp)+,D000 + 0004715, // jsr pc,(r5) + 0010304, // mov r3,r4 + 0004715, // jsr pc,(r5) + 0000303, // swap r3 + 0050304, // bis r3,r4 + 0016707, 0000030, // mov D000,pc + 0004767, 0177752, // B007: jsr pc,R000 + 0004715, // jsr pc,(r5) + 0105700, // tstb r0 + 0001342, // bne B004 + 0006204, // asr r4 + 0103002, // bcc B008 + 0000000, // halt + 0000700, // br B000 + 0006304, // B008: asl r4 + 0061604, // add (sp),r4 + 0000114, // jmp (r4) + 0000000, // D000: .word 000000 + 0012767, 0000352, 0000020, // L000: mov #000352,B009+2 + 0012767, 0000765, 0000034, // mov #000765,D001 + 0000167, 0177532, // jmp C000 + 0016701, 0000026, // bstart: mov p.prcs,r1 + 0012702, 0000352, // B009: mov #000352,r2 + 0005211, // inc (r1) + 0105711, // B010: tstb (r1) + 0100376, // bpl B010 + 0116162, 0000002, 0157400, // movb 000002(r1),157400(r2) + 0005267, 0177756, // inc B009+2 + 0000765, // D001: br B009 + 0177550 // p.prcs: .word 177550 + }; + + code.clear(); + foreach_ (uint16_t& w, bootcode) code.push_back(w); + aload = kBOOT_START; + astart = kBOOT_START+2; + return true; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11CntlPC11::UnitSetup(size_t ind) +{ + Rw11UnitPC11& unit = *fspUnit[ind]; + SetOnline(ind, unit.Virt()); // online if stream attached + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11CntlPC11::Dump(std::ostream& os, int ind, const char* text) const +{ + RosFill bl(ind); + os << bl << (text?text:"--") << "Rw11CntlPC11 @ " << this << endl; + os << bl << " fPC_pbuf: " << fPC_pbuf << endl; + + Rw11CntlBase::Dump(os, ind, " ^"); + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +int Rw11CntlPC11::AttnHandler(const RlinkServer::AttnArgs& args) +{ + RlinkCommandList* pclist; + size_t off; + + GetPrimInfo(args, pclist, off); + + uint16_t pbuf = (*pclist)[off+fPC_pbuf].Data(); + bool pval = pbuf & kPBUF_M_PVAL; + bool rbusy = pbuf & kPBUF_M_RBUSY; + uint8_t ochr = pbuf & kPBUF_M_BUF; + + if (fTraceLevel>0) { + RlogMsg lmsg(LogFile()); + lmsg << "-I PC11." << Name() + << " pbuf=" << RosPrintBvi(pbuf,8) + << " pval=" << pval + << " rbusy=" << rbusy; + if (pval) { + lmsg << " char="; + if (ochr>=040 && ochr<0177) { + lmsg << "'" << char(ochr) << "'"; + } else { + lmsg << RosPrintBvi(ochr,8); + } + } + } + + if (pval) { + RerrMsg emsg; + bool rc = fspUnit[kUnit_PP]->VirtWrite(&ochr, 1, emsg); + if (!rc) { + RlogMsg lmsg(LogFile()); + lmsg << emsg; + SetOnline(1, false); + } + } + + if (rbusy) { + uint8_t ichr = 0; + RerrMsg emsg; + int irc = fspUnit[kUnit_PR]->VirtRead(&ichr, 1, emsg); + if (irc < 0) { + RlogMsg lmsg(LogFile()); + lmsg << emsg; + } + if (irc <= 0) { + SetOnline(0, false); + } else { + RlinkCommandList clist; + Cpu().AddWibr(clist, fBase+kRBUF, ichr); + Server().Exec(clist); + } + } + + return 0; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11CntlPC11::SetOnline(size_t ind, bool online) +{ + Rw11Cpu& cpu = Cpu(); + RlinkCommandList clist; + cpu.AddIbrb(clist, fBase); + if (ind == kUnit_PR) { // reader on/offline + uint16_t rcsr = online ? 0 : kRCSR_M_ERROR; + cpu.AddWibr(clist, fBase+kRCSR, rcsr); + } else { // puncher on/offline + uint16_t pcsr = online ? 0 : kPCSR_M_ERROR; + cpu.AddWibr(clist, fBase+kPCSR, pcsr); + } + Server().Exec(clist); + return; +} + +} // end namespace Retro diff --git a/tools/src/librw11/Rw11CntlPC11.hpp b/tools/src/librw11/Rw11CntlPC11.hpp new file mode 100644 index 00000000..1c3f8e6f --- /dev/null +++ b/tools/src/librw11/Rw11CntlPC11.hpp @@ -0,0 +1,85 @@ +// $Id: Rw11CntlPC11.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-03 515 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: Rw11CntlPC11.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class Rw11CntlPC11. +*/ + +#ifndef included_Retro_Rw11CntlPC11 +#define included_Retro_Rw11CntlPC11 1 + +#include "Rw11CntlBase.hpp" +#include "Rw11UnitPC11.hpp" + +namespace Retro { + + class Rw11CntlPC11 : public Rw11CntlBase { + public: + + Rw11CntlPC11(); + ~Rw11CntlPC11(); + + void Config(const std::string& name, uint16_t base, int lam); + + virtual void Start(); + + virtual bool BootCode(size_t unit, std::vector& code, + uint16_t& aload, uint16_t& astart); + + virtual void UnitSetup(size_t ind); + + virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; + + // some constants (also defined in cpp) + static const uint16_t kIbaddr = 0177550; //!< PC11 default address + static const int kLam = 10; //!< PC11 default lam + + static const uint16_t kRCSR = 000; //!< RCSR register address offset + static const uint16_t kRBUF = 002; //!< RBUF register address offset + static const uint16_t kPCSR = 004; //!< PCSR register address offset + static const uint16_t kPBUF = 006; //!< PBUF register address offset + + static const uint16_t kUnit_PR = 0; // // Other credits: @@ -21,7 +21,7 @@ /*! \file - \version $Id: Rw11CntlRK11.cpp 509 2013-04-21 20:46:20Z mueller $ + \version $Id: Rw11CntlRK11.cpp 515 2013-05-04 17:28:59Z mueller $ \brief Implemenation of Rw11CntlRK11. */ @@ -224,30 +224,30 @@ bool Rw11CntlRK11::BootCode(size_t unit, std::vector& code, uint16_t& aload, uint16_t& astart) { uint16_t kBOOT_START = 02000; - uint16_t bootcode[] = { // rk05 boot loader - from simh pdp11_rk.c - 0042113, // "KD" - 0012706, kBOOT_START, // MOV #boot_start, SP - 0012700, uint16_t(unit), // MOV #unit, R0 ; unit number - 0010003, // # MOV R0, R3 - 0000303, // # SWAB R3 - 0006303, // # ASL R3 - 0006303, // # ASL R3 - 0006303, // # ASL R3 - 0006303, // # ASL R3 - 0006303, // # ASL R3 - 0012701, 0177412, // # MOV #RKDA, R1 ; rkda - 0010311, // # MOV R3, (R1) ; load da - 0005041, // # CLR -(R1) ; clear ba - 0012741, 0177000, // # MOV #-256.*2, -(R1) ; load wc - 0012741, 0000005, // # MOV #READ+GO, -(R1) ; read & go - 0005002, // # CLR R2 - 0005003, // # CLR R3 - 0012704, uint16_t(kBOOT_START+020), // # MOV #START+20, R4 - 0005005, // # CLR R5 - 0105711, // # TSTB (R1) - 0100376, // # BPL .-4 - 0105011, // # CLRB (R1) - 0005007 // # CLR PC (5007) + uint16_t bootcode[] = { // rk05 boot loader - from simh pdp11_rk.c + 0042113, // "KD" + 0012706, kBOOT_START, // MOV #boot_start, SP + 0012700, uint16_t(unit), // MOV #unit, R0 ; unit number + 0010003, // MOV R0, R3 + 0000303, // SWAB R3 + 0006303, // ASL R3 + 0006303, // ASL R3 + 0006303, // ASL R3 + 0006303, // ASL R3 + 0006303, // ASL R3 + 0012701, 0177412, // MOV #RKDA, R1 ; rkda + 0010311, // MOV R3, (R1) ; load da + 0005041, // CLR -(R1) ; clear ba + 0012741, 0177000, // MOV #-256.*2, -(R1) ; load wc + 0012741, 0000005, // MOV #READ+GO, -(R1) ; read & go + 0005002, // CLR R2 + 0005003, // CLR R3 + 0012704, uint16_t(kBOOT_START+020), // MOV #START+20, R4 + 0005005, // CLR R5 + 0105711, // TSTB (R1) + 0100376, // BPL .-4 + 0105011, // CLRB (R1) + 0005007 // CLR PC (5007) }; code.clear(); diff --git a/tools/src/librw11/Rw11Cpu.cpp b/tools/src/librw11/Rw11Cpu.cpp index ad17632b..0fc0d0e2 100644 --- a/tools/src/librw11/Rw11Cpu.cpp +++ b/tools/src/librw11/Rw11Cpu.cpp @@ -1,4 +1,4 @@ -// $Id: Rw11Cpu.cpp 506 2013-04-14 21:54:03Z mueller $ +// $Id: Rw11Cpu.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -20,7 +20,7 @@ /*! \file - \version $Id: Rw11Cpu.cpp 506 2013-04-14 21:54:03Z mueller $ + \version $Id: Rw11Cpu.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of Rw11Cpu. */ #include @@ -399,7 +399,7 @@ bool Rw11Cpu::LoadAbs(const std::string& fname, RerrMsg& emsg, bool trace) if (fd < 0) { emsg.InitErrno("Rw11Cpu::LoadAbs()", string("open() for '") + fname + - string("' failed: "), errno); + "' failed: ", errno); return false; } @@ -590,8 +590,7 @@ bool Rw11Cpu::Boot(const std::string& uname, RerrMsg& emsg) } if (!TestCntl(cname)) { - emsg.Init("Rw11Cpu::Boot", string("controller '") + cname + - string("' not known")); + emsg.Init("Rw11Cpu::Boot", string("controller '") + cname + "' not known"); return false; } @@ -605,7 +604,7 @@ bool Rw11Cpu::Boot(const std::string& uname, RerrMsg& emsg) if (!cntl.BootCode(uind, code, aload, astart) || code.size()==0) { emsg.Init("Rw11Cpu::Boot", string("boot not supported for controller '") - + cname + string("'")); + + cname + "'"); return false; } diff --git a/tools/src/librw11/Rw11Unit.cpp b/tools/src/librw11/Rw11Unit.cpp index f924b0c9..bc473c75 100644 --- a/tools/src/librw11/Rw11Unit.cpp +++ b/tools/src/librw11/Rw11Unit.cpp @@ -1,4 +1,4 @@ -// $Id: Rw11Unit.cpp 495 2013-03-06 17:13:48Z mueller $ +// $Id: Rw11Unit.cpp 515 2013-05-04 17:28:59Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone() // 2013-03-06 495 1.0 Initial version // 2013-02-13 488 0.1 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: Rw11Unit.cpp 495 2013-03-06 17:13:48Z mueller $ + \version $Id: Rw11Unit.cpp 515 2013-05-04 17:28:59Z mueller $ \brief Implemenation of Rw11Unit. */ @@ -43,6 +44,7 @@ namespace Retro { Rw11Unit::Rw11Unit(Rw11Cntl* pcntl, size_t index) : fpCntlBase(pcntl), fIndex(index), + fAttachOpts(), fStats() {} @@ -78,6 +80,7 @@ void Rw11Unit::Dump(std::ostream& os, int ind, const char* text) const os << bl << (text?text:"--") << "Rw11Unit @ " << this << endl; os << bl << " fIndex: " << fIndex << endl; + os << bl << " fAttachOpts: " << fAttachOpts << endl; fStats.Dump(os, ind+2, "fStats: "); return; } @@ -85,7 +88,7 @@ void Rw11Unit::Dump(std::ostream& os, int ind, const char* text) const //------------------------------------------+----------------------------------- //! FIXME_docs -void Rw11Unit::AttachSetup() +void Rw11Unit::AttachDone() {} //------------------------------------------+----------------------------------- @@ -94,4 +97,10 @@ void Rw11Unit::AttachSetup() void Rw11Unit::DetachCleanup() {} +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11Unit::DetachDone() +{} + } // end namespace Retro diff --git a/tools/src/librw11/Rw11Unit.hpp b/tools/src/librw11/Rw11Unit.hpp index 06c14f71..296e911e 100644 --- a/tools/src/librw11/Rw11Unit.hpp +++ b/tools/src/librw11/Rw11Unit.hpp @@ -1,4 +1,4 @@ -// $Id: Rw11Unit.hpp 495 2013-03-06 17:13:48Z mueller $ +// $Id: Rw11Unit.hpp 515 2013-05-04 17:28:59Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,8 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone() +// 2013-05-01 513 1.0.1 add fAttachOpts, (Set)AttachOpts() // 2013-03-06 495 1.0 Initial version // 2013-02-13 488 0.1 First draft // --------------------------------------------------------------------------- @@ -20,13 +22,15 @@ /*! \file - \version $Id: Rw11Unit.hpp 495 2013-03-06 17:13:48Z mueller $ + \version $Id: Rw11Unit.hpp 515 2013-05-04 17:28:59Z mueller $ \brief Declaration of class Rw11Unit. */ #ifndef included_Retro_Rw11Unit #define included_Retro_Rw11Unit 1 +#include + #include "boost/utility.hpp" #include "librtools/Rstats.hpp" @@ -47,6 +51,9 @@ namespace Retro { size_t Index() const; std::string Name() const; + void SetAttachOpts(const std::string& opts); + const std::string& AttachOpts() const; + Rw11Cntl& CntlBase() const; Rw11Cpu& Cpu() const; Rw11& W11() const; @@ -66,8 +73,9 @@ namespace Retro { }; protected: - virtual void AttachSetup(); + virtual void AttachDone(); virtual void DetachCleanup(); + virtual void DetachDone(); private: Rw11Unit() {} //!< default ctor blocker @@ -75,6 +83,7 @@ namespace Retro { protected: Rw11Cntl* fpCntlBase; //!< plain Rw11Cntl ptr size_t fIndex; //!< unit number + std::string fAttachOpts; //!< unit context options for attach Rstats fStats; //!< statistics }; diff --git a/tools/src/librw11/Rw11Unit.ipp b/tools/src/librw11/Rw11Unit.ipp index dcc7d3d5..8b338b52 100644 --- a/tools/src/librw11/Rw11Unit.ipp +++ b/tools/src/librw11/Rw11Unit.ipp @@ -1,4 +1,4 @@ -// $Id: Rw11Unit.ipp 495 2013-03-06 17:13:48Z mueller $ +// $Id: Rw11Unit.ipp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.0.1 add fAttachOpts, (Set)AttachOpts() // 2013-03-06 495 1.0 Initial version // 2013-02-13 488 0.1 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: Rw11Unit.ipp 495 2013-03-06 17:13:48Z mueller $ + \version $Id: Rw11Unit.ipp 513 2013-05-01 14:02:06Z mueller $ \brief Implemenation (inline) of Rw11Unit. */ @@ -45,6 +46,23 @@ inline std::string Rw11Unit::Name() const //------------------------------------------+----------------------------------- //! FIXME_docs +inline void Rw11Unit::SetAttachOpts(const std::string& opts) +{ + fAttachOpts = opts; + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline const std::string& Rw11Unit::AttachOpts() const +{ + return fAttachOpts; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + inline Rw11Cntl& Rw11Unit::CntlBase() const { return *fpCntlBase; diff --git a/tools/src/librw11/Rw11UnitBase.ipp b/tools/src/librw11/Rw11UnitBase.ipp deleted file mode 100644 index 2a0340a5..00000000 --- a/tools/src/librw11/Rw11UnitBase.ipp +++ /dev/null @@ -1,123 +0,0 @@ -// $Id: Rw11UnitBase.ipp 495 2013-03-06 17:13:48Z mueller $ -// -// Copyright 2013- by Walter F.J. Mueller -// -// This program is free software; you may redistribute and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation, either version 2, or at your option any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for complete details. -// -// Revision History: -// Date Rev Version Comment -// 2013-03-06 495 1.0 Initial version -// 2013-02-05 483 0.1 First draft -// --------------------------------------------------------------------------- - -/*! - \file - \version $Id: Rw11UnitBase.ipp 495 2013-03-06 17:13:48Z mueller $ - \brief Implemenation (inline) of Rw11UnitBase. -*/ - -#include "boost/thread/locks.hpp" - -#include "librtools/RosFill.hpp" - -#include "Rw11CntlBase.hpp" -#include "Rw11UnitBase.hpp" - -/*! - \class Retro::Rw11UnitBase - \brief FIXME_docs -*/ - -// all method definitions in namespace Retro -namespace Retro { - -//------------------------------------------+----------------------------------- -//! Constructor - -template -Rw11UnitBase::Rw11UnitBase(TC* pcntl, size_t index) - : Rw11Unit(index), - fpCntl(pcntl), - fpVirt() -{} - -//------------------------------------------+----------------------------------- -//! Destructor - -template -Rw11UnitBase::~Rw11UnitBase() -{} - -//------------------------------------------+----------------------------------- -//! FIXME_docs - -template -inline TC& Rw11UnitBase::Cntl() const -{ - return *fpCntl; -} - -//------------------------------------------+----------------------------------- -//! FIXME_docs - -template -inline TV* Rw11UnitBase::Virt() const -{ - return fpVirt.get(); -} - -//------------------------------------------+----------------------------------- -//! FIXME_docs - -template -inline bool Rw11UnitBase::Attach(const std::string& url, RerrMsg& emsg) -{ - // synchronize with server thread - boost::lock_guard lock(Cntl().Connect()); - if (fpVirt) DetachCleanup(); - fpVirt.reset(TV::New(url, emsg)); - if (fpVirt) AttachSetup(); - return fpVirt; -} - -//------------------------------------------+----------------------------------- -//! FIXME_docs - -template -inline void Rw11UnitBase::Detach() -{ - // synchronize with server thread - boost::lock_guard lock(Cntl().Connect()); - if (fpVirt) DetachCleanup(); - fpVirt.reset(); - return; -} - -//------------------------------------------+----------------------------------- -//! FIXME_docs - -template -void Rw11UnitBase::Dump(std::ostream& os, int ind, - const char* text) const -{ - RosFill bl(ind); - os << bl << (text?text:"--") << "Rw11UnitBase @ " << this << std::endl; - os << bl << " fpCntl: " << fpCntl << std::endl; - if (fpVirt) { - fpVirt->Dump(os, ind+2, "*fpVirt: "); - } else { - os << bl << " fpVirt: " << fpVirt.get() << std::endl; - } - - Rw11Unit::Dump(os, ind, " ^"); - return; -} - -} // end namespace Retro diff --git a/tools/src/librw11/Rw11UnitDiskBase.hpp b/tools/src/librw11/Rw11UnitDiskBase.hpp index db6f76d7..5aa289ce 100644 --- a/tools/src/librw11/Rw11UnitDiskBase.hpp +++ b/tools/src/librw11/Rw11UnitDiskBase.hpp @@ -1,4 +1,4 @@ -// $Id: Rw11UnitDiskBase.hpp 509 2013-04-21 20:46:20Z mueller $ +// $Id: Rw11UnitDiskBase.hpp 515 2013-05-04 17:28:59Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone() // 2013-04-14 506 1.0 Initial version // 2013-02-22 490 0.1 First draft // --------------------------------------------------------------------------- @@ -20,7 +21,7 @@ /*! \file - \version $Id: Rw11UnitDiskBase.hpp 509 2013-04-21 20:46:20Z mueller $ + \version $Id: Rw11UnitDiskBase.hpp 515 2013-05-04 17:28:59Z mueller $ \brief Declaration of class Rw11UnitDiskBase. */ @@ -43,8 +44,8 @@ namespace Retro { virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; protected: - virtual void AttachSetup(); - virtual void DetachCleanup(); + virtual void AttachDone(); + virtual void DetachDone(); protected: TC* fpCntl; diff --git a/tools/src/librw11/Rw11UnitDiskBase.ipp b/tools/src/librw11/Rw11UnitDiskBase.ipp index aef516f3..4ec24ed0 100644 --- a/tools/src/librw11/Rw11UnitDiskBase.ipp +++ b/tools/src/librw11/Rw11UnitDiskBase.ipp @@ -1,4 +1,4 @@ -// $Id: Rw11UnitDiskBase.ipp 509 2013-04-21 20:46:20Z mueller $ +// $Id: Rw11UnitDiskBase.ipp 515 2013-05-04 17:28:59Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone() // 2013-04-14 506 1.0 Initial version // 2013-02-22 490 0.1 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: Rw11UnitDiskBase.ipp 509 2013-04-21 20:46:20Z mueller $ + \version $Id: Rw11UnitDiskBase.ipp 515 2013-05-04 17:28:59Z mueller $ \brief Implemenation (inline) of Rw11UnitDiskBase. */ @@ -76,7 +77,7 @@ void Rw11UnitDiskBase::Dump(std::ostream& os, int ind, //! FIXME_docs template -void Rw11UnitDiskBase::AttachSetup() +void Rw11UnitDiskBase::AttachDone() { Virt()->Setup(BlockSize(), NBlock()); Cntl().UnitSetup(Index()); @@ -88,7 +89,7 @@ void Rw11UnitDiskBase::AttachSetup() //! FIXME_docs template -void Rw11UnitDiskBase::DetachCleanup() +void Rw11UnitDiskBase::DetachDone() { SetWProt(false); Cntl().UnitSetup(Index()); diff --git a/tools/src/librw11/Rw11UnitLP11.cpp b/tools/src/librw11/Rw11UnitLP11.cpp new file mode 100644 index 00000000..c82faf81 --- /dev/null +++ b/tools/src/librw11/Rw11UnitLP11.cpp @@ -0,0 +1,68 @@ +// $Id: Rw11UnitLP11.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rw11UnitLP11.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of Rw11UnitLP11. +*/ + +#include "boost/bind.hpp" + +#include "librtools/RosFill.hpp" +#include "Rw11CntlLP11.hpp" + +#include "Rw11UnitLP11.hpp" + +using namespace std; + +/*! + \class Retro::Rw11UnitLP11 + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Constructor + +Rw11UnitLP11::Rw11UnitLP11(Rw11CntlLP11* pcntl, size_t index) + : Rw11UnitStreamBase(pcntl, index) +{ + SetAttachOpts("?wonly"); // use write only (output) streams +} + +//------------------------------------------+----------------------------------- +//! Destructor + +Rw11UnitLP11::~Rw11UnitLP11() +{} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11UnitLP11::Dump(std::ostream& os, int ind, const char* text) const +{ + RosFill bl(ind); + os << bl << (text?text:"--") << "Rw11UnitLP11 @ " << this << endl; + Rw11UnitStreamBase::Dump(os, ind, " ^"); + return; +} + +} // end namespace Retro diff --git a/tools/src/librw11/Rw11UnitLP11.hpp b/tools/src/librw11/Rw11UnitLP11.hpp new file mode 100644 index 00000000..51d47ef5 --- /dev/null +++ b/tools/src/librw11/Rw11UnitLP11.hpp @@ -0,0 +1,53 @@ +// $Id: Rw11UnitLP11.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: Rw11UnitLP11.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class Rw11UnitLP11. +*/ + +#ifndef included_Retro_Rw11UnitLP11 +#define included_Retro_Rw11UnitLP11 1 + +#include "Rw11VirtStream.hpp" + +#include "Rw11UnitStreamBase.hpp" + +namespace Retro { + + class Rw11CntlLP11; // forw decl to avoid circular incl + + class Rw11UnitLP11 : public Rw11UnitStreamBase { + public: + + Rw11UnitLP11(Rw11CntlLP11* pcntl, size_t index); + ~Rw11UnitLP11(); + + virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; + + protected: + + }; + +} // end namespace Retro + +//#include "Rw11UnitLP11.ipp" + +#endif diff --git a/tools/src/librw11/Rw11UnitPC11.cpp b/tools/src/librw11/Rw11UnitPC11.cpp new file mode 100644 index 00000000..6af19987 --- /dev/null +++ b/tools/src/librw11/Rw11UnitPC11.cpp @@ -0,0 +1,71 @@ +// $Id: Rw11UnitPC11.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-03 515 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rw11UnitPC11.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of Rw11UnitPC11. +*/ + +#include "boost/bind.hpp" + +#include "librtools/RosFill.hpp" +#include "Rw11CntlPC11.hpp" + +#include "Rw11UnitPC11.hpp" + +using namespace std; + +/*! + \class Retro::Rw11UnitPC11 + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Constructor + +Rw11UnitPC11::Rw11UnitPC11(Rw11CntlPC11* pcntl, size_t index) + : Rw11UnitStreamBase(pcntl, index) +{ + // unit 0 -> reader -> read only stream + // unit 1 -> puncher -> write only stream + const char* opts = (index==0) ? "?ronly" : "?wonly"; + SetAttachOpts(opts); +} + +//------------------------------------------+----------------------------------- +//! Destructor + +Rw11UnitPC11::~Rw11UnitPC11() +{} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11UnitPC11::Dump(std::ostream& os, int ind, const char* text) const +{ + RosFill bl(ind); + os << bl << (text?text:"--") << "Rw11UnitPC11 @ " << this << endl; + Rw11UnitStreamBase::Dump(os, ind, " ^"); + return; +} + +} // end namespace Retro diff --git a/tools/src/librw11/Rw11UnitPC11.hpp b/tools/src/librw11/Rw11UnitPC11.hpp new file mode 100644 index 00000000..276d4ca0 --- /dev/null +++ b/tools/src/librw11/Rw11UnitPC11.hpp @@ -0,0 +1,53 @@ +// $Id: Rw11UnitPC11.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-03 515 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: Rw11UnitPC11.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class Rw11UnitPC11. +*/ + +#ifndef included_Retro_Rw11UnitPC11 +#define included_Retro_Rw11UnitPC11 1 + +#include "Rw11VirtStream.hpp" + +#include "Rw11UnitStreamBase.hpp" + +namespace Retro { + + class Rw11CntlPC11; // forw decl to avoid circular incl + + class Rw11UnitPC11 : public Rw11UnitStreamBase { + public: + + Rw11UnitPC11(Rw11CntlPC11* pcntl, size_t index); + ~Rw11UnitPC11(); + + virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; + + protected: + + }; + +} // end namespace Retro + +//#include "Rw11UnitPC11.ipp" + +#endif diff --git a/tools/src/librw11/Rw11UnitStream.cpp b/tools/src/librw11/Rw11UnitStream.cpp new file mode 100644 index 00000000..1a3148ea --- /dev/null +++ b/tools/src/librw11/Rw11UnitStream.cpp @@ -0,0 +1,135 @@ +// $Id: Rw11UnitStream.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-04 515 1.0 Initial version +// 2013-05-01 513 0.1 First draft +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rw11UnitStream.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of Rw11UnitStream. +*/ + +#include "librtools/Rexception.hpp" + +#include "Rw11UnitStream.hpp" + +using namespace std; + +/*! + \class Retro::Rw11UnitStream + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Constructor + +Rw11UnitStream::Rw11UnitStream(Rw11Cntl* pcntl, size_t index) + : Rw11UnitVirt(pcntl, index) +{ + fStats.Define(kStatNPreAttDrop, "NPreAttDrop", + "output bytes dropped prior attach"); + fStats.Define(kStatNPreAttMiss, "NPreAttMiss", + "input bytes missed prior attach"); +} + +//------------------------------------------+----------------------------------- +//! Destructor + +Rw11UnitStream::~Rw11UnitStream() +{} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11UnitStream::SetPos(int pos) +{ + if (!Virt()) + throw Rexception("Rw11UnitStream::SetPos", "no stream attached"); + + RerrMsg emsg; + if (!Virt()->Seek(pos, emsg)) throw Rexception(emsg); + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +int Rw11UnitStream::Pos() const +{ + if (!Virt()) + throw Rexception("Rw11UnitStream::Pos", "no stream attached"); + + RerrMsg emsg; + int irc = Virt()->Tell(emsg); + if (irc < 0) throw Rexception(emsg); + return irc; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +int Rw11UnitStream::VirtRead(uint8_t* data, size_t count, RerrMsg& emsg) +{ + if (!Virt()) { + fStats.Inc(kStatNPreAttMiss); + emsg.Init("Rw11UnitStream::VirtRead", "no stream attached"); + return -1; + } + return Virt()->Read(data, count, emsg); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +bool Rw11UnitStream::VirtWrite(const uint8_t* data, size_t count, RerrMsg& emsg) +{ + if (!Virt()) { + fStats.Inc(kStatNPreAttDrop, double(count)); + emsg.Init("Rw11UnitStream::VirtWrite", "no stream attached"); + return false; + } + return Virt()->Write(data, count, emsg); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +bool Rw11UnitStream::VirtFlush(RerrMsg& emsg) +{ + if (!Virt()) { + emsg.Init("Rw11UnitStream::VirtFlush", "no stream attached"); + return false; + } + return Virt()->Flush(emsg); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11UnitStream::Dump(std::ostream& os, int ind, const char* text) const +{ + RosFill bl(ind); + os << bl << (text?text:"--") << "Rw11UnitStream @ " << this << endl; + Rw11UnitVirt::Dump(os, ind, " ^"); + return; +} + + +} // end namespace Retro diff --git a/tools/src/librw11/Rw11UnitStream.hpp b/tools/src/librw11/Rw11UnitStream.hpp new file mode 100644 index 00000000..7fa5f906 --- /dev/null +++ b/tools/src/librw11/Rw11UnitStream.hpp @@ -0,0 +1,64 @@ +// $Id: Rw11UnitStream.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-04 515 1.0 Initial version +// 2013-05-01 513 0.1 First draft +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: Rw11UnitStream.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class Rw11UnitStream. +*/ + +#ifndef included_Retro_Rw11UnitStream +#define included_Retro_Rw11UnitStream 1 + +#include "Rw11VirtStream.hpp" + +#include "Rw11UnitVirt.hpp" + +namespace Retro { + + class Rw11UnitStream : public Rw11UnitVirt { + public: + Rw11UnitStream(Rw11Cntl* pcntl, size_t index); + ~Rw11UnitStream(); + + void SetPos(int pos); + int Pos() const; + + int VirtRead(uint8_t* data, size_t count, RerrMsg& emsg); + bool VirtWrite(const uint8_t* data, size_t count, RerrMsg& emsg); + bool VirtFlush(RerrMsg& emsg); + + virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; + + // statistics counter indices + enum stats { + kStatNPreAttDrop = Rw11Unit::kDimStat, + kStatNPreAttMiss, + kDimStat + }; + + protected: + }; + +} // end namespace Retro + +//#include "Rw11UnitStream.ipp" + +#endif diff --git a/tools/src/librw11/Rw11UnitBase.hpp b/tools/src/librw11/Rw11UnitStreamBase.hpp similarity index 55% rename from tools/src/librw11/Rw11UnitBase.hpp rename to tools/src/librw11/Rw11UnitStreamBase.hpp index ade2f057..0df1914d 100644 --- a/tools/src/librw11/Rw11UnitBase.hpp +++ b/tools/src/librw11/Rw11UnitStreamBase.hpp @@ -1,4 +1,4 @@ -// $Id: Rw11UnitBase.hpp 495 2013-03-06 17:13:48Z mueller $ +// $Id: Rw11UnitStreamBase.hpp 515 2013-05-04 17:28:59Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,49 +13,45 @@ // // Revision History: // Date Rev Version Comment -// 2013-03-06 495 1.0 Initial version -// 2013-02-14 488 0.1 First draft +// 2013-05-04 515 1.0 Initial version +// 2013-05-01 513 0.1 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: Rw11UnitBase.hpp 495 2013-03-06 17:13:48Z mueller $ - \brief Declaration of class Rw11UnitBase. + \version $Id: Rw11UnitStreamBase.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class Rw11UnitStreamBase. */ -#ifndef included_Retro_Rw11UnitBase -#define included_Retro_Rw11UnitBase 1 +#ifndef included_Retro_Rw11UnitStreamBase +#define included_Retro_Rw11UnitStreamBase 1 -#include "boost/scoped_ptr.hpp" - -#include "Rw11Unit.hpp" +#include "Rw11UnitStream.hpp" namespace Retro { - template - class Rw11UnitBase : public Rw11Unit { + template + class Rw11UnitStreamBase : public Rw11UnitStream { public: - Rw11UnitBase(TC* pcntl, size_t index); - ~Rw11UnitBase(); + Rw11UnitStreamBase(TC* pcntl, size_t index); + ~Rw11UnitStreamBase(); TC& Cntl() const; - TV* Virt() const; - - virtual bool Attach(const std::string& url, RerrMsg& emsg); - virtual void Detach(); virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; protected: - TC* fpCntl; - boost::scoped_ptr fpVirt; + virtual void AttachDone(); + virtual void DetachDone(); + protected: + TC* fpCntl; }; } // end namespace Retro -#include "Rw11UnitBase.ipp" +#include "Rw11UnitStreamBase.ipp" #endif diff --git a/tools/src/librw11/Rw11UnitStreamBase.ipp b/tools/src/librw11/Rw11UnitStreamBase.ipp new file mode 100644 index 00000000..a2967e4b --- /dev/null +++ b/tools/src/librw11/Rw11UnitStreamBase.ipp @@ -0,0 +1,96 @@ +// $Id: Rw11UnitStreamBase.ipp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-04 515 1.0 Initial version +// 2013-05-01 513 0.1 First draft +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rw11UnitStreamBase.ipp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation (inline) of Rw11UnitStreamBase. +*/ + +#include "Rw11UnitStreamBase.hpp" + +/*! + \class Retro::Rw11UnitStreamBase + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Default constructor + +template +Rw11UnitStreamBase::Rw11UnitStreamBase(TC* pcntl, size_t index) + : Rw11UnitStream(pcntl, index), + fpCntl(pcntl) +{} + +//------------------------------------------+----------------------------------- +//! Destructor + +template +Rw11UnitStreamBase::~Rw11UnitStreamBase() +{} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +template +inline TC& Rw11UnitStreamBase::Cntl() const +{ + return *fpCntl; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +template +void Rw11UnitStreamBase::Dump(std::ostream& os, int ind, + const char* text) const +{ + RosFill bl(ind); + os << bl << (text?text:"--") << "Rw11UnitStreamBase @ " << this << std::endl; + os << bl << " fpCntl: " << fpCntl << std::endl; + Rw11UnitStream::Dump(os, ind, " ^"); + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +template +void Rw11UnitStreamBase::AttachDone() +{ + Cntl().UnitSetup(Index()); + return; +} + + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +template +void Rw11UnitStreamBase::DetachDone() +{ + Cntl().UnitSetup(Index()); + return; +} + +} // end namespace Retro diff --git a/tools/src/librw11/Rw11UnitTerm.cpp b/tools/src/librw11/Rw11UnitTerm.cpp index acf7b2f7..69c7c98f 100644 --- a/tools/src/librw11/Rw11UnitTerm.cpp +++ b/tools/src/librw11/Rw11UnitTerm.cpp @@ -1,4 +1,4 @@ -// $Id: Rw11UnitTerm.cpp 508 2013-04-20 18:43:28Z mueller $ +// $Id: Rw11UnitTerm.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone() // 2013-04-13 504 1.0 Initial version // 2013-02-19 490 0.1 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: Rw11UnitTerm.cpp 508 2013-04-20 18:43:28Z mueller $ + \version $Id: Rw11UnitTerm.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of Rw11UnitTerm. */ @@ -93,7 +94,9 @@ void Rw11UnitTerm::SetLog(const std::string& fname) RparseUrl purl; RerrMsg emsg; - if (!purl.Set(fname, "|app|crlf|", emsg)) + if (!purl.Set(fname, "|app|bck=|crlf|", emsg)) + throw Rexception(emsg); + if (!Rtools::CreateBackupFile(purl, emsg)) throw Rexception(emsg); ios_base::openmode mode = ios_base::out; @@ -309,7 +312,7 @@ void Rw11UnitTerm::Dump(std::ostream& os, int ind, const char* text) const //------------------------------------------+----------------------------------- //! FIXME_docs -void Rw11UnitTerm::AttachSetup() +void Rw11UnitTerm::AttachDone() { fpVirt->SetupRcvCallback(boost::bind(&Rw11UnitTerm::RcvCallback, this, _1, _2)); diff --git a/tools/src/librw11/Rw11UnitTerm.hpp b/tools/src/librw11/Rw11UnitTerm.hpp index a0289bc3..9b87e7dc 100644 --- a/tools/src/librw11/Rw11UnitTerm.hpp +++ b/tools/src/librw11/Rw11UnitTerm.hpp @@ -1,4 +1,4 @@ -// $Id: Rw11UnitTerm.hpp 508 2013-04-20 18:43:28Z mueller $ +// $Id: Rw11UnitTerm.hpp 515 2013-05-04 17:28:59Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone() // 2013-04-20 508 1.0.1 add 7bit and non-printable masking; add log file // 2013-04-13 504 1.0 Initial version // 2013-02-19 490 0.1 First draft @@ -21,7 +22,7 @@ /*! \file - \version $Id: Rw11UnitTerm.hpp 508 2013-04-20 18:43:28Z mueller $ + \version $Id: Rw11UnitTerm.hpp 515 2013-05-04 17:28:59Z mueller $ \brief Declaration of class Rw11UnitTerm. */ @@ -74,7 +75,7 @@ namespace Retro { }; protected: - virtual void AttachSetup(); + virtual void AttachDone(); protected: bool fTo7bit; // // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-03 515 1.1 use AttachDone(),DetachCleanup(),DetachDone() // 2013-03-03 494 1.0 Initial version // 2013-02-05 483 0.1 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: Rw11UnitVirt.ipp 504 2013-04-13 15:37:24Z mueller $ + \version $Id: Rw11UnitVirt.ipp 515 2013-05-04 17:28:59Z mueller $ \brief Implemenation (inline) of Rw11UnitVirt. */ @@ -70,9 +71,9 @@ inline bool Rw11UnitVirt::Attach(const std::string& url, RerrMsg& emsg) { // synchronize with server thread boost::lock_guard lock(Connect()); - if (fpVirt) DetachCleanup(); + if (fpVirt) Detach(); fpVirt.reset(TV::New(url, this, emsg)); - if (fpVirt) AttachSetup(); + if (fpVirt) AttachDone(); return fpVirt; } @@ -84,8 +85,10 @@ inline void Rw11UnitVirt::Detach() { // synchronize with server thread boost::lock_guard lock(Connect()); - if (fpVirt) DetachCleanup(); + if (!fpVirt) return; + DetachCleanup(); fpVirt.reset(); + DetachDone(); return; } diff --git a/tools/src/librw11/Rw11VirtDiskFile.cpp b/tools/src/librw11/Rw11VirtDiskFile.cpp index 96b005ce..845b19ab 100644 --- a/tools/src/librw11/Rw11VirtDiskFile.cpp +++ b/tools/src/librw11/Rw11VirtDiskFile.cpp @@ -1,4 +1,4 @@ -// $Id: Rw11VirtDiskFile.cpp 509 2013-04-21 20:46:20Z mueller $ +// $Id: Rw11VirtDiskFile.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -19,7 +19,7 @@ /*! \file - \version $Id: Rw11VirtDiskFile.cpp 509 2013-04-21 20:46:20Z mueller $ + \version $Id: Rw11VirtDiskFile.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of Rw11VirtDiskFile. */ @@ -70,16 +70,14 @@ bool Rw11VirtDiskFile::Open(const std::string& url, RerrMsg& emsg) int fd = ::open(fUrl.Path().c_str(), wpro ? O_RDONLY : O_RDWR); if (fd < 0) { emsg.InitErrno("Rw11VirtDiskFile::Open()", - string("open() for '") + fUrl.Path() + string("' failed: "), - errno); + string("open() for '") + fUrl.Path() + "' failed: ", errno); return false; } struct stat sbuf; if (::fstat(fd, &sbuf) < 0) { emsg.InitErrno("Rw11VirtDiskFile::Open()", - string("stat() for '") + fUrl.Path() + string("' failed: "), - errno); + string("stat() for '") + fUrl.Path() + "' failed: ", errno); return false; } @@ -138,8 +136,7 @@ bool Rw11VirtDiskFile::Write(size_t lba, size_t nblk, const uint8_t* data, ssize_t irc = ::write(fFd, data, nbyt); if (irc < ssize_t(nbyt)) { - emsg.InitErrno("Rw11VirtDiskFile::Write()", string("write() failed: "), - errno); + emsg.InitErrno("Rw11VirtDiskFile::Write()", "write() failed: ", errno); return false; } @@ -154,8 +151,7 @@ bool Rw11VirtDiskFile::Write(size_t lba, size_t nblk, const uint8_t* data, bool Rw11VirtDiskFile::Seek(size_t seekpos, RerrMsg& emsg) { if (::lseek(fFd, seekpos, SEEK_SET) < 0) { - emsg.InitErrno("Rw11VirtDiskFile::Seek()", string("seek() failed: "), - errno); + emsg.InitErrno("Rw11VirtDiskFile::Seek()", "seek() failed: ", errno); return false; } diff --git a/tools/src/librw11/Rw11VirtStream.cpp b/tools/src/librw11/Rw11VirtStream.cpp new file mode 100644 index 00000000..0a408c7a --- /dev/null +++ b/tools/src/librw11/Rw11VirtStream.cpp @@ -0,0 +1,238 @@ +// $Id: Rw11VirtStream.cpp 516 2013-05-05 21:24:52Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-05 516 1.0.1 Open(): support ?app and ?bck=n options +// 2013-05-04 515 1.0 Initial version +// 2013-05-01 513 0.1 First draft +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rw11VirtStream.cpp 516 2013-05-05 21:24:52Z mueller $ + \brief Implemenation of Rw11VirtStream. +*/ +#include + +#include "librtools/Rtools.hpp" +#include "librtools/Rexception.hpp" +#include "librtools/RparseUrl.hpp" +#include "librtools/RosFill.hpp" + +#include "Rw11VirtStream.hpp" + +using namespace std; + +/*! + \class Retro::Rw11VirtStream + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Default constructor + +Rw11VirtStream::Rw11VirtStream(Rw11Unit* punit) + : Rw11Virt(punit), + fIStream(false), + fOStream(false), + fFile(0) +{ + fStats.Define(kStatNVSRead, "NVSRead", "Read() calls"); + fStats.Define(kStatNVSReadByt, "NVSReadByt", "bytes read"); + fStats.Define(kStatNVSWrite, "NVSWrite", "Write() calls"); + fStats.Define(kStatNVSWriteByt,"NVSWriteByt", "bytes written"); + fStats.Define(kStatNVSFlush, "NVSFlush", "Flush() calls"); + fStats.Define(kStatNVSTell, "NVSTell", "Tell() calls"); + fStats.Define(kStatNVSSeek, "NVSSeek", "Seek() calls"); +} + +//------------------------------------------+----------------------------------- +//! Destructor + +Rw11VirtStream::~Rw11VirtStream() +{ + if (fFile) ::fclose(fFile); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +bool Rw11VirtStream::Open(const std::string& url, RerrMsg& emsg) +{ + RparseUrl opts; + if (!opts.Set(fpUnit->AttachOpts(), "|ronly|wonly|", emsg)) return false; + fIStream = opts.FindOpt("ronly"); + fOStream = opts.FindOpt("wonly"); + if (!(fIStream ^ fOStream)) + throw Rexception("Rw11VirtStream::Open", + "Bad state: neither ronly nor wonly seen"); + + if (fOStream) { // handle output streams + if (!fUrl.Set(url, "|app|bck=|", emsg)) return false; + if (!Rtools::CreateBackupFile(fUrl, emsg)) return false; + + fFile = ::fopen(fUrl.Path().c_str(), fUrl.FindOpt("app") ? "a" : "w"); + + } else { // handle input streams + if (!fUrl.Set(url, "", emsg)) return false; + fFile = ::fopen(fUrl.Path().c_str(), "r"); + } + + if (!fFile) { + emsg.InitErrno("Rw11VirtStream::Open()", + string("fopen() for '") + fUrl.Path() + "' failed: ", + errno); + return false; + } + + return true; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +int Rw11VirtStream::Read(uint8_t* data, size_t count, RerrMsg& emsg) +{ + if (!fIStream) + throw Rexception("Rw11VirtStream::Read", + "Bad state: Read() called but fIStream=false"); + if (!fFile) + throw Rexception("Rw11VirtStream::Read", "Bad state: file not open"); + + fStats.Inc(kStatNVSRead); + size_t irc = ::fread(data, 1, count, fFile); + if (irc == 0 && ferror(fFile)) { + emsg.InitErrno("Rw11VirtStream::Read()", "fread() failed: ", errno); + return -1; + } + + fStats.Inc(kStatNVSReadByt, double(irc)); + return int(irc); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +bool Rw11VirtStream::Write(const uint8_t* data, size_t count, RerrMsg& emsg) +{ + if (!fOStream) + throw Rexception("Rw11VirtStream::Write", + "Bad state: Write() called but fOStream=false"); + if (!fFile) + throw Rexception("Rw11VirtStream::Write", "Bad state: file not open"); + + fStats.Inc(kStatNVSWrite); + size_t irc = ::fwrite(data, 1, count, fFile); + if (irc != count) { + emsg.InitErrno("Rw11VirtStream::Write()", "fwrite() failed: ", errno); + return false; + } + + fStats.Inc(kStatNVSWriteByt, double(count)); + return true; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +bool Rw11VirtStream::Flush(RerrMsg& emsg) +{ + if (!fOStream) return true; + if (!fFile) + throw Rexception("Rw11VirtStream::Write", "Bad state: file not open"); + + fStats.Inc(kStatNVSFlush); + size_t irc = ::fflush(fFile); + if (irc != 0) { + emsg.InitErrno("Rw11VirtStream::Flush()", "fflush() failed: ", errno); + return false; + } + + return true; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +int Rw11VirtStream::Tell(RerrMsg& emsg) +{ + if (!fFile) + throw Rexception("Rw11VirtStream::Tell", "Bad state: file not open"); + + fStats.Inc(kStatNVSTell); + long irc = ::ftell(fFile); + if (irc < 0) { + emsg.InitErrno("Rw11VirtStream::Tell()", "ftell() failed: ", errno); + return -1; + } + + return int(irc); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +bool Rw11VirtStream::Seek(int pos, RerrMsg& emsg) +{ + if (!fFile) + throw Rexception("Rw11VirtStream::Seek", "Bad state: file not open"); + + fStats.Inc(kStatNVSSeek); + int whence = SEEK_SET; + if (pos < 0) { + pos = 0; + whence = SEEK_END; + } + int irc = ::fseek(fFile, pos, whence); + + if (irc < 0) { + emsg.InitErrno("Rw11VirtStream::Seek()", "fseek() failed: ", errno); + return false; + } + + return true; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11VirtStream::Dump(std::ostream& os, int ind, const char* text) const +{ + RosFill bl(ind); + os << bl << (text?text:"--") << "Rw11VirtStream @ " << this << endl; + + os << bl << " fIStream: " << fIStream << endl; + os << bl << " fOStream: " << fOStream << endl; + os << bl << " fFile: " << fFile << endl; + Rw11Virt::Dump(os, ind, " ^"); + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +Rw11VirtStream* Rw11VirtStream::New(const std::string& url, Rw11Unit* punit, + RerrMsg& emsg) +{ + unique_ptr p; + p.reset(new Rw11VirtStream(punit)); + if (p->Open(url, emsg)) return p.release(); + return 0; +} + + +} // end namespace Retro diff --git a/tools/src/librw11/Rw11VirtStream.hpp b/tools/src/librw11/Rw11VirtStream.hpp new file mode 100644 index 00000000..833e00d9 --- /dev/null +++ b/tools/src/librw11/Rw11VirtStream.hpp @@ -0,0 +1,75 @@ +// $Id: Rw11VirtStream.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-04 515 1.0 Initial version +// 2013-05-01 513 0.1 First draft +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rw11VirtStream.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class Rw11VirtStream. +*/ + +#ifndef included_Retro_Rw11VirtStream +#define included_Retro_Rw11VirtStream 1 + +#include + +#include "Rw11Virt.hpp" + +namespace Retro { + + class Rw11VirtStream : public Rw11Virt { + public: + + explicit Rw11VirtStream(Rw11Unit* punit); + ~Rw11VirtStream(); + + bool Open(const std::string& url, RerrMsg& emsg); + int Read(uint8_t* data, size_t count, RerrMsg& emsg); + bool Write(const uint8_t* data, size_t count, RerrMsg& emsg); + bool Flush(RerrMsg& emsg); + int Tell(RerrMsg& emsg); + bool Seek(int pos, RerrMsg& emsg); + + virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const; + + static Rw11VirtStream* New(const std::string& url, Rw11Unit* punit, + RerrMsg& emsg); + + // statistics counter indices + enum stats { + kStatNVSRead = Rw11Virt::kDimStat, + kStatNVSReadByt, + kStatNVSWrite, + kStatNVSWriteByt, + kStatNVSFlush, + kStatNVSTell, + kStatNVSSeek, + kDimStat + }; + + protected: + bool fIStream; // // @@ -13,6 +13,7 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-05 516 1.0.2 fix mistakes in emsg generation with errno // 2013-04-20 508 1.0.1 add fSndPreConQue handling // 2013-03-06 495 1.0 Initial version // 2013-02-13 488 0.1 First draft @@ -20,7 +21,7 @@ /*! \file - \version $Id: Rw11VirtTermTcp.cpp 508 2013-04-20 18:43:28Z mueller $ + \version $Id: Rw11VirtTermTcp.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of Rw11VirtTermTcp. */ @@ -215,8 +216,8 @@ bool Rw11VirtTermTcp::Snd(const uint8_t* data, size_t count, RerrMsg& emsg) if (irc < 0) { RlogMsg lmsg(LogFile(),'E'); RerrMsg emsg("Rw11VirtTermTcp::Snd", - string("write() for port ") + fChannelId + - string(" failed: ", errno)); + string("write() for port ") + fChannelId + " failed: ", + errno); lmsg << emsg; } else { fStats.Inc(kStatNVTSndRaw, double(irc)); @@ -268,8 +269,8 @@ int Rw11VirtTermTcp::ListenPollHandler(const pollfd& pfd) if (fFd < 0) { RlogMsg lmsg(LogFile(),'E'); RerrMsg emsg("Rw11VirtTermTcp::ListenPollHandler", - string("accept() for port ") + fChannelId + - string(" failed: ", errno)); + string("accept() for port ") + fChannelId + " failed: ", + errno); lmsg << emsg; // FIXME_code: proper error handling return 0; @@ -317,8 +318,8 @@ int Rw11VirtTermTcp::ListenPollHandler(const pollfd& pfd) fFd = -1; RlogMsg lmsg(LogFile(),'E'); RerrMsg emsg("Rw11VirtTermTcp::ListenPollHandler", - string("initial write()s for port ") + fChannelId + - string(" failed: ", errno)); + string("initial write()s for port ") + fChannelId + + " failed: ", errno); lmsg << emsg; return 0; } @@ -408,8 +409,8 @@ int Rw11VirtTermTcp::RcvPollHandler(const pollfd& pfd) if (irc < 0) { RlogMsg lmsg(LogFile(),'E'); RerrMsg emsg("Rw11VirtTermTcp::ListenPollHandler", - string("read() for port ") + fChannelId + - string(" failed: ", errno)); + string("read() for port ") + fChannelId + " failed: ", + errno); lmsg << emsg; } if (fTcpTrace) { diff --git a/tools/src/librwxxtpp/Makefile b/tools/src/librwxxtpp/Makefile index afd84d6d..c5cb1875 100644 --- a/tools/src/librwxxtpp/Makefile +++ b/tools/src/librwxxtpp/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 504 2013-04-13 15:37:24Z mueller $ +# $Id: Makefile 515 2013-05-04 17:28:59Z mueller $ # # Revision History: # Date Rev Version Comment @@ -29,8 +29,11 @@ OBJ_all += RtclRw11Cntl.o RtclRw11CntlFactory.o OBJ_all += RtclRw11Unit.o OBJ_all += RtclRw11UnitTerm.o OBJ_all += RtclRw11UnitDisk.o +OBJ_all += RtclRw11UnitStream.o OBJ_all += RtclRw11CntlDL11.o RtclRw11UnitDL11.o OBJ_all += RtclRw11CntlRK11.o RtclRw11UnitRK11.o +OBJ_all += RtclRw11CntlLP11.o RtclRw11UnitLP11.o +OBJ_all += RtclRw11CntlPC11.o RtclRw11UnitPC11.o # DEP_all = $(OBJ_all:.o=.dep) # diff --git a/tools/src/librwxxtpp/RtclRw11.cpp b/tools/src/librwxxtpp/RtclRw11.cpp index d7a027ea..5a272898 100644 --- a/tools/src/librwxxtpp/RtclRw11.cpp +++ b/tools/src/librwxxtpp/RtclRw11.cpp @@ -1,4 +1,4 @@ -// $Id: RtclRw11.cpp 504 2013-04-13 15:37:24Z mueller $ +// $Id: RtclRw11.cpp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -19,7 +19,7 @@ /*! \file - \version $Id: RtclRw11.cpp 504 2013-04-13 15:37:24Z mueller $ + \version $Id: RtclRw11.cpp 513 2013-05-01 14:02:06Z mueller $ \brief Implemenation of class RtclRw11. */ @@ -143,7 +143,7 @@ int RtclRw11::M_default(RtclArgs& args) if (!args.AllDone()) return kERR; ostringstream sos; - sos << "cpu type base : cntl type ibbase probe lam boot" << endl; + sos << "cpu type base : cntl type ibbase probe lam boot" << endl; for (size_t i=0; i 0) sos << " " << RosPrintf(cntl.Lam(),"d",3); else sos << " -"; uint16_t aload; diff --git a/tools/src/librwxxtpp/RtclRw11CntlDL11.cpp b/tools/src/librwxxtpp/RtclRw11CntlDL11.cpp index b8673637..c92b6cfe 100644 --- a/tools/src/librwxxtpp/RtclRw11CntlDL11.cpp +++ b/tools/src/librwxxtpp/RtclRw11CntlDL11.cpp @@ -1,4 +1,4 @@ -// $Id: RtclRw11CntlDL11.cpp 504 2013-04-13 15:37:24Z mueller $ +// $Id: RtclRw11CntlDL11.cpp 516 2013-05-05 21:24:52Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-04 516 1.0.1 add RxRlim support (receive interrupt rate limit) // 2013-03-06 495 1.0 Initial version // 2013-02-02 480 0.1 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: RtclRw11CntlDL11.cpp 504 2013-04-13 15:37:24Z mueller $ + \version $Id: RtclRw11CntlDL11.cpp 516 2013-05-05 21:24:52Z mueller $ \brief Implemenation of RtclRw11CntlDL11. */ @@ -44,7 +45,11 @@ namespace Retro { RtclRw11CntlDL11::RtclRw11CntlDL11() : RtclRw11CntlBase("Rw11CntlDL11") { - //Rw11CntlDL11* pobj = &Obj(); + Rw11CntlDL11* pobj = &Obj(); + fGets.Add ("rxrlim", + boost::bind(&Rw11CntlDL11::RxRlim, pobj)); + fSets.Add ("rxrlim", + boost::bind(&Rw11CntlDL11::SetRxRlim,pobj, _1)); } //------------------------------------------+----------------------------------- diff --git a/tools/src/librwxxtpp/RtclRw11CntlFactory.cpp b/tools/src/librwxxtpp/RtclRw11CntlFactory.cpp index 4700cb89..4d11322d 100644 --- a/tools/src/librwxxtpp/RtclRw11CntlFactory.cpp +++ b/tools/src/librwxxtpp/RtclRw11CntlFactory.cpp @@ -1,4 +1,4 @@ -// $Id: RtclRw11CntlFactory.cpp 504 2013-04-13 15:37:24Z mueller $ +// $Id: RtclRw11CntlFactory.cpp 515 2013-05-04 17:28:59Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -13,13 +13,14 @@ // // Revision History: // Date Rev Version Comment +// 2013-05-01 513 1.0.1 add LP11 // 2013-03-06 495 1.0 Initial version // 2013-02-09 489 0.1 First draft // --------------------------------------------------------------------------- /*! \file - \version $Id: RtclRw11CntlFactory.cpp 504 2013-04-13 15:37:24Z mueller $ + \version $Id: RtclRw11CntlFactory.cpp 515 2013-05-04 17:28:59Z mueller $ \brief Implemenation of global function RtclRw11CntlFactory. */ @@ -29,6 +30,8 @@ #include "RtclRw11CntlDL11.hpp" #include "RtclRw11CntlRK11.hpp" +#include "RtclRw11CntlLP11.hpp" +#include "RtclRw11CntlPC11.hpp" using namespace std; @@ -54,6 +57,16 @@ int RtclRw11CntlFactory(RtclArgs& args, RtclRw11Cpu& cpu) if(pobj->FactoryCmdConfig(args, cpu) != TCL_OK) return TCL_ERROR; pobj.release(); + } else if (type == "lp11") { // lp11 -------------------------- + unique_ptr pobj(new RtclRw11CntlLP11()); + if(pobj->FactoryCmdConfig(args, cpu) != TCL_OK) return TCL_ERROR; + pobj.release(); + + } else if (type == "pc11") { // pc11 -------------------------- + unique_ptr pobj(new RtclRw11CntlPC11()); + if(pobj->FactoryCmdConfig(args, cpu) != TCL_OK) return TCL_ERROR; + pobj.release(); + } else { // unknown cntl type ------------- return args.Quit(string("-E: unknown controller type '") + type + "'"); } diff --git a/tools/src/librwxxtpp/RtclRw11CntlLP11.cpp b/tools/src/librwxxtpp/RtclRw11CntlLP11.cpp new file mode 100644 index 00000000..b2bf14f1 --- /dev/null +++ b/tools/src/librwxxtpp/RtclRw11CntlLP11.cpp @@ -0,0 +1,96 @@ +// $Id: RtclRw11CntlLP11.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: RtclRw11CntlLP11.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of RtclRw11CntlLP11. +*/ + +#include "librtcltools/RtclNameSet.hpp" + +#include "RtclRw11CntlLP11.hpp" +#include "RtclRw11UnitLP11.hpp" + +using namespace std; + +/*! + \class Retro::RtclRw11CntlLP11 + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Constructor + +RtclRw11CntlLP11::RtclRw11CntlLP11() + : RtclRw11CntlBase("Rw11CntlLP11") +{ + //Rw11CntlLP11* pobj = &Obj(); +} + +//------------------------------------------+----------------------------------- +//! Destructor + +RtclRw11CntlLP11::~RtclRw11CntlLP11() +{} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +int RtclRw11CntlLP11::FactoryCmdConfig(RtclArgs& args, RtclRw11Cpu& cpu) +{ + static RtclNameSet optset("-base|-lam"); + + string cntlname(cpu.Obj().NextCntlName("lp")); + string cntlcmd = cpu.CommandName() + cntlname; + + uint16_t base = Rw11CntlLP11::kIbaddr; + int lam = Rw11CntlLP11::kLam; + + string opt; + while (args.NextOpt(opt, optset)) { + if (opt == "-base") { + if (!args.GetArg("base", base, 0177776, 0160000)) return kERR; + } else if (opt == "-lam") { + if (!args.GetArg("lam", lam, 0, 15)) return kERR; + } + } + if (!args.AllDone()) return kERR; + + // configure controller + Obj().Config(cntlname, base, lam); + + // install in CPU + cpu.Obj().AddCntl(dynamic_pointer_cast(ObjSPtr())); + + // finally create tcl command + CreateObjectCmd(args.Interp(), cntlcmd.c_str()); + + // and create unit commands + for (size_t i=0; i +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: RtclRw11CntlLP11.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class RtclRw11CntlLP11. +*/ + +#ifndef included_Retro_RtclRw11CntlLP11 +#define included_Retro_RtclRw11CntlLP11 1 + +#include "RtclRw11CntlBase.hpp" +#include "librw11/Rw11CntlLP11.hpp" + +namespace Retro { + + class RtclRw11CntlLP11 : public RtclRw11CntlBase { + public: + RtclRw11CntlLP11(); + ~RtclRw11CntlLP11(); + + virtual int FactoryCmdConfig(RtclArgs& args, RtclRw11Cpu& cpu); + }; + +} // end namespace Retro + +//#include "RtclRw11CntlLP11.ipp" + +#endif diff --git a/tools/src/librwxxtpp/RtclRw11CntlPC11.cpp b/tools/src/librwxxtpp/RtclRw11CntlPC11.cpp new file mode 100644 index 00000000..7d59c502 --- /dev/null +++ b/tools/src/librwxxtpp/RtclRw11CntlPC11.cpp @@ -0,0 +1,96 @@ +// $Id: RtclRw11CntlPC11.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-03 515 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: RtclRw11CntlPC11.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of RtclRw11CntlPC11. +*/ + +#include "librtcltools/RtclNameSet.hpp" + +#include "RtclRw11CntlPC11.hpp" +#include "RtclRw11UnitPC11.hpp" + +using namespace std; + +/*! + \class Retro::RtclRw11CntlPC11 + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Constructor + +RtclRw11CntlPC11::RtclRw11CntlPC11() + : RtclRw11CntlBase("Rw11CntlPC11") +{ + //Rw11CntlPC11* pobj = &Obj(); +} + +//------------------------------------------+----------------------------------- +//! Destructor + +RtclRw11CntlPC11::~RtclRw11CntlPC11() +{} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +int RtclRw11CntlPC11::FactoryCmdConfig(RtclArgs& args, RtclRw11Cpu& cpu) +{ + static RtclNameSet optset("-base|-lam"); + + string cntlname(cpu.Obj().NextCntlName("pc")); + string cntlcmd = cpu.CommandName() + cntlname; + + uint16_t base = Rw11CntlPC11::kIbaddr; + int lam = Rw11CntlPC11::kLam; + + string opt; + while (args.NextOpt(opt, optset)) { + if (opt == "-base") { + if (!args.GetArg("base", base, 0177776, 0160000)) return kERR; + } else if (opt == "-lam") { + if (!args.GetArg("lam", lam, 0, 15)) return kERR; + } + } + if (!args.AllDone()) return kERR; + + // configure controller + Obj().Config(cntlname, base, lam); + + // install in CPU + cpu.Obj().AddCntl(dynamic_pointer_cast(ObjSPtr())); + + // finally create tcl command + CreateObjectCmd(args.Interp(), cntlcmd.c_str()); + + // and create unit commands + for (size_t i=0; i +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-03 515 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: RtclRw11CntlPC11.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class RtclRw11CntlPC11. +*/ + +#ifndef included_Retro_RtclRw11CntlPC11 +#define included_Retro_RtclRw11CntlPC11 1 + +#include "RtclRw11CntlBase.hpp" +#include "librw11/Rw11CntlPC11.hpp" + +namespace Retro { + + class RtclRw11CntlPC11 : public RtclRw11CntlBase { + public: + RtclRw11CntlPC11(); + ~RtclRw11CntlPC11(); + + virtual int FactoryCmdConfig(RtclArgs& args, RtclRw11Cpu& cpu); + }; + +} // end namespace Retro + +//#include "RtclRw11CntlPC11.ipp" + +#endif diff --git a/tools/src/librwxxtpp/RtclRw11Cpu.cpp b/tools/src/librwxxtpp/RtclRw11Cpu.cpp index d1ecacd2..5ec3ee6d 100644 --- a/tools/src/librwxxtpp/RtclRw11Cpu.cpp +++ b/tools/src/librwxxtpp/RtclRw11Cpu.cpp @@ -1,4 +1,4 @@ -// $Id: RtclRw11Cpu.cpp 511 2013-04-27 13:51:46Z mueller $ +// $Id: RtclRw11Cpu.cpp 513 2013-05-01 14:02:06Z mueller $ // // Copyright 2013- by Walter F.J. Mueller // @@ -20,7 +20,7 @@ /*! \file - \version $Id: RtclRw11Cpu.cpp 511 2013-04-27 13:51:46Z mueller $ + \version $Id: RtclRw11Cpu.cpp 513 2013-05-01 14:02:06Z mueller $ \brief Implemenation of RtclRw11Cpu. */ @@ -823,7 +823,7 @@ int RtclRw11Cpu::M_set(RtclArgs& args) int RtclRw11Cpu::M_show(RtclArgs& args) { - static RtclNameSet optset("-pcps|-r0r5|-mmu|-ubmap" + static RtclNameSet optset("-pcps|-r0ps|-mmu|-ubmap" ); string opt; @@ -838,10 +838,9 @@ int RtclRw11Cpu::M_show(RtclArgs& args) "F:seq", "F:vmbox" , "1101", "1111"}; while (args.NextOpt(opt, optset)) { - if (opt == "-pcps") { + if (opt == "-pcps" || opt == "-r0ps") { RlinkCommandList clist; size_t i_pc = clist.AddRreg(base + Rw11Cpu::kCp_addr_pc); - size_t i_sp = clist.AddRreg(base + Rw11Cpu::kCp_addr_r0+6); size_t i_psw = clist.AddRreg(base + Rw11Cpu::kCp_addr_psw); size_t i_stat = clist.AddRreg(base + Rw11Cpu::kCp_addr_stat); if (!Server().Exec(clist, emsg)) return args.Quit(emsg); @@ -854,15 +853,37 @@ int RtclRw11Cpu::M_show(RtclArgs& args) uint16_t psw_tbit = (psw>>4) & 001; uint16_t psw_nzvc = (psw) & 017; uint16_t stat_rust = (stat>>4) & 017; - sos << "PC=" << RosPrintBvi(clist[i_pc].Data(),8) - << " SP=" << RosPrintBvi(clist[i_sp].Data(),8) - << " PS=" << RosPrintBvi(psw,8) + uint16_t regs[8]; + regs[7] = clist[i_pc].Data(); + bool r0ps = opt == "-r0ps"; + + if (r0ps) { + clist.Clear(); + for (size_t i=0; i<7; i++) clist.AddRreg(base + Rw11Cpu::kCp_addr_r0+i); + if (!Server().Exec(clist, emsg)) return args.Quit(emsg); + for (size_t i=0; i<7; i++) regs[i] = clist[i].Data(); + } + + if (r0ps) sos << "Processor registers and status:" << endl; + if (!r0ps) sos << " PC: " << RosPrintBvi(regs[7],8); + sos << " PS: " << RosPrintBvi(psw,8) << " cm,pm=" << mode[psw_cm] << "," << mode[psw_pm] << " s,p,t=" << psw_set << "," << psw_pri << "," << psw_tbit << " NZVC=" << RosPrintBvi(psw_nzvc,2,4) - << " rust=" << RosPrintBvi(stat_rust,8,4) << " " << rust[stat_rust] + << " rust: " << RosPrintBvi(stat_rust,8,4) << " " << rust[stat_rust] << endl; + if (r0ps) { + sos << " R0: " << RosPrintBvi(regs[0],8) + << " R1: " << RosPrintBvi(regs[1],8) + << " R2: " << RosPrintBvi(regs[2],8) + << " R3: " << RosPrintBvi(regs[3],8) << endl; + sos << " R4: " << RosPrintBvi(regs[4],8) + << " R5: " << RosPrintBvi(regs[5],8) + << " SP: " << RosPrintBvi(regs[6],8) + << " PC: " << RosPrintBvi(regs[7],8) << endl; + } + } else if (opt == "-r0r5") { RlinkCommandList clist; for (size_t i=0; i<6; i++) clist.AddRreg(base + Rw11Cpu::kCp_addr_r0+i); @@ -964,7 +985,7 @@ int RtclRw11Cpu::M_show(RtclArgs& args) size_t k = 2*(i+j); uint32_t data = uint32_t(ubmap[k]) | (uint32_t(ubmap[k+1]))<<16; if (j!=0) sos << " "; - sos << RosPrintBvi(j+i,8,5) << " " + sos << RosPrintBvi(uint32_t(j+i),8,5) << " " << RosPrintBvi(data,8,22); } sos << endl; diff --git a/tools/src/librwxxtpp/RtclRw11UnitLP11.cpp b/tools/src/librwxxtpp/RtclRw11UnitLP11.cpp new file mode 100644 index 00000000..bffc6b64 --- /dev/null +++ b/tools/src/librwxxtpp/RtclRw11UnitLP11.cpp @@ -0,0 +1,55 @@ +// $Id: RtclRw11UnitLP11.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: RtclRw11UnitLP11.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of RtclRw11UnitLP11. +*/ + +#include "RtclRw11UnitLP11.hpp" + +using namespace std; + +/*! + \class Retro::RtclRw11UnitLP11 + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Constructor + +RtclRw11UnitLP11::RtclRw11UnitLP11(Tcl_Interp* interp, + const std::string& unitcmd, + const boost::shared_ptr& spunit) + : RtclRw11UnitBase("Rw11UnitLP11", spunit), + RtclRw11UnitStream(this, spunit.get()) +{ + CreateObjectCmd(interp, unitcmd.c_str()); +} + +//------------------------------------------+----------------------------------- +//! Destructor + +RtclRw11UnitLP11::~RtclRw11UnitLP11() +{} + +} // end namespace Retro diff --git a/tools/src/librwxxtpp/RtclRw11UnitLP11.hpp b/tools/src/librwxxtpp/RtclRw11UnitLP11.hpp new file mode 100644 index 00000000..b8e16fed --- /dev/null +++ b/tools/src/librwxxtpp/RtclRw11UnitLP11.hpp @@ -0,0 +1,52 @@ +// $Id: RtclRw11UnitLP11.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: RtclRw11UnitLP11.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class RtclRw11UnitLP11. +*/ + +#ifndef included_Retro_RtclRw11UnitLP11 +#define included_Retro_RtclRw11UnitLP11 1 + +#include "librw11/Rw11UnitLP11.hpp" +#include "librw11/Rw11CntlLP11.hpp" + +#include "RtclRw11UnitStream.hpp" +#include "RtclRw11UnitBase.hpp" + +namespace Retro { + +class RtclRw11UnitLP11 : public RtclRw11UnitBase, + public RtclRw11UnitStream { + public: + RtclRw11UnitLP11(Tcl_Interp* interp, + const std::string& unitcmd, + const boost::shared_ptr& spunit); + ~RtclRw11UnitLP11(); + + protected: + }; + +} // end namespace Retro + +//#include "RtclRw11UnitLP11.ipp" + +#endif diff --git a/tools/src/librwxxtpp/RtclRw11UnitPC11.cpp b/tools/src/librwxxtpp/RtclRw11UnitPC11.cpp new file mode 100644 index 00000000..5c73c5bc --- /dev/null +++ b/tools/src/librwxxtpp/RtclRw11UnitPC11.cpp @@ -0,0 +1,68 @@ +// $Id: RtclRw11UnitPC11.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-03 515 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: RtclRw11UnitPC11.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of RtclRw11UnitPC11. +*/ + +#include "RtclRw11UnitPC11.hpp" + +using namespace std; + +/*! + \class Retro::RtclRw11UnitPC11 + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Constructor + +RtclRw11UnitPC11::RtclRw11UnitPC11(Tcl_Interp* interp, + const std::string& unitcmd, + const boost::shared_ptr& spunit) + : RtclRw11UnitBase("Rw11UnitPC11", spunit), + RtclRw11UnitStream(this, spunit.get()) +{ + // create default unit command + CreateObjectCmd(interp, unitcmd.c_str()); + + // for 1st PC11, create also alias + // cpuxpca0 -> cpuxpr + // cpuxpca1 -> cpuxpp + if (unitcmd.length() == 8) { + size_t ind = spunit->Index(); + if (unitcmd.length() == 8 && unitcmd.substr(4,3) == "pca") { + string alias = unitcmd.substr(0,4); + alias += (ind==Rw11CntlPC11::kUnit_PR) ? "pr" : "pp"; + Tcl_CreateAlias(interp, alias.c_str(), interp, unitcmd.c_str(), 0, NULL); + } + } +} + +//------------------------------------------+----------------------------------- +//! Destructor + +RtclRw11UnitPC11::~RtclRw11UnitPC11() +{} + +} // end namespace Retro diff --git a/tools/src/librwxxtpp/RtclRw11UnitPC11.hpp b/tools/src/librwxxtpp/RtclRw11UnitPC11.hpp new file mode 100644 index 00000000..fcccd5a6 --- /dev/null +++ b/tools/src/librwxxtpp/RtclRw11UnitPC11.hpp @@ -0,0 +1,52 @@ +// $Id: RtclRw11UnitPC11.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-03 515 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: RtclRw11UnitPC11.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class RtclRw11UnitPC11. +*/ + +#ifndef included_Retro_RtclRw11UnitPC11 +#define included_Retro_RtclRw11UnitPC11 1 + +#include "librw11/Rw11UnitPC11.hpp" +#include "librw11/Rw11CntlPC11.hpp" + +#include "RtclRw11UnitStream.hpp" +#include "RtclRw11UnitBase.hpp" + +namespace Retro { + +class RtclRw11UnitPC11 : public RtclRw11UnitBase, + public RtclRw11UnitStream { + public: + RtclRw11UnitPC11(Tcl_Interp* interp, + const std::string& unitcmd, + const boost::shared_ptr& spunit); + ~RtclRw11UnitPC11(); + + protected: + }; + +} // end namespace Retro + +//#include "RtclRw11UnitPC11.ipp" + +#endif diff --git a/tools/src/librwxxtpp/RtclRw11UnitStream.cpp b/tools/src/librwxxtpp/RtclRw11UnitStream.cpp new file mode 100644 index 00000000..3da8e39f --- /dev/null +++ b/tools/src/librwxxtpp/RtclRw11UnitStream.cpp @@ -0,0 +1,60 @@ +// $Id: RtclRw11UnitStream.cpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: RtclRw11UnitStream.cpp 515 2013-05-04 17:28:59Z mueller $ + \brief Implemenation of RtclRw11UnitStream. +*/ + +using namespace std; + +#include "RtclRw11UnitStream.hpp" + +/*! + \class Retro::RtclRw11UnitStream + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Constructor + +RtclRw11UnitStream::RtclRw11UnitStream(RtclRw11Unit* ptcl, Rw11UnitStream* pobj) + : fpTcl(ptcl), + fpObj(pobj) +{ + RtclGetList& gets = ptcl->GetList(); + RtclSetList& sets = ptcl->SetList(); + gets.Add ("pos", + boost::bind(&Rw11UnitStream::Pos, pobj)); + + sets.Add ("pos", + boost::bind(&Rw11UnitStream::SetPos,pobj, _1)); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +RtclRw11UnitStream::~RtclRw11UnitStream() +{} + + +} // end namespace Retro diff --git a/tools/src/librwxxtpp/RtclRw11UnitStream.hpp b/tools/src/librwxxtpp/RtclRw11UnitStream.hpp new file mode 100644 index 00000000..b1004b75 --- /dev/null +++ b/tools/src/librwxxtpp/RtclRw11UnitStream.hpp @@ -0,0 +1,52 @@ +// $Id: RtclRw11UnitStream.hpp 515 2013-05-04 17:28:59Z mueller $ +// +// Copyright 2013- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2013-05-01 513 1.0 Initial version +// --------------------------------------------------------------------------- + + +/*! + \file + \version $Id: RtclRw11UnitStream.hpp 515 2013-05-04 17:28:59Z mueller $ + \brief Declaration of class RtclRw11UnitStream. +*/ + +#ifndef included_Retro_RtclRw11UnitStream +#define included_Retro_RtclRw11UnitStream 1 + +#include "librw11/Rw11UnitStream.hpp" + +#include "RtclRw11Unit.hpp" + +namespace Retro { + + class RtclRw11UnitStream { + public: + RtclRw11UnitStream(RtclRw11Unit* ptcl, + Rw11UnitStream* pobj); + ~RtclRw11UnitStream(); + + protected: + + protected: + RtclRw11Unit* fpTcl; + Rw11UnitStream* fpObj; + }; + +} // end namespace Retro + +//#include "RtclRw11UnitStream.ipp" + +#endif diff --git a/tools/tcl/rbbram/perf.tcl b/tools/tcl/rbbram/perf.tcl index f9a3a7e9..07dd5084 100644 --- a/tools/tcl/rbbram/perf.tcl +++ b/tools/tcl/rbbram/perf.tcl @@ -1,4 +1,4 @@ -# $Id: perf.tcl 469 2013-01-05 12:29:44Z mueller $ +# $Id: perf.tcl 516 2013-05-05 21:24:52Z mueller $ # # Copyright 2011-2013 by Walter F.J. Mueller # @@ -40,9 +40,9 @@ namespace eval rbbram { set wbuf3 {} for {set i 0} {$i < $nblk} {incr i} { lappend wbuf0 $i - lappend wbuf1 [expr 0x1000 + $i] - lappend wbuf2 [expr 0x2000 + $i] - lappend wbuf3 [expr 0x3000 + $i] + lappend wbuf1 [expr {0x1000 + $i}] + lappend wbuf2 [expr {0x2000 + $i}] + lappend wbuf3 [expr {0x3000 + $i}] } set pval {} @@ -55,9 +55,9 @@ namespace eval rbbram { rlc exec \ -wreg br.cntl $addr \ -wblk br.data $wbuf0 - set trun [expr [clock clicks -milliseconds] - $tbeg] + set trun [expr {[clock clicks -milliseconds] - $tbeg}] if {$trun > $tmax} { break } - set addr [expr ( $addr + $nblk ) & $amax] + set addr [expr {( $addr + $nblk ) & $amax}] } lappend pval 1 $i $trun @@ -70,9 +70,9 @@ namespace eval rbbram { -wreg br.cntl $addr \ -wblk br.data $wbuf0 \ -wblk br.data $wbuf1 - set trun [expr [clock clicks -milliseconds] - $tbeg] + set trun [expr {[clock clicks -milliseconds] - $tbeg}] if {$trun > $tmax} { break } - set addr [expr ( $addr + 2 * $nblk ) & $amax] + set addr [expr {( $addr + 2 * $nblk ) & $amax}] } lappend pval 2 $i $trun @@ -87,9 +87,9 @@ namespace eval rbbram { -wblk br.data $wbuf1 \ -wblk br.data $wbuf2 \ -wblk br.data $wbuf3 - set trun [expr [clock clicks -milliseconds] - $tbeg] + set trun [expr {[clock clicks -milliseconds] - $tbeg}] if {$trun > $tmax} { break } - set addr [expr ( $addr + 4 * $nblk ) & $amax] + set addr [expr {( $addr + 4 * $nblk ) & $amax}] } lappend pval 4 $i $trun @@ -101,9 +101,9 @@ namespace eval rbbram { rlc exec \ -wreg br.cntl $addr \ -rblk br.data $nblk rbuf0 - set trun [expr [clock clicks -milliseconds] - $tbeg] + set trun [expr {[clock clicks -milliseconds] - $tbeg}] if {$trun > $tmax} { break } - set addr [expr ( $addr + $nblk ) & $amax] + set addr [expr {( $addr + $nblk ) & $amax}] } lappend pval 1 $i $trun @@ -116,9 +116,9 @@ namespace eval rbbram { -wreg br.cntl $addr \ -rblk br.data $nblk rbuf0 \ -rblk br.data $nblk rbuf1 - set trun [expr [clock clicks -milliseconds] - $tbeg] + set trun [expr {[clock clicks -milliseconds] - $tbeg}] if {$trun > $tmax} { break } - set addr [expr ( $addr + 2 * $nblk ) & $amax] + set addr [expr {( $addr + 2 * $nblk ) & $amax}] } lappend pval 2 $i $trun @@ -133,16 +133,16 @@ namespace eval rbbram { -rblk br.data $nblk rbuf1 \ -rblk br.data $nblk rbuf2 \ -rblk br.data $nblk rbuf3 - set trun [expr [clock clicks -milliseconds] - $tbeg] + set trun [expr {[clock clicks -milliseconds] - $tbeg}] if {$trun > $tmax} { break } - set addr [expr ( $addr + 4 * $nblk ) & $amax] + set addr [expr {( $addr + 4 * $nblk ) & $amax}] } lappend pval 4 $i $trun set oline [format "\n%4d" $nblk] foreach {nr i trun} $pval { - set ms [expr double($trun) / double($nr*$i)] - set kb [expr double(2*$nr*$i*$nblk) / double($trun)] + set ms [expr {double($trun) / double($nr*$i)}] + set kb [expr {double(2*$nr*$i*$nblk) / double($trun)}] if { $ms < 9.94 } { append oline [format " %5.2f" $ms] } else { diff --git a/tools/tcl/rbbram/util.tcl b/tools/tcl/rbbram/util.tcl index 3690cd1e..5c05e5ec 100644 --- a/tools/tcl/rbbram/util.tcl +++ b/tools/tcl/rbbram/util.tcl @@ -1,6 +1,6 @@ -# $Id: util.tcl 376 2011-04-17 12:24:07Z mueller $ +# $Id: util.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -27,8 +27,8 @@ namespace eval rbbram { # setup: amap definitions for rbd_bram # proc setup {{base 0x00f4}} { - rlc amap -insert br.cntl [expr $base + 0x00] - rlc amap -insert br.data [expr $base + 0x01] + rlc amap -insert br.cntl [expr {$base + 0x00}] + rlc amap -insert br.data [expr {$base + 0x01}] } # # init: reset rbd_bram (clear cntl register) diff --git a/tools/tcl/rbemon/test_rbtest_sim.tcl b/tools/tcl/rbemon/test_rbtest_sim.tcl index 11fb6258..7455c16a 100644 --- a/tools/tcl/rbemon/test_rbtest_sim.tcl +++ b/tools/tcl/rbemon/test_rbtest_sim.tcl @@ -1,6 +1,6 @@ -# $Id: test_rbtest_sim.tcl 376 2011-04-17 12:24:07Z mueller $ +# $Id: test_rbtest_sim.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -62,7 +62,7 @@ namespace eval rbemon { ] { set bdata {} for {set i 0} {$i < $bsize} {incr i} { - lappend bdata [expr ( $pat << 8 ) | $pat] + lappend bdata [expr {( $pat << 8 ) | $pat}] } rbemon::clear diff --git a/tools/tcl/rbemon/test_regs.tcl b/tools/tcl/rbemon/test_regs.tcl index dd8b436b..a9f49f20 100644 --- a/tools/tcl/rbemon/test_regs.tcl +++ b/tools/tcl/rbemon/test_regs.tcl @@ -1,6 +1,6 @@ -# $Id: test_regs.tcl 440 2011-12-18 20:08:09Z mueller $ +# $Id: test_regs.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -65,13 +65,13 @@ namespace eval rbemon { # #------------------------------------------------------------------------- rlc log " test 2: verify addr increments on data reads" - foreach addr [list 0x0 0x011 [expr $amax - 1]] { + foreach addr [list 0x0 0x011 [expr {$amax - 1}]] { rlc exec -estatdef $esdval $esdmsk \ -wreg em.addr $addr \ -rreg em.data \ - -rreg em.addr -edata [expr ( $addr + 1 ) & $amax] \ + -rreg em.addr -edata [expr {( $addr + 1 ) & $amax}] \ -rreg em.data \ - -rreg em.addr -edata [expr ( $addr + 2 ) & $amax] + -rreg em.addr -edata [expr {( $addr + 2 ) & $amax}] } # #------------------------------------------------------------------------- diff --git a/tools/tcl/rbemon/util.tcl b/tools/tcl/rbemon/util.tcl index 94a259f7..5d71e9cf 100644 --- a/tools/tcl/rbemon/util.tcl +++ b/tools/tcl/rbemon/util.tcl @@ -1,6 +1,6 @@ -# $Id: util.tcl 376 2011-04-17 12:24:07Z mueller $ +# $Id: util.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -33,10 +33,10 @@ namespace eval rbemon { # setup: amap definitions for rbd_eyemon # proc setup {base} { - rlc amap -insert em.cntl [expr $base + 0x00] - rlc amap -insert em.rdiv [expr $base + 0x01] - rlc amap -insert em.addr [expr $base + 0x02] - rlc amap -insert em.data [expr $base + 0x03] + rlc amap -insert em.cntl [expr {$base + 0x00}] + rlc amap -insert em.rdiv [expr {$base + 0x01}] + rlc amap -insert em.addr [expr {$base + 0x02}] + rlc amap -insert em.data [expr {$base + 0x03}] } # # init: reset rbd_eyemon (stop monitor, clear rdiv and addr) @@ -52,12 +52,12 @@ namespace eval rbemon { proc clear {} { set clrbit [regbld rbemon::CNTL clr] rlc exec -rreg em.cntl cur_cntl - rlc exec -wreg em.cntl [expr $cur_cntl | $clrbit] + rlc exec -wreg em.cntl [expr {$cur_cntl | $clrbit}] set clrrun $clrbit set npoll 0 while {$clrrun != 0} { rlc exec -rreg em.cntl cur_cntl - set clrrun [expr $cur_cntl & $clrbit] + set clrrun [expr {$cur_cntl & $clrbit}] incr npoll 1 if {$npoll > 10} { error "-E: rbemon::clear failed, CNTL.clr didn't go back to 0" @@ -89,16 +89,16 @@ namespace eval rbemon { set addr 0 set rval {} while {$nval > 0} { - set nblk [expr $nval << 1] + set nblk [expr {$nval << 1}] if {$nblk > 256} {set nblk 256} rlc exec \ -wreg em.addr $addr \ -rblk em.data $nblk rawdat foreach {dl dh} $rawdat { - lappend rval [expr ( $dh << 16 ) | $dl] + lappend rval [expr {( $dh << 16 ) | $dl}] } incr addr $nblk - set nval [expr $nval - ( $nblk >> 1 ) ] + set nval [expr {$nval - ( $nblk >> 1 ) }] } return $rval } diff --git a/tools/tcl/rbmoni/test_rbtest.tcl b/tools/tcl/rbmoni/test_rbtest.tcl index 965e2c52..c18462c8 100644 --- a/tools/tcl/rbmoni/test_rbtest.tcl +++ b/tools/tcl/rbmoni/test_rbtest.tcl @@ -1,6 +1,6 @@ -# $Id: test_rbtest.tcl 375 2011-04-02 07:56:47Z mueller $ +# $Id: test_rbtest.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -81,7 +81,7 @@ namespace eval rbmoni { rlc exec -estatdef $esdval $esdmsk \ -wreg rm.addr $addr \ -rreg rm.data -edata [lindex $edat $addr] [lindex $emsk $addr] \ - -rreg rm.addr -edata [expr $addr + 1] + -rreg rm.addr -edata [expr {$addr + 1}] } # #------------------------------------------------------------------------- @@ -89,9 +89,9 @@ namespace eval rbmoni { foreach addr {0x1 0x3 0x5 0x6 0x4 0x2 0x0} { rlc exec -estatdef $esdval $esdmsk \ -wreg rm.addr $addr \ - -rblk rm.data 2 -edata [lrange $edat $addr [expr $addr + 1] ] \ - [lrange $emsk $addr [expr $addr + 1] ] \ - -rreg rm.addr -edata [expr $addr + 2] + -rblk rm.data 2 -edata [lrange $edat $addr [expr {$addr + 1}] ] \ + [lrange $emsk $addr [expr {$addr + 1}] ] \ + -rreg rm.addr -edata [expr {$addr + 2}] } # #------------------------------------------------------------------------- diff --git a/tools/tcl/rbmoni/util.tcl b/tools/tcl/rbmoni/util.tcl index 3d56fe96..8c322e9c 100644 --- a/tools/tcl/rbmoni/util.tcl +++ b/tools/tcl/rbmoni/util.tcl @@ -1,6 +1,6 @@ -# $Id: util.tcl 375 2011-04-02 07:56:47Z mueller $ +# $Id: util.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -41,10 +41,10 @@ namespace eval rbmoni { # setup: amap definitions for rbd_rbmon # proc setup {{base 0x00fc}} { - rlc amap -insert rm.cntl [expr $base + 0x00] - rlc amap -insert rm.alim [expr $base + 0x01] - rlc amap -insert rm.addr [expr $base + 0x02] - rlc amap -insert rm.data [expr $base + 0x03] + rlc amap -insert rm.cntl [expr {$base + 0x00}] + rlc amap -insert rm.alim [expr {$base + 0x01}] + rlc amap -insert rm.addr [expr {$base + 0x02}] + rlc amap -insert rm.data [expr {$base + 0x03}] } # # init: reset rbd_rbmon (stop, reset alim) @@ -83,25 +83,25 @@ namespace eval rbmoni { if {$nent > $nval} {set nent $nval} if {$nent == 0} { return {} } - set caddr [expr ( $laddr - $nent ) & $amax] + set caddr [expr {( $laddr - $nent ) & $amax}] rlc exec -wreg rm.addr [regbld rbmoni::ADDR [list laddr $caddr]] set rval {} while {$nent > 0} { - set nblk [expr $nent << 2] + set nblk [expr {$nent << 2}] if {$nblk > 256} {set nblk 256} rlc exec -rblk rm.data $nblk rawdat foreach {d0 d1 d2 d3} $rawdat { set eflag [regget rbmoni::DAT3(flags) $d3] set eaddr [regget rbmoni::DAT3(addr) $d3] - set edly [expr ( [regget rbmoni::DAT0(ndlymsb) $d0] << 16 ) | $d1] + set edly [expr {( [regget rbmoni::DAT0(ndlymsb) $d0] << 16 ) | $d1 }] set enbusy [regget rbmoni::DAT0(nbusy) $d0] lappend rval [list $eflag $eaddr $d2 $edly $enbusy] } - set nent [expr $nent - ( $nblk >> 2 ) ] + set nent [expr {$nent - ( $nblk >> 2 ) }] } rlc exec -wreg rm.addr $raddr @@ -123,7 +123,7 @@ namespace eval rbmoni { set rval {} - set eind [expr 1 - [llength $mondat]] + set eind [expr {1 - [llength $mondat] }] append rval " ind addr data delay nbusy ac bs er na to in we" foreach {ele} $mondat { @@ -165,7 +165,7 @@ namespace eval rbmoni { set uedat {} set uemsk {} - set m0 [expr 0xffff & ~[regget rbmoni::DAT0(nbusy) -1] ] + set m0 [expr {0xffff & ~[regget rbmoni::DAT0(nbusy) -1] }] set d1 0x0000 set m1 0xffff set m3 0x0000 diff --git a/tools/tcl/rbs3hio/util.tcl b/tools/tcl/rbs3hio/util.tcl index 6a72faad..f5be6c72 100644 --- a/tools/tcl/rbs3hio/util.tcl +++ b/tools/tcl/rbs3hio/util.tcl @@ -1,6 +1,6 @@ -# $Id: util.tcl 406 2011-08-14 21:06:44Z mueller $ +# $Id: util.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -35,10 +35,10 @@ namespace eval rbs3hio { # setup: amap definitions for s3_humanio_rbus # proc setup {base} { - rlc amap -insert hi.cntl [expr $base + 0x00] - rlc amap -insert hi.swi [expr $base + 0x01] - rlc amap -insert hi.led [expr $base + 0x02] - rlc amap -insert hi.dsp [expr $base + 0x03] + rlc amap -insert hi.cntl [expr {$base + 0x00}] + rlc amap -insert hi.swi [expr {$base + 0x01}] + rlc amap -insert hi.led [expr {$base + 0x02}] + rlc amap -insert hi.dsp [expr {$base + 0x03}] } # @@ -65,8 +65,8 @@ namespace eval rbs3hio { append rval "\n led: [pbvi b8 $led]" set dspval "" for {set i 3} {$i >= 0} {incr i -1} { - set digval [expr ( $r_dsp >> ( 4 * $i ) ) & 0x0f] - set digdp [expr ( $dp >> $i ) & 0x01] + set digval [expr {( $r_dsp >> ( 4 * $i ) ) & 0x0f}] + set digdp [expr {( $dp >> $i ) & 0x01}] append dspval [format "%x" $digval] if {$digdp} {append dspval "."} else {append dspval " "} } @@ -84,7 +84,7 @@ namespace eval rbs3hio { [list swien $swien] ] foreach ledval {0x0f 0xf0 0xff} { - set dpval [expr $ledval & 0x0f] + set dpval [expr {$ledval & 0x0f}] set hiled [regbld rbs3hio::LED [list led $ledval] [list dp $dpval]] rlc exec \ -wreg hi.led $hiled \ @@ -93,8 +93,8 @@ namespace eval rbs3hio { } for {set i 0} {$i <= 0xf} {incr i} { - set ledval [expr ( $i << 4 ) | $i] - set dspval [expr ( $ledval << 8 ) | $ledval] + set ledval [expr {( $i << 4 ) | $i}] + set dspval [expr {( $ledval << 8 ) | $ledval}] set hiled [regbld rbs3hio::LED [list led $ledval] [list dp $i]] rlc exec \ -wreg hi.led $hiled \ @@ -104,14 +104,14 @@ namespace eval rbs3hio { set ledval 0x01 for {set i 0} {$i < 32} {incr i} { - set dpval [expr $ledval & 0x0f] + set dpval [expr {$ledval & 0x0f}] set hiled [regbld rbs3hio::LED [list led $ledval] [list dp $dpval]] rlc exec \ -wreg hi.led $hiled \ -wreg hi.dsp $i after 50 - set ledval [expr $ledval << 1] - if {$ledval & 0x100} {set ledval [expr ( $ledval & 0xff ) | 0x01]} + set ledval [expr {$ledval << 1}] + if {$ledval & 0x100} {set ledval [expr {( $ledval & 0xff ) | 0x01}] } } rlc exec \ diff --git a/tools/tcl/rbtest/test_attn.tcl b/tools/tcl/rbtest/test_attn.tcl index d9d48c0d..b64c4edf 100644 --- a/tools/tcl/rbtest/test_attn.tcl +++ b/tools/tcl/rbtest/test_attn.tcl @@ -1,6 +1,6 @@ -# $Id: test_attn.tcl 375 2011-04-02 07:56:47Z mueller $ +# $Id: test_attn.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -36,8 +36,8 @@ namespace eval rbtest { # set apats {} for {set i 0} {$i < 16} {incr i} { - set apat [expr 1 << $i] - if {[expr $apat & $attnmsk]} {lappend apats $apat} + set apat [expr {1 << $i}] + if {[expr {$apat & $attnmsk}]} {lappend apats $apat} } # set errcnt 0 diff --git a/tools/tcl/rbtest/test_data.tcl b/tools/tcl/rbtest/test_data.tcl index 3dbec96f..54feaba4 100644 --- a/tools/tcl/rbtest/test_data.tcl +++ b/tools/tcl/rbtest/test_data.tcl @@ -1,6 +1,6 @@ -# $Id: test_data.tcl 375 2011-04-02 07:56:47Z mueller $ +# $Id: test_data.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -64,7 +64,7 @@ namespace eval rbtest { rlc log " test 1c: as test 1, now cntl.stat field is used" foreach stat {0x1 0x3 0x7 0x0} { set valc [regbld rbtest::CNTL [list stat $stat]] - set vald [expr $stat | ( $stat << 8 ) ] + set vald [expr {$stat | ( $stat << 8 ) }] rlc exec -estatdef $esdval $esdmsk \ -wreg te.cntl $valc \ -wreg te.data $vald \ @@ -123,10 +123,10 @@ namespace eval rbtest { set valc [regbld rbtest::CNTL [list nbusy $nbusy]] rlc exec -estatdef $esdval $esdmsk \ -wreg te.cntl $valc \ - -wreg te.data [expr $nbusy | ( $nbusy << 8 ) ] \ - -rreg te.attn -edata [expr $nbusy + 1 ] \ - -rreg te.data -edata [expr $nbusy | ( $nbusy << 8 ) ] \ - -rreg te.attn -edata [expr $nbusy + 1 ] + -wreg te.data [expr {$nbusy | ( $nbusy << 8 ) }] \ + -rreg te.attn -edata [expr {$nbusy + 1 }] \ + -rreg te.data -edata [expr {$nbusy | ( $nbusy << 8 ) }] \ + -rreg te.attn -edata [expr {$nbusy + 1 }] } # # ------------------------------------------------------------------------- diff --git a/tools/tcl/rbtest/test_fifo.tcl b/tools/tcl/rbtest/test_fifo.tcl index e177130f..70d36736 100644 --- a/tools/tcl/rbtest/test_fifo.tcl +++ b/tools/tcl/rbtest/test_fifo.tcl @@ -1,6 +1,6 @@ -# $Id: test_fifo.tcl 375 2011-04-02 07:56:47Z mueller $ +# $Id: test_fifo.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -77,7 +77,7 @@ namespace eval rbtest { rlc log " test 3b: fifo write error (write 17, read 16)" set blk {} for { set i 0 } { $i < 17 } { incr i } { - lappend blk [expr $i | ( $i << 8 ) ] + lappend blk [expr {$i | ( $i << 8 ) }] } rlc exec -estatdef $esdval $esdmsk \ -wblk te.fifo $blk -estat [regbld rlink::STAT rberr] $esdmsk \ @@ -124,10 +124,10 @@ namespace eval rbtest { set valc [regbld rbtest::CNTL [list nbusy $nbusy]] rlc exec -estatdef $esdval $esdmsk \ -wreg te.cntl $valc \ - -wreg te.fifo [expr $nbusy | ( $nbusy << 8 ) ] \ - -rreg te.attn -edata [expr $nbusy + 1 ] \ - -rreg te.fifo -edata [expr $nbusy | ( $nbusy << 8 ) ] \ - -rreg te.attn -edata [expr $nbusy + 1 ] + -wreg te.fifo [expr {$nbusy | ( $nbusy << 8 ) }] \ + -rreg te.attn -edata [expr {$nbusy + 1 }] \ + -rreg te.fifo -edata [expr {$nbusy | ( $nbusy << 8 ) }] \ + -rreg te.attn -edata [expr {$nbusy + 1 }] } # #------------------------------------------------------------------------- @@ -135,8 +135,8 @@ namespace eval rbtest { for {set i 0} {$i < 8} {incr i} { set blk {} for {set j 0} {$j < 16} {incr j} { - set bcode [expr 32 * $i + 2 * $j] - lappend blk [expr ( $bcode << 8 ) | ( $bcode + 1 )] + set bcode [expr {32 * $i + 2 * $j}] + lappend blk [expr {( $bcode << 8 ) | ( $bcode + 1 )}] } rlc exec -estatdef $esdval $esdmsk \ -wblk te.fifo $blk \ diff --git a/tools/tcl/rbtest/test_stat.tcl b/tools/tcl/rbtest/test_stat.tcl index 3feb8046..8e3c9aa0 100644 --- a/tools/tcl/rbtest/test_stat.tcl +++ b/tools/tcl/rbtest/test_stat.tcl @@ -1,6 +1,6 @@ -# $Id: test_stat.tcl 375 2011-04-02 07:56:47Z mueller $ +# $Id: test_stat.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -41,8 +41,8 @@ namespace eval rbtest { #------------------------------------------------------------------------- rlc log " test 1: verify connection of cntl stat bits to stat return" for {set i 0} {$i < 3} {incr i} { - set spat [expr 1 << $i] - if {[expr $spat & $statmsk]} { + set spat [expr {1 << $i}] + if {[expr {$spat & $statmsk}]} { set cntl [regbld rbtest::CNTL [list stat $spat]] rlc exec \ -wreg te.cntl $cntl \ diff --git a/tools/tcl/rbtest/util.tcl b/tools/tcl/rbtest/util.tcl index c94f327d..80529366 100644 --- a/tools/tcl/rbtest/util.tcl +++ b/tools/tcl/rbtest/util.tcl @@ -1,6 +1,6 @@ -# $Id: util.tcl 375 2011-04-02 07:56:47Z mueller $ +# $Id: util.tcl 516 2013-05-05 21:24:52Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -33,10 +33,10 @@ namespace eval rbtest { # setup: amap definitions for rbd_tester # proc setup {{base 0x00f0}} { - rlc amap -insert te.cntl [expr $base + 0x00] - rlc amap -insert te.data [expr $base + 0x01] - rlc amap -insert te.fifo [expr $base + 0x02] - rlc amap -insert te.attn [expr $base + 0x03] + rlc amap -insert te.cntl [expr {$base + 0x00}] + rlc amap -insert te.data [expr {$base + 0x01}] + rlc amap -insert te.fifo [expr {$base + 0x02}] + rlc amap -insert te.attn [expr {$base + 0x03}] } # # init: reset rbd_tester (clear via init) @@ -56,7 +56,7 @@ namespace eval rbtest { -rreg te.attn ncyc rlc exec -estatdef 0 $esdmsk \ -wreg te.cntl $sav_cntl - return [expr $ncyc - 1] + return [expr {$ncyc - 1}] } # # probe: determine rbd_tester environment (max nbusy, stat and attn wiring) @@ -75,9 +75,9 @@ namespace eval rbtest { set wrerr {} set rderr {} for {set i 3} { $i < 8 } {incr i} { - set nbusy0 [expr ( 1 << $i )] + set nbusy0 [expr {( 1 << $i )}] for {set j -1} { $j <= 1 } {incr j} { - set nbusy [expr $nbusy0 + $j] + set nbusy [expr {$nbusy0 + $j}] set valc [regbld rbtest::CNTL [list nbusy $nbusy]] rlc exec \ -wreg te.cntl $valc -estat $esdval $esdmsk\ @@ -97,7 +97,7 @@ namespace eval rbtest { # probe stat wiring # for {set i 0} { $i < 3 } {incr i} { - set valc [regbld rbtest::CNTL [list stat [expr 1 << $i]]] + set valc [regbld rbtest::CNTL [list stat [expr {1 << $i}]]] rlc exec -estatdef $esdval $esdmsk \ -wreg te.cntl $valc \ -rreg te.data dummy statrd @@ -110,7 +110,7 @@ namespace eval rbtest { rlc exec -attn for {set i 0} { $i < 16 } {incr i} { rlc exec -estatdef $esdval $esdmskatt \ - -wreg te.attn [expr 1 << $i] \ + -wreg te.attn [expr {1 << $i}] \ -attn attnpat lappend rattn [list $i $attnpat] } @@ -158,7 +158,7 @@ namespace eval rbtest { # proc print_bitind {pat} { for {set i 0} { $i < 16 } {incr i} { - if {[expr $pat & [expr 1 << $i]]} { return $i} + if {[expr {$pat & [expr {1 << $i}] }] } { return $i} } return -1 } diff --git a/tools/tcl/rutil/util.tcl b/tools/tcl/rutil/util.tcl index 2b9825cf..400d3afa 100644 --- a/tools/tcl/rutil/util.tcl +++ b/tools/tcl/rutil/util.tcl @@ -1,6 +1,6 @@ -# $Id: util.tcl 502 2013-04-02 19:29:30Z mueller $ +# $Id: util.tcl 517 2013-05-09 21:34:45Z mueller $ # -# Copyright 2011- by Walter F.J. Mueller +# Copyright 2011-2013 by Walter F.J. Mueller # # This program is free software; you may redistribute and/or modify it under # the terms of the GNU General Public License as published by the Free @@ -13,6 +13,7 @@ # # Revision History: # Date Rev Version Comment +# 2013-05-09 517 1.0.1 add optlist2arr # 2011-03-27 374 1.0 Initial version # 2011-03-19 372 0.1 First draft # @@ -22,6 +23,23 @@ package provide rutil 1.0 package require rutiltpp namespace eval rutil { + # + # optlist2arr: process options arguments given as key value list + # + proc optlist2arr {outarrname refarrname optlist} { + upvar $outarrname outarr + upvar $refarrname refarr + array set outarr [array get refarr] + foreach {key value} $optlist { + if {[info exists outarr($key)]} { + set outarr($key) $value + } else { + error "key $key not valid in optlist" + } + } + return "" + } + # # regdsc: setup a register descriptor # @@ -46,18 +64,18 @@ namespace eval rutil { error "error in field dsc \"$arg\": length > start position" } - set mskb [expr ( 1 << $flen ) - 1] - set mskf [expr $mskb << ( $fbeg - ( $flen - 1 ) )] + set mskb [expr {( 1 << $flen ) - 1}] + set mskf [expr {$mskb << ( $fbeg - ( $flen - 1 ) )}] set rdsc($fnam) [list $fbeg $flen $mskb $mskf $popt] if {$fbegmax < $fbeg} {set fbegmax $fbeg} - set mskftot [expr $mskftot | $mskf] + set mskftot [expr {$mskftot | $mskf}] } set rdsc(-n) [lsort -decreasing -command regdsc_sort \ [array names rdsc -regexp {^[^-]}] ] - set rdsc(-w) [expr $fbegmax + 1] + set rdsc(-w) [expr {$fbegmax + 1}] set rdsc(-m) $mskftot return "" @@ -85,7 +103,7 @@ namespace eval rutil { set line " " append line [format "%8s" $fnam] if {$flen > 1} { - append line [format " %2d:%2d" $fbeg [expr $fbeg - $flen + 1]] + append line [format " %2d:%2d" $fbeg [expr {$fbeg - $flen + 1}]] } else { append line [format " %2d" $fbeg] } @@ -98,7 +116,7 @@ namespace eval rutil { proc regdsc_sort {a b} { upvar rdsc urdsc - return [expr [lindex $urdsc($a) 0] - [lindex $urdsc($b) 0]] + return [expr {[lindex $urdsc($a) 0] - [lindex $urdsc($b) 0] }] } # @@ -123,7 +141,7 @@ namespace eval rutil { error "error in field specifier \"$arg\": no value and flen>1" } set mskf [lindex $rdsc($fnam) 3] - set rval [expr $rval | $mskf] + set rval [expr {$rval | $mskf}] } else { set fval [lindex $arg 1] @@ -133,12 +151,12 @@ namespace eval rutil { error "error in field specifier \"$arg\": value > $mskb" } } else { - if {$fval < [expr - $mskb]} { + if {$fval < [expr {- $mskb}]} { error "error in field specifier \"$arg\": value < [expr -$mskb]" } - set fval [expr $fval & $mskb] + set fval [expr {$fval & $mskb}] } - set rval [expr $rval | $fval << ( $fbeg - ( $flen - 1 ) )] + set rval [expr {$rval | $fval << ( $fbeg - ( $flen - 1 ) )}] } } @@ -153,7 +171,7 @@ namespace eval rutil { set fbeg [lindex $fdsc 0] set flen [lindex $fdsc 1] set mskb [lindex $fdsc 2] - return [expr ( $val >> ( $fbeg - ( $flen - 1 ) ) ) & $mskb] + return [expr {( $val >> ( $fbeg - ( $flen - 1 ) ) ) & $mskb}] } # diff --git a/tools/tcl/rw11/cpucons.tcl b/tools/tcl/rw11/cpucons.tcl index a1355c8e..7f548103 100644 --- a/tools/tcl/rw11/cpucons.tcl +++ b/tools/tcl/rw11/cpucons.tcl @@ -1,4 +1,4 @@ -# $Id: cpucons.tcl 511 2013-04-27 13:51:46Z mueller $ +# $Id: cpucons.tcl 512 2013-04-28 07:44:02Z mueller $ # # Copyright 2013- by Walter F.J. Mueller # @@ -50,10 +50,10 @@ namespace eval rw11 { } # - # '?' show current PC and PS and R0-R5 + # '?' show current PC and PS and R0-R6 # proc "?" {} { - return [cpu0 show -pcps -r0r5] + return [cpu0 show -r0ps] } # diff --git a/tools/tcl/rw11/cpumon.tcl b/tools/tcl/rw11/cpumon.tcl index 9b7b980a..d7d8e673 100644 --- a/tools/tcl/rw11/cpumon.tcl +++ b/tools/tcl/rw11/cpumon.tcl @@ -1,4 +1,4 @@ -# $Id: cpumon.tcl 511 2013-04-27 13:51:46Z mueller $ +# $Id: cpumon.tcl 512 2013-04-28 07:44:02Z mueller $ # # Copyright 2013- by Walter F.J. Mueller # @@ -80,7 +80,7 @@ namespace eval rw11 { if {$cpumon_active} { puts "CPU down attention" - puts [cpu0 show -pcps] + puts [cpu0 show -r0ps] # restore ti_rri prompt and eof handling if { $tirri_interactive } { rename ::tclreadline::prompt1 {} diff --git a/tools/tcl/rw11/util.tcl b/tools/tcl/rw11/util.tcl index 4aa4e02a..8225f8c9 100644 --- a/tools/tcl/rw11/util.tcl +++ b/tools/tcl/rw11/util.tcl @@ -1,4 +1,4 @@ -# $Id: util.tcl 510 2013-04-26 16:14:57Z mueller $ +# $Id: util.tcl 517 2013-05-09 21:34:45Z mueller $ # # Copyright 2013- by Walter F.J. Mueller # @@ -13,6 +13,7 @@ # # Revision History: # Date Rev Version Comment +# 2013-05-09 517 1.1.2 add setup_(tt|lp|pp|ostr) device setup procs # 2013-04-26 510 1.1.1 split, asm* and tbench* into separate files # 2013-04-01 501 1.1 add regdsc's and asm* procs # 2013-02-02 380 1.0 Initial version @@ -55,10 +56,109 @@ namespace eval rw11 { cpu0 add dl11 cpu0 add dl11 -base 0176500 -lam 2 cpu0 add rk11 + cpu0 add lp11 + cpu0 add pc11 rlw start return "" } + # + # setup_tt: setup terminals + # + proc setup_tt {{cpu "cpu0"} {optlist {}}} { + # process and check options + array set optref { ndl 2 dlrlim 0 ndz 0 to7bit 0 app 0 nbck 1} + rutil::optlist2arr opt optref $optlist + + # check option values + if {$opt(ndl) < 1 || $opt(ndl) > 2} { + error "ndl option must be 1 or 2" + } + if {$opt(ndz) != 0} { + error "ndz option must be 0 (till dz11 support is added)" + } + + # setup attach url options + set urlopt "?crlf" + if {$opt(app) != 0} { + append urlopt ";app" + } + if {$opt(nbck) != 0} { + append urlopt ";bck=$opt(nbck)" + } + + # setup list if DL11 controllers + set dllist {} + lappend dllist "tta" "8000" + if {$opt(ndl) == 2} { + lappend dllist "ttb" "8001" + } + + # handle DL11 controllers + foreach {cntl port} $dllist { + set unit "${cntl}0" + ${cpu}${unit} att "tcp:?port=${port}" + ${cpu}${unit} set log "tirri_${unit}.log${urlopt}" + if {$opt(dlrlim) != 0} { + ${cpu}${cntl} set rxrlim 7 + } + if {$opt(to7bit) != 0} { + ${cpu}${unit} set to7bit 1 + } + } + return "" + } + + # + # setup_ostr: setup Ostream device (currently lp or pp) + # + proc setup_ostr {cpu unit optlist} { + # process and check options + array set optref { app 0 nbck 1} + rutil::optlist2arr opt optref $optlist + + # setup attach url options + set urloptlist {} + if {$opt(app) != 0} { + append urloptlist "app" + } + if {$opt(nbck) != 0} { + append urloptlist "bck=$opt(nbck)" + } + set urlopt "" + if {[llength $urloptlist] > 0} { + append urlopt "?" + append urlopt [join $urloptlist ";"] + } + + # handle unit + ${cpu}${unit} att "tirri_${unit}.dat${urlopt}" + return "" + } + + # + # setup_lp: setup printer + # + proc setup_lp {{cpu "cpu0"} {optlist {}}} { + # process and check options + array set optref { nlp 1 app 0 nbck 1} + rutil::optlist2arr opt optref $optlist + if {$opt(nlp) != 0} { + setup_ostr $cpu "lpa0" [list app $opt(app) nbck $opt(nbck)] + } + } + # + # setup_pp: setup paper puncher + # + proc setup_pp {{cpu "cpu0"} {optlist {}}} { + # process and check options + array set optref { npc 1 app 0 nbck 1} + rutil::optlist2arr opt optref $optlist + if {$opt(npc) != 0} { + setup_ostr $cpu "pp" [list app $opt(app) nbck $opt(nbck)] + } + } + # # run_pdpcp: execute pdpcp type command file # diff --git a/tools/tcl/tst_rlink/perf.tcl b/tools/tcl/tst_rlink/perf.tcl index 1042d03b..94807c96 100644 --- a/tools/tcl/tst_rlink/perf.tcl +++ b/tools/tcl/tst_rlink/perf.tcl @@ -1,4 +1,4 @@ -# $Id: perf.tcl 376 2011-04-17 12:24:07Z mueller $ +# $Id: perf.tcl 516 2013-05-05 21:24:52Z mueller $ # # Copyright 2011- by Walter F.J. Mueller # @@ -42,10 +42,10 @@ namespace eval tst_rlink { rlc exec \ -attn \ -wreg timer.0 $dly - set trun [expr [clock clicks -milliseconds] - $tbeg] + set trun [expr {[clock clicks -milliseconds] - $tbeg}] if {$trun > $tmax} { break } } - set ms [expr double($trun) / double($i)] + set ms [expr {double($trun) / double($i)}] append rval [format "\n%5d %6.2f" $dly $ms] } diff --git a/tools/tcl/tst_rlink/util.tcl b/tools/tcl/tst_rlink/util.tcl index 59ab4a77..34a1f359 100644 --- a/tools/tcl/tst_rlink/util.tcl +++ b/tools/tcl/tst_rlink/util.tcl @@ -1,4 +1,4 @@ -# $Id: util.tcl 376 2011-04-17 12:24:07Z mueller $ +# $Id: util.tcl 516 2013-05-05 21:24:52Z mueller $ # # Copyright 2011- by Walter F.J. Mueller # @@ -73,9 +73,9 @@ namespace eval tst_rlink { rlc close rlc open "term:$rldev?baud=${baud};break" rlc exec -rreg hi.dsp hidsp - set mhz [expr double($baud*$hidsp) / 1.e6] + set mhz [expr {double($baud*$hidsp) / 1.e6}] append rval [format "\n%7d 0x%4.4x %6d %6.2f" \ - $baud $hidsp [expr $hidsp + 1] $mhz] + $baud $hidsp [expr {$hidsp + 1}] $mhz] } rlc close