CDC1700: Initial import of new simulator from John Forecast

This commit is contained in:
Mark Pizzolato 2016-07-20 21:05:02 -07:00
parent 93a8754bfe
commit 1897dfeb94
22 changed files with 13713 additions and 4 deletions

View file

@ -0,0 +1,280 @@
Running Diagnostics on the CDC 1700 Simulator
=============================================
1. Overview
The diagnostics system (System Maintenance Monitor) is available from
bitsavers.org as bits/CDC/1700_Cyber18/20100517/SYSTEM17_SMM_DIAGS.TAP. The
simulator is able to boot this tape and has successfully run the following
diagnostics with some caveats (for more detailed information see
pdf/CDC/1700/SMM17 at bitsavers.org).
In some cases the diagnostics fail to run correctly on the simulator
for various reasons:
- Some tests require hardware modifications or special cabling
- Some tests perform timing checks which are difficult to implement
in the simulator without further documentation or access to the
diagnostic source code
- Some tests check for features which are not implemented in the
simulator. E.G. The disk controllers write Checkwords (CRC) for each
sector written but the documentation does not specify the CRC
algorithm in sufficient detail to allow the simulator to correctly
simulate the feature.
Partial listing from the maintenance monitor:
FF QL1 12166 04EB Quick Look 1 (basic instruction set test)
Passed
FE QL2 10196 095C Quick Look 2 (more detailed instruction set test)
Passed with and without protect mode enabled
01 COM 12166 0990 Comprehensive instruction set test
Passed
03 PTP 12166 05B8 1723/77 Paper Tape Punch Test
Passed (Interrupt + character mode)
04 PTR 12166 03C8 1721/77 Paper Tape Reader Test
Passed (Interrupt + Character mode)
05 TTY 10226 093B 1711/1712/1713 Teletype Test
Passed
08 DP1 12166 0EE6 1738 Disk Pack Test
Passed (Single/dual 854, overlapped seeks)
0A BD1 10076 08BD 1706 Buffered Data Channel Test
Passed (Need to use non-interrupt TTY output)
0C LP1 11056 07E7 1740/1742/93x2 Line Printer Test
Passed
15 MT3 09306 0A96 1732 Magnetic Tape Test
Passed sections 0 - 5. Section 6 fails
1C CMD 12166 07C6 4KW Command Test
Passed
4B PET 12166 0C14 1732-2/1732-3 Magnetic Tape Test
Passed in programmed I/O mode
Failed in DMA mode
91 RTC 10216 04DA System 17 Real Time Clock Test
Passed
In addition the following tests were run but are not available on the above
tape:
7A MDC 10186 1CE9 1733-2 Multiple Drive Cartridge Disk Test
Fails seek timing and checkword tests
2. Running diagnostics
Detailed information on running the System Maintenance Monitor can be
found at bitsavers.org in "pdf/cdc/1700/smm17". Here is a sample test run of
the COMmand test (test 01), a CPU instruction test, using the default settings
for running the test:
Sample test run of the COMmand test (test 01), a CPU instruction test. Note
that SMM uses a private bootstrap and we have to load that into the simulator
by hand (User input to SMM17 is marked with "<==="):
CDC1700 simulator V4.0-0 Beta git commit id: 9d2079df
sim> attach mt0 SYSTEM17_SMM_DIAGS.TAP
sim> do -v CDC1700/smm32KMTboot
CDC1700/smm32KMTboot-6> echo Loading SMM17 MT bootstrap (32KW)
Loading SMM17 MT bootstrap (32KW)
CDC1700/smm32KMTboot-7> echo
CDC1700/smm32KMTboot-9> set cpu sstop
CDC1700/smm32KMTboot-10> set mt0 locked
CDC1700/smm32KMTboot-11> set dca interrupt=F
CDC1700/smm32KMTboot-12> boot -S mt0
PROGRAM PROTECT NOT SET PROTECTED TEST NOT RUN
SMM17 VERSION 4.0 CP2F
COPYRIGHT CONTROL DATA CORP. 1974
BUILD TEST LIST
0000 / 0000? 0101 <==================== High byte is test # (COM)
Low byte is repetition count
0000 / 0000?
COM001 COMMAND TEST.
IA = 0A00, FC = 01 CP2F, VERSION 4.0
0121 / 020D? <========================= Return to keep defaults
0044 / 0BB8? <=========================
A1 Q1 A2 Q2
0121 020D 0044 0BB8
0124 020D 0001 0A17
0124 / 020D?
Simulation stopped, P: 0837 (P 0DFE INQ $FE)
If a test terminates with A1 containing xxy4 (where xx is the test # and
y is the number of register pairs to be displayed) it was successful. If it
terminates with A1 containing xxy8, the test failed and the remaining
registers indicate what and where the failure occured (format is test
dependent).
3. Scripts for running SMM17
These scripts allow SMM17 to be run with various test features
enabled. All of the scripts assume that a bootable SMM17 tape image is
attached to mt0.
3.1 Basic SMM17 boot sequence
echo Loading SMM17
echo
set cpu sstop
set mt0 locked
boot -S mt0
3.2 Use Buffered Data Channel #1 for tape access
echo Loading SMM17 - Uses BDC #1
echo
set cpu sstop
set mt0 locked
set dca interrupt=F
boot -DS mt0
3.3 Load MBS and use non-interrupt driven TTY output
echo Loading SMM17
echo - MBS loaded
echo - Non-interrupt driven TTY output
echo
set cpu sstop
set cpu sskip
set mt0 locked
boot -S mt0
c
d a 31E0
set cpu nosskip
set cpu nosstop
c
4. Notes on specific diagnostic tests
MBS (Monitor Based Subroutine package) must be loaded for tests 0F
and 4B.
Test 0F (BD2, 1706/1716 Data Channel Test) requires a 7-track tape
for section 4 (relies on the controller masking the output to 6-bits).
Test 0F (BD2, 1706/1716 Data Channel Test) gets an error 0004 with
Q set to 001C! The problem seems to be related to returning 7-track
status in Director Status 2 (if I disable setting IO_ST2_7TRACK
everything works correctly for sections 2 and 4).
Test 4A (MTX, 1731/1732 Mag Tape Test) hangs while writing to the
TTY. The source listing (60411400C...) does not match the code
loaded from the magtape image.
Test 4B (PET, 1732-2/-3 Mag Tape subsystem test) can only be used if
the mag tape controller type is set to 1732-3. The test can access
the controller in 2 modes; programmed I/O which only works up to
800 BPI and DMA (called DSA) which works up to 1600 BPI. In programmed
I/O mode the tests complete successfully. In DSA mode, the test
fails during the first read from tape (writes work successfully) with
a timeout waiting for "end of operation". My current hypothesis is
that the controller asserts "end of operation" when all of the data
has been transferred to the CPU but delays generating an interrupt
until it has processed the CRC at the end of the block. I would need
to look at the test source listing before making any changes.
Test 7A (MDC, 1733-2 Cartridge Disk Controller) passes most test.
The seek timing test fails - I don't want to debug this without
source listings. The checkword test fails since we don't store the
checkword data in the emulated storage and it is not clear there
is sufficient documentation to be able to construct a valid checkword
on the fly.
5. Directory listing of the SMM17 tape (with descriptions)
BIN QL
FF QL1 12166 04E8 Quick Look 1
FE QL2 10196 095C Quick Look 2
FC DPC 09146 0685 Disk Call-up Program
00 SMM 11046 10A3 System Maintenance Monitor
01 COM 12166 0990 Command Test
02 MY2 12166 0753 Memory Test
03 PTP 12166 05B8 1723/77 Paper Tape Punch Test
04 PTR 12166 03C8 1721/77 Paper Tape Reader Test
05 TTY 10226 093B 1711/12/13 Teletype Test
07 MT1 07046 0980 1731 Magnetic Tape Test
08 DP1 12166 0EE6 1738 Disk Pack Test
09 RPT 12166 023D Random Protect Test
0A BD1 10076 08BD 1706 Buffered Data Channel Test
0B SC1 12166 0A2E Satellite Coupler Test
0C LP1 11056 07E7 1740/42/93X2 Line Printer Test
0D CRP 10154 0C46 1728 Card Reader/Punch Test
0E MT2 11036 0BCA 1731 Magnetic Tape Test
0F BD2 10076 0A0B 1706/1716 Data Channel Test
10 DTB 10154 08A4 1700/8000 - 8049-A, 211 Display Test
11 DSC 04122 092F 1700 Data Set Controller Test
12 MY1 10186 0834 Memory Test
13 CR3 11056 0B46 1729-2/3 Card Reader Test
14 MEM 07046 0612 Memory Test
17 CR2 10154 0AE1 1726/405 Card Reader Test
1C CMD 12166 07C6 4K Command Test
1D DDT 07046 0BB1 1745-2 Display Test. Version 4.0
1E MOS 07046 05AF MOS Memory Test
1F MTS 10206 053B 1731/32 Special Test
20 DS1 11056 0989 1747 DSC Test
23 LP5 10196 0F06 1742-120 Line Printer Test W/595-4 Train
27 DP3 10154 1517 1700 Disk Subsystem Test
2D UD3 08012 0971 3000 Channel Simulator Program Update
30 RX1 09246 148E 1700/FF104/955 System Test
31 LR1 09247 16C4 Unknown
32 LDR 09096 0182 Unknown
34 RX4 09166 12E9 Unknown
35 OCR 12146 1727 1735/915 OCR035 Test
36 AQM 11086 1327 DJ814A A/Q Communications Multiplexer (NUMOD) Test
3B DMP 10154 01F9 Printer/TTY Dump
3D SAS 08012 0EE6 3000 Channel Simulator Assembler
3E EDT 12166 0805 17X4 Library Editing Routine
40 DDC 11086 0B5B 1745/1746/211 Display Station Test
42 CLK 08176 0994 10126 Interval Timer - Day Clock Test
43 CTC 10216 1C90 1749 Communications Terminal Test
4A MTX 10076 11A8 1731/1732 Mag Tape Test
4B PET 12166 0C14 1732-2/1732-3 Magnetic Tape Test
4C HOR 10233 0FC9 1500 Series Remote Peripheral Controller Diagnostic
56 BC2 07155 15AC SC17/1700 FR101 MEM/COM/IFP Test
57 UD1 01303 0774 1700 Source/6000 TVC Update
59 BC3 07155 0967 SC17/1700/FR101/FR113 Interface Test
60 KEY 04016 0D8F Cyberdata Key Entry Station Test
61 RST 12146 0FD3 979 Reader/Sorter Test
69 PAD 11086 0CCF Punch the 1726/405 Test Deck
6F DG4 02022 2340 1744/274 Digigraphic Test
70 GT0 10154 0623 GPGT Troubleshooting Test
71 GT1 10086 2880 GPGT DCI Test
72 GT2 07155 2842 GPGT Display Quality Test
73 GT3 10154 0C8B GPGT Light Pen And Keyboard Test
74 GT4 12112 0A25 GPGT Communications Test
75 GT5 10154 0827 GPGT Communications Test (12 Bit Interface)
76 GT6 10154 0C87 GPGT Specification Vertification Test
78 CDD 07046 19AD 1739 Cartridge Disk Controller Test
80 DRM 11086 2702 BG504 Drum Test
81 CTR 07046 092C FR117 Event Counter Subsystem Test
83 DIO 11096 06F3 1553/54 1544/45 Digital Input/Output Subsystem Test
84 DP5 07046 0F7C 1738 Quick Look Test
86 ACC 07155 0A81 Asynchronous Communication Controller (DJ815-A) Test
87 SCC 07155 0BCD Synchronous Communication Controller (FJ606-A) Test
88 CPC 10216 0E5C 1725-1 Card Punch Test
89 BSC 11196 0CC3 Cyberdata Bisync Controller Test
8A HFP 07046 1CDE 1781-a Hardware Floating Point Unit Test
90 IOM 11096 0B8B IOM Mother Unit Digital Input/Output Test
91 RTC 10216 04DA System 17 Real Time Clock Test
92 PT1 10205 0617 1720-1 Paper Tape Punch Test
93 PT2 10205 05B1 1720-1 Paper Tape Reader Test
D0 CPY 07046 02CC Tape To Tape Copy
F0 CPV 10216 03FB Card Punch Verify Utility
FB REP 10216 14E2 Replace/Update 17X4 SMM Disk Library
FD INS 10216 0965 Mass Storage Maintenance System Installation Program

588
CDC1700/CDC1700-MSOS.txt Normal file
View file

@ -0,0 +1,588 @@
Installing MSOS 5 on the CDC 1700 Simulator
===========================================
1. Overview.
A Mass Storage Operating System Version 5 (MSOS 5) distribution tape
which will run on the CDC 1700 Simulator is available from bitsaver.org as
bits/CDC/1700_Cyber18/20100524/MSOS5_SL136.tap. At the time, CDC would have
tailored a distribution tape for the customers specific hardware and this
tape was built for a 64KW 1784 system used by Exxon. Not all of the
peripherals included in the system are implemented on the simulator due to
lack of documentation but enough are available to perform a basic
installation.
2. Installation
Installation of MSOS 5 occurs in 2 phases:
- Phase 1
In Phase 1, the distribution tape is booted and the initializer
lays down a skeleton system on the cartridge disk.
- Phase 2
In Phase 2, the skeleton system is booted from the cartridge disk
and the batch subsystem is started to read and process a sequence
of batch jobs to complete the installation.
It is important that both phases are within the same execution of the CDC
1700 Simulator since phase 1 leaves the tape correctly positioned at the
start of the batch jobs for phase 2.
The device drivers built into this version of MSOS 5 use specific
versions of the magtape and line printer controllers. The type of these
controllers must be set before attaching host data files. If the controller
types are not set correctly, phase 1 of the installation will complete
successfully but the batch subsystem will refuse to start.
Sample installation run of MSOS 5 (user input to MSOS is marked with "<==="):
CDC1700 simulator V4.0-0 Beta git commit id: 9d2079df
sim> set cpu mode65k,64k
sim> set mt type=1732-3
sim> att mt0 MSOS5_SL136.tap
sim> set lp type=1742
sim> att lp MSOSinstall.lpt
LP: creating new file
sim> att cd0 MSOS5.dsk
CD: creating new file
sim> boot mt0
MSOS 5.0 SYSTEM INITIALIZER
FWA OF CONTRL = 5000
DATE MM/DD/YY
07/14/88 <============================ Enter date
Q
*I,3 <================================= Distribution media is tape
*I,3
Q
*V <=================================== Start installation
*V
*V
*S,SYSMON,$3031
*S,SYSDAY,$3236
*S,SYSYER,$3832
*S,SYSLVL,$3230
*V
*V 1700 MASS STORAGE OPERATING SYSTEM - VER 5.0
*V
*V EXXON DEVELOPMENT SYSTEM
*V
*YM,LIBEDT,1
*YM,LOADSD,2
*YM,JOBENT,3
*YM,JOBPRO,4
*YM,PROTEC,5
*YM,JPLOAD,6
*YM,JPCHGE,7
*YM,JPT13,8
*YM,JCRDV4,9
*YM,JLGOV4,10
*YM,JPSTV4,11
*YM,NAMEV4,12
*YM,JPFLV4,13
*YM,AFILV4,14
*YM,RESTOR,15
*YM,RCOVER,16
*YM,BRKPT,17
*YM,ODEBUG,18
*YM,SYSCOP,19
*YM,SYSSEG,20
*YM,MIPRO,21
*YM,TDFUNC,22
*YM,EFSTOR,23
*YM,EFLIST,24
*YM,VERIFY,25
*YM,SCMM17,26
*YM,DUMMY1,27
*YM,DUMMY2,28
*YM,DUMMY3,29
*YM,DUMMY4,30
*YM,DUMMY5,31
*YM,DUMMY6,32
*YM,DUMMY7,33
*YM,DUMMY8,34
*YM,DUMMY9,35
*YM,DUMMY0,36
*S,N4,$0800
*S,END0V4,$7FFF
*S,BGNMON,$8000
*S,MSIZV4,$FFFF
*S,SECTOR,$5BFA
*
*L SYSTEM DATA PROGRAM
CS7C17
SYSDAT 0000 EXXON DEVELOPMENT SYSTEM SUMMARY-122
*L SPACE REQUEST PROCESSOR
SPACE 1C21 DECK-ID M29 MSOS 5.0 SUMMARY-136
*
* SYSTEM CORE RESIDENT PROGRAMS
*
*LP MONITOR
NMONI 8000 DECK-ID M10 MSOS 5.0 SUMMARY-136
RDISP 804D DECK-ID M23 MSOS 5.0 SUMMARY-110
RW 81FF DECK-ID M09 MSOS 5.0 SUMMARY-110
T14 82AD DECK-ID M26 MSOS 5.0 SUMMARY-110
T16 82BE DECK-ID M04 MSOS 5.0 SUMMARY-110
PARAME 82C9 DECK-ID M03 MSOS 5.0 SUMMARY-110
COMMON 833A DECK-ID M13 MSOS 5.0 SUMMARY-110
NIPROC 8361 DECK-ID M12 MSOS 5.0 SUMMARY-118
ALVOL 83F3 DECK-ID M16 MSOS 5.0 SUMMARY-110
OFVOL 8410 DECK-ID M15 MSOS 5.0 SUMMARY-110
ALCORE 841D DECK-ID M17 MSOS 5.0 SUMMARY-110
DCORE 84CB DECK-ID M19 MSOS 5.0 SUMMARY-110
PRTCDR 8634 DECK-ID M18 MSOS 5.0 SUMMARY-110
NFNR 884E DECK-ID M21 MSOS 5.0 SUMMARY-141
NCMPRQ 88C7 DECK-ID M20 MSOS 5.0 SUMMARY-110
MAKQ 88F7 DECK-ID M08 MSOS 5.0 SUMMARY-110
ADEV 8925 DECK-ID M22 MSOS 5.0 SUMMARY-132
TMINT 8A98 DECK-ID M06 MSOS 5.0 SUMMARY-116
DTIMER 8B2A DECK-ID M05 MSOS 5.0 SUMMARY-136
TOD 8B4D DECK-ID M25 MSOS 5.0 SUMMARY-110
MINT 8B9C DECK-ID M07 MSOS 5.0 SUMMARY-116
TRVEC 8CC6 DECK-ID M14 MSOS 5.0 SUMMARY-116
*LP DEBUGGING / CHECKOUT
SNAPOL 8D19 DECK-ID M02 MSOS 5.0 SUMMARY-110
DMP42X 8DD2 DECK-ID B17 PERIPH. DRIVERS 1.0B SUMMARY-106
B17332 8EA1 DECK-ID B11 PERIPH. DRIVERS 1.0B SUMMARY-106
*LP FILE MANAGER
FILMGR 8EF3 DECK-ID F01 FILE MANAGER 1.0 SUMMARY-124
RSPCV4 91DC DECK-ID F02 FILE MANAGER SUMMARY-116
SRHFIS 92CE DECK-ID F03 FILE MANAGER SUMMARY-110
*LP CORE RESIDENT DRIVERS
EFDATA 94A0 DECK-ID M27 MSOS 5.0 SUMMARY-110
DUMMY 960D DECK-ID M30 MSOS 5.0 SUMMARY-110
D1711 9630 DECK-ID B27 PERIPH. DRIVERS 1.0B SUMMARY-106
D17332 97D8 DECK-ID B34 PERIPH. DRIVERS 1.0B SUMMARY-119
D1752 9A77 DECK-ID A40 PERIPH. DRIVERS 1.0A SUMMARY-106
DPSDSK 9C81 DECK-ID C90 PERIPH. DRIVERS 1.2C SUMMARY-122
REWCK 9CB2 DECK-ID B78 PERIPH. DRIVERS 1.0B SUMMARY-106
MMEXEC 9CCD DECK-ID M01 MSOS 5.0 SUMMARY-132
D17432 9E60 DECK-ID B35 PERIPH. DRIVERS 1.0B SUMMARY-115
*LP REENTRANT FORTRAN RUNTIME LIBRARY
FORTR A0A9 DECK-ID A01 FTN 3.3 RUNTIME SUMMARY-102
Q8PRMR A1ED DECK-ID B01 FTN 3.3 RUNTIME SUMMARY-102
PARABR A217 DECK-ID B02 FTN 3.3 RUNTIME SUMMARY-102
Q8F2IR A228 DECK-ID B03 FTN 3.3 RUNTIME SUMMARY-102
ABSR A2D4 DECK-ID B04 FTN 3.3 RUNTIME SUMMARY-102
SQRTFR A2ED DECK-ID B05 FTN 3.3 RUNTIME SUMMARY-102
SIGNR A348 DECK-ID B06 FTN 3.3 RUNTIME SUMMARY-102
FXFLTR A374 DECK-ID B07 FTN 3.3 RUNTIME SUMMARY-102
EXPR A3AC DECK-ID B08 FTN 3.3 RUNTIME SUMMARY-102
ALOGR A44C DECK-ID B09 FTN 3.3 RUNTIME SUMMARY-102
TANHR A4C3 DECK-ID B10 FTN 3.3 RUNTIME SUMMARY-102
SNCSR A52F DECK-ID B11 FTN 3.3 RUNTIME SUMMARY-102
ATANR A5F9 DECK-ID B12 FTN 3.3 RUNTIME SUMMARY-102
Q8QIOR A697 DECK-ID C01 FTN 3.3 RUNTIME SUMMARY-102
BINARR A7FC DECK-ID C02 FTN 3.3 RUNTIME SUMMARY-102
IOCODR A847 DECK-ID D01 FTN 3.3 RUNTIME SUMMARY-102
INITLR A87B DECK-ID D02 FTN 3.3 RUNTIME SUMMARY-102
RSTORR A88A DECK-ID D03 FTN 3.3 RUNTIME SUMMARY-102
GETCHR A89A DECK-ID D04 FTN 3.3 RUNTIME SUMMARY-102
IPACKR A8B4 DECK-ID D05 FTN 3.3 RUNTIME SUMMARY-102
UPDATR A8F2 DECK-ID D06 FTN 3.3 RUNTIME SUMMARY-102
DECPLR A8FF DECK-ID D07 FTN 3.3 RUNTIME SUMMARY-102
INTGRR A925 DECK-ID D08 FTN 3.3 RUNTIME SUMMARY-102
SPACER A952 DECK-ID D09 FTN 3.3 RUNTIME SUMMARY-102
HOLR A96A DECK-ID D10 FTN 3.3 RUNTIME SUMMARY-102
DCHXR A9FE DECK-ID D11 FTN 3.3 RUNTIME SUMMARY-102
HXASCR AA71 DECK-ID D12 FTN 3.3 RUNTIME SUMMARY-102
AFMTOR AAC4 DECK-ID D13 FTN 3.3 RUNTIME SUMMARY-102
RFMTOR AAEE DECK-ID D14 FTN 3.3 RUNTIME SUMMARY-102
AFMTIR AB07 DECK-ID D15 FTN 3.3 RUNTIME SUMMARY-102
RFMTIR AB35 DECK-ID D16 FTN 3.3 RUNTIME SUMMARY-102
ASCHXR AB4C DECK-ID D17 FTN 3.3 RUNTIME SUMMARY-102
HXDCR AB87 DECK-ID D18 FTN 3.3 RUNTIME SUMMARY-102
FLOTIR AC17 DECK-ID D19 FTN 3.3 RUNTIME SUMMARY-102
FOUTR AC61 DECK-ID D20 FTN 3.3 RUNTIME SUMMARY-102
EOUTR ACEB DECK-ID D21 FTN 3.3 RUNTIME SUMMARY-102
EWRITR ADD3 DECK-ID D22 FTN 3.3 RUNTIME SUMMARY-102
INTI1R ADDF DECK-ID D23 FTN 3.3 RUNTIME SUMMARY-102
FORMTR ADFC DECK-ID D24 FTN 3.3 RUNTIME SUMMARY-115
Q8QFIR AFFD DECK-ID D25 FTN 3.3 RUNTIME SUMMARY-102
Q8QFLR B017 DECK-ID D26 FTN 3.3 RUNTIME SUMMARY-102
Q8QFXR B046 DECK-ID D27 FTN 3.3 RUNTIME SUMMARY-102
HEXAR B07D DECK-ID D28 FTN 3.3 RUNTIME SUMMARY-102
HEXDR B095 DECK-ID D29 FTN 3.3 RUNTIME SUMMARY-102
ASCIIR B0B2 DECK-ID D30 FTN 3.3 RUNTIME SUMMARY-102
DECHXR B0C7 DECK-ID D31 FTN 3.3 RUNTIME SUMMARY-102
AFORMR B0E7 DECK-ID D32 FTN 3.3 RUNTIME SUMMARY-102
RFORMR B103 DECK-ID D33 FTN 3.3 RUNTIME SUMMARY-102
FLOTGR B11F DECK-ID D34 FTN 3.3 RUNTIME SUMMARY-102
FLOTR B13B DECK-ID B14 FTN 3.3 RUNTIME SUMMARY-112
COMFPR B389 DECK-ID B15 FTN 3.3 RUNTIME SUMMARY-102
SGDBLR B49C DECK-ID E01 FTN 3.3 RUNTIME SUMMARY-102
Q8D2IR B4B0 DECK-ID E02 FTN 3.3 RUNTIME SUMMARY-102
DABSR B542 DECK-ID E03 FTN 3.3 RUNTIME SUMMARY-102
DSQRTR B55E DECK-ID E04 FTN 3.3 RUNTIME SUMMARY-102
DSIGNR B5DE DECK-ID E05 FTN 3.3 RUNTIME SUMMARY-102
DEXPR B60B DECK-ID E08 FTN 3.3 RUNTIME SUMMARY-102
DLOGR B6C7 DECK-ID E09 FTN 3.3 RUNTIME SUMMARY-102
DSNCSR B76D DECK-ID E11 FTN 3.3 RUNTIME SUMMARY-102
DATANR B882 DECK-ID E12 FTN 3.3 RUNTIME SUMMARY-132
Q8QDFR B958 DECK-ID E14 FTN 3.3 RUNTIME SUMMARY-102
DOUTR B974 DECK-ID E15 FTN 3.3 RUNTIME SUMMARY-102
DFLOTR BA7E DECK-ID E13 FTN 3.3 RUNTIME SUMMARY-102
DRSTRR BEDC DECK-ID E10 FTN 3.3 RUNTIME SUMMARY-102
NXTLOC BF12 NEXT AVAILABLE LOCATION
*
* SYSTEM MASS RESIDENT PROGRAMS
*
*M LIBEDT 1
LIBEDT 0203 DECK-ID M35 MSOS 5.0 SUMMARY-122
*M LOADSD 2
LOAD1 0243 DECK-ID M36 MSOS 5.0 SUMMARY-110
BRNCH1 0236 DECK-ID M37 MSOS 5.0 SUMMARY-132
PG2KRD 0398 DECK-ID O69 MSOS 5.0 SUMMARY-116
LIDRV1 03C9 DECK-ID M38 MSOS 5.0 SUMMARY-110
LCDRV1 041A DECK-ID M39 MSOS 5.0 SUMMARY-110
LMDRV1 0447 DECK-ID M40 MSOS 5.0 SUMMARY-110
LLDRV1 0466 DECK-ID M41 MSOS 5.0 SUMMARY-110
ADJOF1 0474 DECK-ID M42 MSOS 5.0 SUMMARY-110
CNVRT1 0480 DECK-ID M43 MSOS 5.0 SUMMARY-110
LSTOT1 0498 DECK-ID M44 MSOS 5.0 SUMMARY-110
LINK11 04EB DECK-ID M45 MSOS 5.0 SUMMARY-110
LOADR1 052E DECK-ID M46 MSOS 5.0 SUMMARY-116
NAMPR1 05A7 DECK-ID M47 MSOS 5.0 SUMMARY-110
RBDBZ1 0648 DECK-ID M48 MSOS 5.0 SUMMARY-110
ENTEX1 0741 DECK-ID M49 MSOS 5.0 SUMMARY-110
XFRPR1 0777 DECK-ID M50 MSOS 5.0 SUMMARY-110
STBASE 0788 DECK-ID M51 MSOS 5.0 SUMMARY-110
LNKENT 0870 DECK-ID M52 MSOS 5.0 SUMMARY-110
LNKCR1 088C DECK-ID M53 MSOS 5.0 SUMMARY-110
PATCH 08CD DECK-ID M54 MSOS 5.0 SUMMARY-110
TBSCH1 090F DECK-ID M55 MSOS 5.0 SUMMARY-110
HASH 0957 DECK-ID M56 MSOS 5.0 SUMMARY-110
TBSTR1 096F DECK-ID M57 MSOS 5.0 SUMMARY-110
PAGE 09C4 DECK-ID M58 MSOS 5.0 SUMMARY-136
PROGLD 0AB5 DECK-ID M59 MSOS 5.0 SUMMARY-110
SCAN1 0BB7 DECK-ID M60 MSOS 5.0 SUMMARY-110
CHPU1 0C7D DECK-ID M61 MSOS 5.0 SUMMARY-110
ADJOV2 0C8A DECK-ID M62 MSOS 5.0 SUMMARY-110
ADRPR1 0CA3 DECK-ID M63 MSOS 5.0 SUMMARY-110
*M JOBENT 3
JOBENT 0266 DECK-ID M64 MSOS 5.0 SUMMARY-116
T11 0112 DECK-ID M65 MSOS 5.0 SUMMARY-110
T7 0149 DECK-ID M66 MSOS 5.0 SUMMARY-110
T5 026B DECK-ID M67 MSOS 5.0 SUMMARY-110
T3 02C4 DECK-ID M68 MSOS 5.0 SUMMARY-110
*S,N1,P
*M JOBPRO 4
JOBPRO 026E DECK-ID M69 MSOS 5.0 SUMMARY-132
ONE 023D DECK-ID M70 MSOS 5.0 SUMMARY-110
TWO 0240 DECK-ID M71 MSOS 5.0 SUMMARY-110
THREE 0243 DECK-ID M72 MSOS 5.0 SUMMARY-110
* * * U N P A T C H E D E X T E R N A L S * * *
BATLST
*S,N2,P
*M PROTEC 5
UPROTK 0275 DECK-ID M73 MSOS 5.0 SUMMARY-115
JBKILL 044C DECK-ID M75 MSOS 5.0 SUMMARY-110
*M JPLOAD 6
JPLOAD 0282 DECK-ID M76 MSOS 5.0 SUMMARY-110
*M JPCHGE 7
JPCHGE 0287 DECK-ID M77 MSOS 5.0 SUMMARY-110
ASCHEX 013E DECK-ID M78 MSOS 5.0 SUMMARY-110
*M JPT13 8
T13 028C DECK-ID M79 MSOS 5.0 SUMMARY-110
*M JCRDV4 9
JCRDV4 0291 DECK-ID M80 MSOS 5.0 SUMMARY-136
*M JLGOV4 10
JLGOV4 0295 DECK-ID M81 MSOS 5.0 SUMMARY-110
*M JPSTV4 11
JPSTV4 0298 DECK-ID M84 MSOS 5.0 SUMMARY-110
*M NAMEV4 12
NAMEV4 029A DECK-ID M85 MSOS 5.0 SUMMARY-110
*M JPFLV4 13
JPFLV4 02A2 DECK-ID M82 MSOS 5.0 SUMMARY-110
*M AFILV4 14
JPF2V4 02A9 DECK-ID M83 MSOS 5.0 SUMMARY-110
*M RESTOR 15
RESTOR 02B3 DECK-ID M86 MSOS 5.0 SUMMARY-114
*M RCOVER 16
RCOVER 02B6 DECK-ID M87 MSOS 5.0 SUMMARY-110
OUTSEL 0144 DECK-ID M88 MSOS 5.0 SUMMARY-110
RDMPV4 0189 DECK-ID M89 MSOS 5.0 SUMMARY-110
MASDMP 0249 DECK-ID M90 MSOS 5.0 SUMMARY-110
*M BRKPT 17
BRKPT1 02BF DECK-ID N01 MSOS 5.0 SUMMARY-110
*M ODEBUG 18
ODBUG1 02CC DECK-ID N07 MSOS 5.0 SUMMARY-116
GETREQ 0120 DECK-ID N08 MSOS 5.0 SUMMARY-110
LHXREQ 0240 DECK-ID N09 MSOS 5.0 SUMMARY-110
DPCREQ 0300 DECK-ID N10 MSOS 5.0 SUMMARY-132
SCNREQ 03C0 DECK-ID N11 MSOS 5.0 SUMMARY-116
SETREQ 0480 DECK-ID N12 MSOS 5.0 SUMMARY-110
MBCREQ 04E0 DECK-ID N13 MSOS 5.0 SUMMARY-110
SCHREQ 05A0 DECK-ID N14 MSOS 5.0 SUMMARY-116
SPEREQ 0660 DECK-ID N15 MSOS 5.0 SUMMARY-113
CPPREQ 06C0 DECK-ID N16 MSOS 5.0 SUMMARY-110
SPPREQ 0720 DECK-ID N17 MSOS 5.0 SUMMARY-110
ADHREQ 0780 DECK-ID N18 MSOS 5.0 SUMMARY-110
SBHREQ 07E0 DECK-ID N19 MSOS 5.0 SUMMARY-110
ALCREQ 0840 DECK-ID N20 MSOS 5.0 SUMMARY-116
RELREQ 0900 DECK-ID N21 MSOS 5.0 SUMMARY-110
DACREQ 0960 DECK-ID N22 MSOS 5.0 SUMMARY-116
PTHREQ 0A80 DECK-ID N23 MSOS 5.0 SUMMARY-116
MTRREQ 0BA0 DECK-ID N24 MSOS 5.0 SUMMARY-116
MSDREQ 0C00 DECK-ID N25 MSOS 5.0 SUMMARY-116
CLUREQ 0CC0 DECK-ID N26 MSOS 5.0 SUMMARY-110
WCDREQ 0D20 DECK-ID N27 MSOS 5.0 SUMMARY-116
LASREQ 0D80 DECK-ID N28 MSOS 5.0 SUMMARY-110
DASREQ 0EA0 DECK-ID N29 MSOS 5.0 SUMMARY-116
MLUREQ 0F60 DECK-ID N30 MSOS 5.0 SUMMARY-110
DPTREQ 0FC0 DECK-ID N31 MSOS 5.0 SUMMARY-116
SLDREQ 1080 DECK-ID N32 MSOS 5.0 SUMMARY-116
CWAREQ 10E0 DECK-ID N33 MSOS 5.0 SUMMARY-132
DMHREQ 1200 DECK-ID N34 MSOS 5.0 SUMMARY-116
SMNREQ 12C0 DECK-ID N35 MSOS 5.0 SUMMARY-116
SMPREQ 1440 DECK-ID N36 MSOS 5.0 SUMMARY-116
LSPREQ 1500 DECK-ID N37 MSOS 5.0 SUMMARY-116
DSPREQ 15C0 DECK-ID N38 MSOS 5.0 SUMMARY-116
DMSREQ 16E0 DECK-ID N39 MSOS 5.0 SUMMARY-116
LSOREQ 1860 DECK-ID N40 MSOS 5.0 SUMMARY-116
CCCREQ 1980 DECK-ID N41 MSOS 5.0 SUMMARY-116
CCMREQ 1AA0 DECK-ID N42 MSOS 5.0 SUMMARY-116
CMMREQ 1BC0 DECK-ID N43 MSOS 5.0 SUMMARY-116
MMMREQ 1CE0 DECK-ID N44 MSOS 5.0 SUMMARY-116
LICREQ 1E60 DECK-ID N45 MSOS 5.0 SUMMARY-118
LIOREQ 1FE0 DECK-ID N46 MSOS 5.0 SUMMARY-116
LAMREQ 2160 DECK-ID N47 MSOS 5.0 SUMMARY-116
DDPREQ 2280 DECK-ID N48 MSOS 5.0 SUMMARY-116
LDPREQ 23A0 DECK-ID N49 MSOS 5.0 SUMMARY-116
LDOREQ 24C0 DECK-ID N50 MSOS 5.0 SUMMARY-116
DMDREQ 2640 DECK-ID N51 MSOS 5.0 SUMMARY-116
WDKREQ 27C0 DECK-ID N52 MSOS 5.0 SUMMARY-116
LSTREQ 28E0 DECK-ID N53 MSOS 5.0 SUMMARY-116
PRINT 2A60 DECK-ID N54 MSOS 5.0 SUMMARY-116
GETFLD 2B20 DECK-ID N55 MSOS 5.0 SUMMARY-110
ASHX 2BE0 DECK-ID N56 MSOS 5.0 SUMMARY-110
DMPBUF 2C40 DECK-ID N57 MSOS 5.0 SUMMARY-116
ASCDEC 2D00 DECK-ID N58 MSOS 5.0 SUMMARY-110
HXAS 2D60 DECK-ID N59 MSOS 5.0 SUMMARY-110
DECDMP 2DC0 DECK-ID N60 MSOS 5.0 SUMMARY-116
FETMM 2E80 DECK-ID N61 MSOS 5.0 SUMMARY-132
PNTMD 2FA0 DECK-ID N62 MSOS 5.0 SUMMARY-116
MASOT 3060 DECK-ID N63 MSOS 5.0 SUMMARY-116
CONFM 3180 DECK-ID N64 MSOS 5.0 SUMMARY-116
GETINT 32A0 DECK-ID N65 MSOS 5.0 SUMMARY-116
FLCVSG 3360 DECK-ID N66 MSOS 5.0 SUMMARY-116
FLCVDB 3480 DECK-ID N67 MSOS 5.0 SUMMARY-116
NAMEMS 35A0 DECK-ID N68 MSOS 5.0 SUMMARY-110
DCONV 3A20 DECK-ID N69 MSOS 5.0 SUMMARY-110
LAZY2 3B40 DECK-ID N70 MSOS 5.0 SUMMARY-110
ODDFLT 3C00 DECK-ID N71 MSOS 5.0 SUMMARY-110
ODDFTN 3CC0 DECK-ID N72 MSOS 5.0 SUMMARY-110
ECONV 4080 DECK-ID N73 MSOS 5.0 SUMMARY-110
LAZY1 4140 DECK-ID N74 MSOS 5.0 SUMMARY-110
ODFLOT 4200 DECK-ID N75 MSOS 5.0 SUMMARY-110
ODFXFL 4440 DECK-ID N76 MSOS 5.0 SUMMARY-110
*M SYSCOP 19
SYSCOP 0384 DECK-ID N77 MSOS 5.0 SUMMARY-110
*M SYSSEG 20
CO1ST 0389 DECK-ID N78 MSOS 5.0 SUMMARY-110
CO2ND 04E0 DECK-ID N79 MSOS 5.0 SUMMARY-136
CO3RD 0D80 DECK-ID N80 MSOS 5.0 SUMMARY-110
COLAST 1500 DECK-ID N81 MSOS 5.0 SUMMARY-110
*M MIPRO 21
MIPRO 03C2 DECK-ID N06 MSOS 5.0 SUMMARY-110
* * * U N P A T C H E D E X T E R N A L S * * *
CRIMPT
INDACS
TSUTIL
*M TDFUNC 22
TDFUNC 03C9 DECK-ID O67 MSOS 5.0 SUMMARY-110
*M EFSTOR 23
EFSTOR 03CD DECK-ID N04 MSOS 5.0 SUMMARY-110
*M EFLIST 24
EFLIST 03D2 DECK-ID N05 MSOS 5.0 SUMMARY-123
*M VERIFY 25
VERFY1 03F0 DECK-ID O24 MSOS 5.0 SUMMARY-110
*M SCMM17 26
SCMEXC 03F5 DECK-ID O54 MSOS 5.0 SUMMARY-117
*M DUMMY1 27
*M DUMMY2 28
*M DUMMY3 29
*M DUMMY4 30
*M DUMMY5 31
*M DUMMY6 32
*M DUMMY7 33
*M DUMMY8 34
*M DUMMY9 35
*M DUMMY0 36
*
* MASS RESIDENT DRIVERS
*
*M COSY DRIVER
DCOSY 0405 DECK-ID M34 MSOS 5.0 SUMMARY-114
NXTLOC 02F0 NEXT AVAILABLE LOCATION
*S,SCOSY,S
*S,LCOSY,P
*M 1732-3 616 MAG TAPE
D17323 040D DECK-ID B33 PERIPH. DRIVERS 1.0B SUMMARY-114
D327TR 0442 DECK-ID B36 PERIPH. DRIVERS 1.0B SUMMARY-106
NXTLOC 0565 NEXT AVAILABLE LOCATION
*S,S17323,S
*S,L17323,P
*M 1732-3 616 MAG TAPE LONG RECORD
D7323L 041C DECK-ID B38 PERIPH. DRIVERS 1.0B SUMMARY-114
NXTLOC 0539 NEXT AVAILABLE LOCATION
*S,S7323L,S
*S,L7323L,P
*M PSEUDO TAPE
DPSUDO 042A DECK-ID F04 FILE MANAGER SUMMARY-114
NXTLOC 03CD NEXT AVAILABLE LOCATION
*S,SPSUDO,S
*S,LPSUDO,P
*M 1742-30/120 LINE PRINTER
D42312 0435 DECK-ID B37 PERIPH. DRIVERS 1.0B SUMMARY-132
T5954 01AF DECK-ID B77 PERIPH. DRIVERS 1.0B SUMMARY-112
NXTLOC 023F NEXT AVAILABLE LOCATION
*S,S42312,S
*S,L42312,P
*M 1728-430 CARD READER/PUNCH - 026 FORMAT
D1728 043B DECK-ID A30 PERIPH. DRIVERS 1.0A SUMMARY-106
CR026 03A2 DECK-ID A16 PERIPH. DRIVERS 1.0A SUMMARY-106
CP026 03C2 DECK-ID A14 PERIPH. DRIVERS 1.0A SUMMARY-106
NXTLOC 0402 NEXT AVAILABLE LOCATION
*S,S1728,S
*S,L1728,P
*M 1728-430 CARD READER/PUNCH - 029 FORMAT
D1728 0446 DECK-ID A30 PERIPH. DRIVERS 1.0A SUMMARY-106
CR029 03A2 DECK-ID A17 PERIPH. DRIVERS 1.0A SUMMARY-106
CP029 03C2 DECK-ID A15 PERIPH. DRIVERS 1.0A SUMMARY-106
NXTLOC 0402 NEXT AVAILABLE LOCATION
*
* MASS RESIDENT FILE MANAGER
*
*M
DEFFIL 0451 DECK-ID F05 FILE MANAGER SUMMARY-116
FILSPC 0186 DECK-ID F06 FILE MANAGER SUMMARY-110
RPEND 0233 DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP01,S
*M
RELFIL 0457 DECK-ID F08 FILE MANAGER SUMMARY-110
RELSPC 0092 DECK-ID F09 FILE MANAGER SUMMARY-110
RPEND 0141 DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP02,S
*M
DEFIDX 045B DECK-ID F10 FILE MANAGER SUMMARY-110
SQRTFM 0098 DECK-ID F11 FILE MANAGER SUMMARY-110
FILSPC 00A8 DECK-ID F06 FILE MANAGER SUMMARY-110
RPEND 0155 DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP03,S
*M
LOKFIL 045F DECK-ID F12 FILE MANAGER SUMMARY-110
RPEND 004D DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP04,S
*M
UNLFIL 0460 DECK-ID F13 FILE MANAGER SUMMARY-110
RPEND 003D DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP05,S
*M
STOSEQ 0461 DECK-ID F14 FILE MANAGER SUMMARY-110
FILSPC 00C6 DECK-ID F06 FILE MANAGER SUMMARY-110
RPEND 0173 DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP06,S
*M
STODIR 0465 DECK-ID F15 FILE MANAGER SUMMARY-110
RPEND 008D DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP07,S
*M
STOIDX 0467 DECK-ID F20 FILE MANAGER SUMMARY-110
HASHCD 0341 DECK-ID F16 FILE MANAGER SUMMARY-110
GETKID 034C DECK-ID F17 FILE MANAGER SUMMARY-110
FILSPC 0373 DECK-ID F06 FILE MANAGER SUMMARY-110
RPEND 0420 DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP08,S
*M
EDFDMY 0472 DECK-ID F27 FILE MANAGER SUMMARY-116
FILSPC 0472 DECK-ID F06 FILE MANAGER SUMMARY-110
RPEND 00AF DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMREDF,S
*M
EDRDMY 0474 DECK-ID F28 FILE MANAGER SUMMARY-116
RTNSPC 0474 DECK-ID F19 FILE MANAGER SUMMARY-110
RPEND 00A2 DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMREDR,S
*M
RTVSEQ 0476 DECK-ID F18 FILE MANAGER SUMMARY-110
RTNSPC 018B DECK-ID F19 FILE MANAGER SUMMARY-110
RPEND 022B DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP09,S
*M
RTVDIR 047C DECK-ID F21 FILE MANAGER SUMMARY-110
RTNSPC 0115 DECK-ID F19 FILE MANAGER SUMMARY-110
RPEND 01B5 DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP10,S
*M
RTVIDX 0481 DECK-ID F22 FILE MANAGER SUMMARY-110
HASHCD 0258 DECK-ID F16 FILE MANAGER SUMMARY-110
GETKID 0263 DECK-ID F17 FILE MANAGER SUMMARY-110
RTNSPC 028A DECK-ID F19 FILE MANAGER SUMMARY-110
RPEND 032A DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP11,S
*M
RTVIDO 048A DECK-ID F23 FILE MANAGER SUMMARY-118
GETKID 0260 DECK-ID F17 FILE MANAGER SUMMARY-110
RTNSPC 0287 DECK-ID F19 FILE MANAGER SUMMARY-110
RPEND 0327 DECK-ID F07 FILE MANAGER SUMMARY-110
*S,FMRP12,S
*M
FMDUMY 0493 DECK-ID F24 FILE MANAGER SUMMARY-110
*S,FMREND,S
*S,JFILV4,S SPECIFY THE JOB FILE TABLE SPACE
*M,JFILV4+$40
*T END OF SYSTEM
* * * U N P A T C H E D E X T E R N A L S * * *
PARITY
POWERU
INITIALIZATION COMPLETED - YOU MAY AUTOLOAD
Simulation stopped, P: 5914 ( 18FF JMP* $FF)
sim> autoload cd
sim> run 0
MSOS 5.0--PSR LEVEL 120 01/26/82
SET PROGRAM PROTECT
Simulation stopped, P: 1E13 ( 4CF0 STQ* ($F0))
sim> set cpu protect
sim> c
EXXON DEVELOPMENT SYSTEM
65K MODE
CHECKING FILES - OK
ENTER DATE/TIME MMDDYYHHMM
0714881208 <============================ Enter date/time
DATE: 14 JUL 88 TIME: 1208:00
MI <==================================== ^G (Control + G) for
manual interrupt
*BATCH <================================ Start batch subsystem
*CTO, MSOS 5.0 INSTALLATION COMPLETED - YOU MAY AUTOLOAD
Simulation stopped, P: 8592 (P 18FB JMP* $FB)
sim> q
Goodbye
Output from the batch jobs is sent to the line printer.

198
CDC1700/CDC1700.txt Normal file
View file

@ -0,0 +1,198 @@
CDC 1700 Simulator
==================
1. Overview.
The CDC 1700 was a 16-bit mini-computer produced by the Control Data
Corporation with deliveries beginning in May 1966.
2. Hardware
This simulator provides support for a subset of available peripherals,
mostly from the early period of its release:
device name Hardware
CPU 1714 CPU with up to 32KW of memory in 4KW increments
1705 Interrupt/Data channel option
Optional extensions:
64KW of memory with indirect addressing changes
Character addressing option
RTC 10336-1 Real-time clock
Default tick interval is 10mSec, can be changed with
"set rtc rate=<rate>" command, where <rate> is
{1usec|10usec|100usec|1msec|10msec|100msec|1second}.
[ Equipment address: 0xD]
DCA Data channels providing DMA access to non-DMA
DCB peripherals. The configuration is currently fixed
DCC with DCA providing access to the magtape controller
if it is configured as a 1732-A.
TTI 1711-A Half-duplex console terminal.
TTO [Equipment address: 0x1, Station address: 1]
PTR 1721-A Paper tape reader
[Equipment address: 0x1, Station address: 2]
PTP 1723-A Paper tape punch
[Equipment address: 0x1, Station address: 4]
MT 1732-A or 1732-3 Magtape controller, 3 9-track drives
(MT0 - MT2) and 1 7-track drive (MT3). The type of
the controller may be chaged using the command
"set mt type={1732-a|1732-3}". The 1732-A controller
supports 200, 556 and 800 BPI on the 9 track drives
and allows DMA access via a 1706 Buffered Data
Channel (device DCA). The 1733-3 controller supports
556, 800 and 1600 BPI on the 9 track drives and
includes DSA (DMA) access built into the controller.
Access via a 1706 Buffered Data Channel is not
available.
[Equipment address: 0x7]
LP 1740 or 1742-30 Line printer (Upper case only). The
type of the printer may be changed with the command
"set lp type={1740|1742}; The 1742-30 is compatible
with the 1742-120 but not allow the print train
configuration to be loaded by software.
[Equipment address: 0x4]
DP 1738-B Disk pack controller. Supports up to 2
disk pack drives:
853 drive - 3072000 bytes
854 drive - 6236160 bytes
[Equipment address: 0x3]
CD 1733-2 Cartridge disk pack controller. Supports up to
4 cartridge disk drives. Each drive supports a fixed
and a removeable disk:
856-2 drive - 2260608 bytes
856-4 drive - 4543488 bytes
[Equipment address: 0x3]
Notes:
DP and CD use the same equipment address so only 1 of them may be
enabled (default is for CD to be enabled).
Both controllers use checkwords (CRC) for validating the consistency
of the data stored on disk. The DP controller exports a single status
bit indicating whether the checkword is valid or not (the simulator
always sets this to valid). The CD controller also exports a single
status bit which is handled in the same way as the DP controller.
It also makes the actual checkword value available. The simulator
always returns a checkword value of 0 so any attempt to verify the
checkword (such as some diagnostics) will fail.
3. Loading Software
The simulator implements 2 mechanisms for loading software which
follow the hardware mechanisms provided by the real hardware:
- Magtape bootstraps toggled in through the front panel
- Autoload mechanism for disk drives
3.1 Magtape bootstraps
Software may be loaded from a magtape drive by using the SIMH command
"boot mtx" (currently only drive 0 is supported) which loads an appropriate
bootstrap into memory. This bootstrap loads the next record from the tape and
starts execution of the loaded code.
3.1.1 Default bootstrap
The default bootstrap is used for loading operating system distribution
tapes and is loaded at location 0. Register A is set according to the amount
os memory installed in the system:
- 0x5000 if 32KW or greater is installed
- 0x4000 if 24KW or 28KW is installed
- 0x2000 if less than 24KW is installed
3.1.2 SMM17 bootstrap
SMM17 is the System Maintenance Monitor and uses a tailored bootstrap
which is loaded into the highest addressed 4KW module installed in the system.
The following switches may be used with the "boot" command for special
handling:
-S load the SMM17 bootstrap rather than the default bootstrap
-D configure the SMM17 bootstrap to use Buffered Data Channel #1
to access the magtape controller
3.2 Disk autoload
The autoload mechanism loads track 0 from logical drive 0 of a disk
controller to memory location 0, it does not start execution of the loaded
code (some of the diagnostics code relies on this). Both DP and CD controllers
support the autoload command ("autoload dp" or "autoload cd") which is
normally followed by a "run 0" command to start execution of the loaded code.
4. Operating The Simulator
4.1 CPU
The control panel of a physical CDC 1700 system has a number of
switches which control the operation of the CPU. In the simulator, these
switches can be turned on and off with the commands "set cpu xxx" and
"set cpu noxxx". By default, all the switches are off.
4.1.1 Selective Stop (set cpu sstop/nosstop)
The Selective Stop switch controls how the "Selective Stop (SLS)"
instruction executes. If the switch is Off, SLS executes as a no-operation.
If the switch is On, SLS executes as a halt instruction. Continuing after
the halt causes the CPU to execute the instruction following SLS.
4.1.2 Selective Skip (set cpu sskip/nosskip)
The Selective Skip switch controls how the SWS and SWN skip
instruction execute. SWS will skip if the switch is set and SWN will skip if
the switch is not set. Both the Selective Stop and Selective Skip switches
are used extensively to control execution of the System Maintenance Monitor.
4.1.3 Protect (set cpu protect/noprotect)
Each word of memory on the CDC 1700 series consists of 18-bits; 16-bits
of data/instructions, a parity bit (which is not implemented in the simulator)
and a program protect bit. If the Protect switch is Off, any program may
reference any word of memory. If the Protect switch is On, there are a set of
rules which control how memory accesses work and when to generate a program
protect violation - see one of the 1700 reference manuals on bitsavers.org for
exact details.
The simulator fully implements CPU protect mode allowing protected
operating systems such as MSOS 5 to execute. It does not support peripheral
protect operation which allows unprotected programs to directly access
some unprotected peripherals.
Operating systems and other programs which run with the Protect
switch on usually start up with the Protect switch off, manipulate the
protect bits in memory (using the CPB/SPB instructions) and then ask the
operator to set the Protect switch on.
4.2 Teletype
The console teletype on some of the earlier models of the CDC 1700
series had a "Manual Interrupt" button so that the operator could get the
attention of the operating system. Later models used a display terminal and
used the "Control+G" key conbination to generate a Manual Interrupt. The
Simulator follows this convention of using the "Control+G" key combination.
The actual key combination may be changed by issuing the command
"deposit tti intrkey xx" where xx is desired key code in hex.
5. Software
There is some software available at bitsavers.org in the
bits/CDC/1700_Cyber18 directory, see CDC1700_Diagnostics.txt and
CDC1700_MSOS.txt for more details.

1327
CDC1700/cdc1700_cd.c Normal file

File diff suppressed because it is too large Load diff

1548
CDC1700/cdc1700_cpu.c Normal file

File diff suppressed because it is too large Load diff

795
CDC1700/cdc1700_dc.c Normal file
View file

@ -0,0 +1,795 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_dc.c: CDC1700 Buffered data channel support
* Simh devices: dca, dcb, dcc
*/
#include "cdc1700_defs.h"
extern char INTprefix[];
extern uint16 Areg, Preg, Qreg, IOAreg, IOQreg, M[];
extern t_bool IOFWinitialized;
extern DEVICE *IOdev[];
extern UNIT cpu_unit;
extern uint16 LoadFromMem(uint16);
extern t_bool IOStoreToMem(uint16, uint16, t_bool);
extern void rebuildPending(void);
extern void RaiseExternalInterrupt(DEVICE *);
extern IO_DEVICE *fw_findChanDevice(IO_DEVICE *, uint16);
extern enum IOstatus fw_doIO(DEVICE *, t_bool);
extern enum IOstatus fw_doBDCIO(IO_DEVICE *, uint16 *, t_bool, uint8);
extern uint16 LoadFromMem(uint16);
extern t_bool IOStoreToMem(uint16, uint16, t_bool);
extern t_stat show_debug(FILE *, UNIT *, int32, CONST void *);
t_stat set_intr(UNIT *uptr, int32 val, CONST char *, void *);
t_stat show_intr(FILE *, UNIT *, int32, CONST void *);
t_stat show_target(FILE *, UNIT *, int32, CONST void *);
t_stat dc_svc(UNIT *);
t_stat dc_reset(DEVICE *);
void DCstate(const char *, DEVICE *, IO_DEVICE *);
t_bool DCreject(IO_DEVICE *, t_bool, uint8);
enum IOstatus DCin(IO_DEVICE *, uint8);
enum IOstatus DCout(IO_DEVICE *, uint8);
/*
1706-A Buffered Data Channel
Addresses (A maximum of 3 1706-A's may be attached to a 1700 series system)
Computer Instruction
Q Register Output From A Input To A
(Bits 11-15)
#1 #2 #3
00010 00111 01100 Direct Output Direct Input
00011 01000 01101 Function Terminate Buffer
00100 01001 01110 Buffered Output 1706-A Status
00101 01010 01111 Buffered Input 1706-A Current Address
Operations:
Function
15 14 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | |
| +---------------------------------------------------+ EOP Interrupt
| | Request
| Not defined
Set/Clear condition bits 0 - 14
Status Response:
Status
15 10 7 5 3 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X | X | X | X | | | X | | X | | X | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | |
| | | | | | Ready
| | | | | Busy
| | | | Interrupt
| | | End of Operation
| | Program Protect Fault
| Device Reject
Device Reply
*/
IO_DEVICE DCAdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_1_A,
DCreject, DCin, DCout, NULL, NULL,
DCstate, NULL, NULL, NULL,
0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | \
MASK_REGISTER2 | MASK_REGISTER3,
MASK_REGISTER2, 0, 0, DEVICE_DC, 0, NULL);
IO_DEVICE DCBdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_2_A,
DCreject, DCin, DCout, NULL, NULL,
DCstate, NULL, NULL, NULL,
0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | \
MASK_REGISTER2 | MASK_REGISTER3,
MASK_REGISTER2, 0, 0, DEVICE_DC, 0, NULL);
IO_DEVICE DCCdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_3_A,
DCreject, DCin, DCout, NULL, NULL,
DCstate, NULL, NULL, NULL,
0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | \
MASK_REGISTER2 | MASK_REGISTER3,
MASK_REGISTER2, 0, 0, DEVICE_DC, 0, NULL);
/*
* Define usage for "private" IO_DEVICE data areas.
*/
#define iod_lastIO iod_private
#define iod_target iod_private2
#define iod_svcstate iod_private3
#define iod_CWA iod_private6
#define iod_LWA iod_private7
#define iod_nextAddr iod_private8
#define iod_reg iod_private9
/*
* Define current state of the 1706-A with respect to the Direct Storage
* Access Bus.
*/
#define IO_BDC_IDLE 0x00
#define IO_BDC_STARTR 0x01 /* Start read sequence */
#define IO_BDC_STARTW 0x02 /* Start write sequence */
#define IO_BDC_READING 0x03 /* Read sequence in progress */
#define IO_BDC_WRITING 0x04 /* Write sequence in progress */
#define IO_BDC_DONE 0x05 /* Transfer has completed */
/* Buffered Data Channel (DC) data structures
dca_dev DC device descriptor
dcb_dev DC device descriptor
dcc_dev DC device descriptor
dca_unit DC unit
dcb_unit DC unit
dcc_unit DC unit
dc_reg DC register list
dc_mod DC modifier list
*/
UNIT dca_unit[] = {
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) }
};
UNIT dcb_unit[] = {
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) }
};
UNIT dcc_unit[] = {
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) },
{UDATA(&dc_svc, UNIT_DISABLE, 0) }
};
REG dca_reg[] = {
{ HRDATA(STATUS, DCAdev.iod_readR[2], 16) },
{ HRDATA(CWA, DCAdev.iod_CWA, 16) },
{ HRDATA(NEXT, DCAdev.iod_nextAddr, 16) },
{ HRDATA(LWA, DCAdev.iod_LWA, 16) },
{ HRDATA(IENABLE, DCAdev.IENABLE, 16) },
{ NULL }
};
REG dcb_reg[] = {
{ HRDATA(STATUS, DCBdev.iod_readR[2], 16) },
{ HRDATA(CWA, DCBdev.iod_CWA, 16) },
{ HRDATA(NEXT, DCBdev.iod_nextAddr, 16) },
{ HRDATA(LWA, DCBdev.iod_LWA, 16) },
{ HRDATA(IENABLE, DCBdev.IENABLE, 16) },
{ NULL }
};
REG dcc_reg[] = {
{ HRDATA(STATUS, DCCdev.iod_readR[2], 16) },
{ HRDATA(CWA, DCCdev.iod_CWA, 16) },
{ HRDATA(NEXT, DCCdev.iod_nextAddr, 16) },
{ HRDATA(LWA, DCCdev.iod_LWA, 16) },
{ HRDATA(IENABLE, DCCdev.IENABLE, 16) },
{ NULL }
};
MTAB dc_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "1706-A", NULL, NULL, NULL },
{ MTAB_XTD|MTAB_VUN, 0, "TARGET", NULL, NULL, &show_target, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, NULL, "INTERRUPT", &set_intr, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "INTERRUPT", NULL, NULL, &show_intr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DEBUG", NULL, NULL, &show_debug, NULL },
{ 0 }
};
DEBTAB dc_deb[] = {
{ "TRACE", DBG_DTRACE },
{ "STATE", DBG_DSTATE },
{ "INTR", DBG_DINTR },
{ "LOCATION", DBG_DLOC },
{ "ALL", DBG_DTRACE | DBG_DSTATE | DBG_DINTR | DBG_DLOC },
{ NULL }
};
DEVICE dca_dev = {
"DCA", dca_unit, dca_reg, dc_mod,
0, 16, 16, 1, 16, 16,
NULL, NULL, &dc_reset,
NULL, NULL, NULL,
&DCAdev,
DEV_DEBUG | DEV_NOEQUIP | DEV_INDEV | DEV_OUTDEV, 0, dc_deb,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
DEVICE dcb_dev = {
"DCB", dcb_unit, dcb_reg, dc_mod,
0, 16, 16, 1, 16, 16,
NULL, NULL, &dc_reset,
NULL, NULL, NULL,
&DCBdev,
DEV_DEBUG | DEV_NOEQUIP | DEV_INDEV | DEV_OUTDEV, 0, dc_deb,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
DEVICE dcc_dev = {
"DCC", dcc_unit, dcc_reg, dc_mod,
0, 16, 16, 1, 16, 16,
NULL, NULL, &dc_reset,
NULL, NULL, NULL,
&DCCdev,
DEV_DEBUG | DEV_NOEQUIP | DEV_INDEV | DEV_OUTDEV, 0, dc_deb,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
static DEVICE *dc_devices[IO_1706_MAX] = {
&dca_dev, &dcb_dev, &dcc_dev
};
/*
* Dump the current state of the Buffered Data Channel.
*/
const char *DCstateStr[] = {
"Idle", "StartR", "StartW", "Read", "Write", "Done"
};
void DCstate(const char *where, DEVICE *dev, IO_DEVICE *iod)
{
fprintf(DBGOUT,
"%s[%s %s: Sta: %04X, %s, ena: %04X, cur: %04X, next: %04X, last: %04X, reg: %d]\r\n",
INTprefix, dev->name, where,
DCSTATUS(iod), DCstateStr[iod->iod_svcstate], ENABLED(iod),
iod->iod_CWA, iod->iod_nextAddr, iod->iod_LWA, iod->iod_reg);
}
/*
* Display device description.
*/
static const char *description(DEVICE *dptr)
{
return "1706-A";
}
/*
* Unit service
*/
t_stat dc_svc(UNIT *uptr)
{
DEVICE *dptr;
enum IOstatus status;
uint16 temp;
if ((dptr = find_dev_from_unit(uptr)) != NULL) {
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
IO_DEVICE *target = (IO_DEVICE *)iod->iod_target;
if ((dptr->dctrl & DBG_DSTATE) != 0)
DCstate("dc_svc() entry", iod->iod_indev, iod);
switch (iod->iod_svcstate) {
case IO_BDC_IDLE:
return SCPE_OK;
case IO_BDC_STARTR:
case IO_BDC_STARTW:
if ((dptr->dctrl & DBG_DTRACE) != 0)
fprintf(DBGOUT,
"%s%s - Start %s on %s, current: %04X, last: %04X\r\n",
INTprefix, dptr->name,
iod->iod_svcstate == IO_BDC_STARTR ? "input" : "output",
target == NULL ? "no device" : target->iod_indev->name,
iod->iod_CWA, iod->iod_LWA);
iod->iod_svcstate =
iod->iod_svcstate == IO_BDC_STARTR ? IO_BDC_READING : IO_BDC_WRITING;
sim_activate(uptr, DC_IO_WAIT);
if ((dptr->dctrl & DBG_DSTATE) != 0)
DCstate("dc_svc() - started", iod->iod_indev, iod);
return SCPE_OK;
case IO_BDC_READING:
if (target != NULL) {
if ((target->STATUS & IO_ST_EOP) != 0)
goto ioDone;
if (iod->iod_CWA == iod->iod_LWA) {
/*
* Transfer complete - complete status change and, optionally,
* generate interrupt.
*/
iod->iod_svcstate = IO_BDC_DONE;
sim_activate(uptr, DC_EOP_WAIT);
if ((dptr->dctrl & DBG_DSTATE) != 0)
DCstate("dc_svc() - read complete", iod->iod_indev, iod);
return SCPE_OK;
}
DCSTATUS(iod) &= ~(IO_1706_REPLY | IO_1706_REJECT);
iod->iod_nextAddr = iod->iod_CWA + 1;
status = fw_doBDCIO(target, &temp, FALSE, iod->iod_reg);
switch (status) {
case IO_REPLY:
DCSTATUS(iod) |= IO_1706_REPLY;
if (!IOStoreToMem(iod->iod_CWA, temp, TRUE)) {
DCSTATUS(iod) |= IO_1706_PROT;
/*** TODO: Signal protect fault ***/
}
iod->iod_CWA++;
if ((dptr->dctrl & DBG_DTRACE) != 0)
fprintf(DBGOUT,
"%s%s - Read %04X\r\n",
INTprefix, dptr->name, temp);
break;
case IO_REJECT:
case IO_INTERNALREJECT:
DCSTATUS(iod) |= IO_1706_REJECT;
break;
}
} else DCSTATUS(iod) |= IO_1706_REJECT;
sim_activate(uptr, DC_IO_WAIT);
if ((dptr->dctrl & DBG_DSTATE) != 0)
DCstate("dc_svc() - reading", iod->iod_indev, iod);
return SCPE_OK;
case IO_BDC_WRITING:
if (target != NULL) {
if ((target->STATUS & IO_ST_EOP) != 0)
goto ioDone;
if (iod->iod_CWA == iod->iod_LWA) {
/*
* Transfer complete - complete status change and, optionally,
* generate interrupt.
*/
iod->iod_svcstate = IO_BDC_DONE;
sim_activate(uptr, DC_EOP_WAIT);
if ((dptr->dctrl & DBG_DSTATE) != 0)
DCstate("dc_svc() - write complete", iod->iod_indev, iod);
return SCPE_OK;
}
DCSTATUS(iod) &= ~(IO_1706_REPLY | IO_1706_REJECT);
iod->iod_nextAddr = iod->iod_CWA + 1;
temp = LoadFromMem(iod->iod_CWA);
status = fw_doBDCIO(target, &temp, TRUE, iod->iod_reg);
switch (status) {
case IO_REPLY:
DCSTATUS(iod) |= IO_1706_REPLY;
iod->iod_CWA++;
break;
case IO_REJECT:
case IO_INTERNALREJECT:
DCSTATUS(iod) |= IO_1706_REJECT;
break;
}
} else DCSTATUS(iod) |= IO_1706_REJECT;
sim_activate(uptr, DC_IO_WAIT);
if ((dptr->dctrl & DBG_DSTATE) != 0)
DCstate("dc_svc() - writing", iod->iod_indev, iod);
return SCPE_OK;
case IO_BDC_DONE:
/*
* The transfer has completed as far as the 1706-A is concerned.
*/
ioDone:
iod->iod_svcstate = IO_BDC_IDLE;
DCSTATUS(iod) |= IO_ST_EOP;
DCSTATUS(iod) &= ~IO_ST_BUSY;
if (ISENABLED(iod, IO_DIR_EOP) && (iod->iod_equip != 0)) {
DEVICE *dptr = iod->iod_indev;
if ((dptr->dctrl & DBG_DINTR) != 0)
fprintf(DBGOUT,
"%s%s - Generate EOP interrupt\r\n",
INTprefix, dptr->name);
DCSTATUS(iod) |= IO_ST_INT;
RaiseExternalInterrupt(dptr);
}
if ((dptr->dctrl & DBG_DSTATE) != 0)
DCstate("dc_svc() - EOP set", iod->iod_indev, iod);
return SCPE_OK;
}
}
return SCPE_NXDEV;
}
/*
* Reset routine
*/
t_stat dc_reset(DEVICE *dptr)
{
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
DEVRESET(iod);
DCSTATUS(iod) = IO_ST_READY;
return SCPE_OK;
}
/*
* Set the interrupt level for a buffered data channel.
*/
t_stat set_intr(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
IO_DEVICE *iod = (IO_DEVICE *)uptr->up7;
t_value v;
t_stat r;
if (cptr == NULL)
return SCPE_ARG;
v = get_uint(cptr, DEV_RDX, 15, &r);
if (r != SCPE_OK)
return r;
if (v == 0)
return SCPE_ARG;
iod->iod_equip = v;
iod->iod_interrupt = 1 << v;
return SCPE_OK;
}
/*
* Display the current interrupt level.
*/
t_stat show_intr(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
IO_DEVICE *iod = (IO_DEVICE *)uptr->up7;
if (iod->iod_equip != 0) {
fprintf(st, "Interrupt: ");
fprint_val(st, (t_value)iod->iod_equip, DEV_RDX, 8, PV_LEFT);
} else fprintf(st, "Interrupt: None");
return SCPE_OK;
}
/*
* Display buffered data channel target device and equipment address
*/
t_stat show_target(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
DEVICE *dptr;
IO_DEVICE *iod;
if (uptr == NULL)
return SCPE_IERR;
iod = (IO_DEVICE *)uptr->up8;
dptr = iod->iod_indev;
fprintf(st, "Target: %s (%s), Equip: %d",
sim_dname(dptr), iod->iod_model, iod->iod_equip);
return SCPE_OK;
}
/*
* Check if I/O should be rejected. I/O allowed if:
*
* Reg. Write (OUT) Read (INP)
*
* 00 Not busy Not busy
* 01 Not busy Always allowed
* 02 Not busy Always allowed
* 03 Not busy Always allowed
*/
t_bool DCreject(IO_DEVICE *iod, t_bool output, uint8 reg)
{
if (output || (reg == 0))
return (DCSTATUS(iod) & IO_ST_BUSY) != 0;
return FALSE;
}
/*
* Start a buffered data channel transfer. Note that target may be NULL if
* an attempt is made to access a device which is not connected to the
* buffered data channel. We need to delay starting the transaction so that
* there is sufficient time to grab the current bufferered data channel
* status and terminate the transfer before starting the actual transfer.
* The diagnostics check for this particular case.
*/
enum IOstatus DCxfer(IO_DEVICE *iod, IO_DEVICE *target, t_bool output)
{
DEVICE *dptr = (DEVICE *)iod->iod_indev;
iod->iod_LWA = LoadFromMem(IOAreg);
iod->iod_CWA = iod->iod_nextAddr = ++IOAreg;
iod->iod_target = target;
if (target != NULL)
iod->iod_reg = IOQreg & target->iod_rmask;
DCSTATUS(iod) &= ~IO_ST_EOP;
DCSTATUS(iod) |= IO_ST_BUSY;
iod->iod_svcstate = output ? IO_BDC_STARTW : IO_BDC_STARTR;
sim_activate(&dptr->units[0], DC_START_WAIT);
if ((dptr->dctrl & DBG_DTRACE) != 0)
fprintf(DBGOUT,
"%s%s - starting %s transfer, cur: %04X, last: %04X\r\n",
INTprefix, dptr->name, output ? "output" : "input",
iod->iod_CWA, iod->iod_LWA);
return IO_REPLY;
}
/*
* Perform a buffered data channel input operation
*/
enum IOstatus DCin(IO_DEVICE *iod, uint8 reg)
{
IO_DEVICE *target;
enum IOstatus status;
/*
* If the "Continue" bit is set in Q, use the last I/O address and treat the
* request as a direct input/output operation.
*/
if ((IOQreg & IO_CONTINUE) != 0) {
IOQreg = iod->iod_lastIO;
reg = 0;
} else iod->iod_lastIO = IOQreg;
/*
* The framework filters out INP requests for the status register.
*/
switch (reg) {
/*
* Perform a direct input request from the target device.
*/
case 0x00:
/*
* Find the target device to be used.
*/
if ((target = fw_findChanDevice(iod, IOQreg)) == NULL)
return IO_REJECT;
if ((target->iod_indev->dctrl & DBG_DSTATE) != 0)
if (target->iod_state != NULL)
(*target->iod_state)("before direct in", target->iod_indev, target);
status = fw_doIO(target->iod_indev, FALSE);
if ((target->iod_indev->dctrl & DBG_DSTATE) != 0)
if (target->iod_state != NULL)
(*target->iod_state)("after direct in", target->iod_indev, target);
return status;
/*
* Terminate buffer, 1706 Current Address.
*/
case 0x01:
iod->iod_svcstate = IO_BDC_IDLE;
DCSTATUS(iod) &= ~IO_ST_BUSY;
/* FALLTHROUGH */
/*
* 1706 Current Address. May be the next address depending on where we
* are in the actual transfer sequence.
*/
case 0x03:
Areg = iod->iod_nextAddr;
return IO_REPLY;
}
return IO_REJECT;
}
/*
* Perform a buffered data channel output operation
*/
enum IOstatus DCout(IO_DEVICE *iod, uint8 reg)
{
IO_DEVICE *target;
enum IOstatus status;
/*
* If the "Continue" bit is set in Q, use the last I/O address and treat the
* request as a direct input/output operation.
*/
if ((IOQreg & IO_CONTINUE) != 0) {
IOQreg = iod->iod_lastIO;
reg = 0;
} else iod->iod_lastIO = IOQreg;
/*
* Find the target device to be used. If the target device is not connected
* to the buffered data channel, the REJECT will eventually be processed
* in dc_svc().
*/
target = fw_findChanDevice(iod, IOQreg);
if ((target == NULL) && (reg == 0x00))
return IO_REJECT;
switch (reg) {
/*
* Perform a direct output request to the target device.
*/
case 0x00:
if ((target->iod_indev->dctrl & DBG_DSTATE) != 0)
if (target->iod_state != NULL)
(*target->iod_state)("before direct out", target->iod_indev, target);
status = fw_doIO(target->iod_indev, TRUE);
if ((target->iod_indev->dctrl & DBG_DSTATE) != 0)
if (target->iod_state != NULL)
(*target->iod_state)("after direct out", target->iod_indev, target);
return status;
/*
* Command function to the 1706-A.
*/
case 0x01:
if ((IOAreg & IO_1706_EOP) != 0) {
iod->OLDIENABLE = iod->IENABLE;
if ((IOAreg & IO_1706_SET) != 0)
iod->IENABLE |= IO_DIR_EOP;
else iod->IENABLE &= ~IO_DIR_EOP;
DCSTATUS(iod) &= ~(IO_ST_INT | IO_ST_EOP);
rebuildPending();
}
return IO_REPLY;
/*
* Initiate buffered output on the 1706-A.
*/
case 0x02:
return DCxfer(iod, target, TRUE);
/*
* Initiate buffered input on the 1706-A.
*/
case 0x03:
return DCxfer(iod, target, FALSE);
}
return IO_REJECT;
}
/*
* Build the buffered data channel tables.
*/
void buildDCtables(void)
{
int i;
uint8 chan;
DEVICE *dptr;
UNIT *uptr;
dca_dev.numunits = 0;
dcb_dev.numunits = 0;
dcc_dev.numunits = 0;
dca_dev.units[0].up7 = &DCAdev;
dcb_dev.units[0].up7 = &DCBdev;
dcc_dev.units[0].up7 = &DCCdev;
for (i = 0; i < 16; i++) {
if ((dptr = IOdev[i]) != NULL) {
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
if (((chan = iod->iod_dc) != 0) &&
((iod->iod_flags & AQ_ONLY) == 0)) {
dptr = dc_devices[IDX_FROM_CHAN(chan)];
uptr = &dptr->units[dptr->numunits];
if (dptr->numunits < IO_1706_DEVS) {
uptr->up8 = iod;
dptr->numunits++;
}
}
}
}
}
/*
* Create bit map of interrupts asserted by the Buffered Data Channels.
*/
uint16 dcINTR(void)
{
uint16 result = 0;
if ((DCSTATUS(&DCAdev) & IO_ST_INT) != 0)
result |= DCAdev.iod_interrupt;
if ((DCSTATUS(&DCBdev) & IO_ST_INT) != 0)
result |= DCBdev.iod_interrupt;
if ((DCSTATUS(&DCCdev) & IO_ST_INT) != 0)
result |= DCCdev.iod_interrupt;
return result;
}

919
CDC1700/cdc1700_defs.h Normal file
View file

@ -0,0 +1,919 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_defs.h: CDC1700 simulator definitions
*/
#ifndef _CDC1700_DEFS_H
#define _CDC1700_DEFS_H
#include "sim_defs.h"
#include "sim_tape.h"
#define DBGOUT (sim_deb != NULL ? sim_deb : stdout)
/*
* Private status codes
*/
#define SCPE_LOOP 1 /* Indirect addressing loop */
#define SCPE_SSTOP 2 /* Selective stop */
#define SCPE_INVEXI 3 /* Invalid bit in EXI delta */
#define SCPE_IBKPT 4 /* Breakpoint */
#define SCPE_REJECT 5 /* Stop on reject */
/*
* Private device flags
*/
#define DEV_V_REJECT (DEV_V_UF + 1) /* Stop on reject enabled */
#define DEV_V_NOEQUIP (DEV_V_UF + 2) /* Not an equipment device */
#define DEV_V_INDEV (DEV_V_UF + 3) /* Input device for IO_DEVICE */
#define DEV_V_OUTDEV (DEV_V_UF + 4) /* Output device for IO_DEVICE */
#define DEV_V_PROTECT (DEV_V_UF + 5) /* Device supports protection */
#define DEV_V_PROTECTED (DEV_V_UF + 6) /* Device protection enabled */
#define DEV_V_REVERSE (DEV_V_UF + 7) /* DP reverse addressing */
#define DEV_V_FIXED (DEV_V_UF + 7) /* CDD fixed drive first addressing */
#define DEV_REJECT (1 << DEV_V_REJECT)
#define DEV_NOEQUIP (1 << DEV_V_NOEQUIP)
#define DEV_INDEV (1 << DEV_V_INDEV)
#define DEV_OUTDEV (1 << DEV_V_OUTDEV)
#define DEV_PROTECT (1 << DEV_V_PROTECT)
#define DEV_PROTECTED (1 << DEV_V_PROTECTED)
#define DEV_REVERSE (1 << DEV_V_REVERSE)
#define DEV_FIXED (1 << DEV_V_FIXED)
/*
* CPU debug flags
*/
#define DBG_V_DISASS 0 /* Disassemble on execution */
#define DBG_V_IDISASS 1 /* Disassemble during interrupt */
#define DBG_V_INTR 2 /* Indicate interrupt execution */
#define DBG_V_TRACE 3 /* Trace register content */
#define DBG_V_ITRACE 4 /* Trace during interrupt */
#define DBG_V_TARGET 5 /* Output target address */
#define DBG_V_INPUT 6 /* Trace input operations */
#define DBG_V_OUTPUT 7 /* Trace output operations */
#define DBG_V_FULL 8 /* Full Trace (emulator debug) */
#define DBG_V_INTLVL 9 /* Prefix with interrupt level */
#define DBG_V_PROTECT 10 /* Display protect fault information */
#define DBG_V_MISSING 11 /* Display access to missing devices */
#define DBG_DISASS (1 << DBG_V_DISASS)
#define DBG_IDISASS (1 << DBG_V_IDISASS)
#define DBG_INTR (1 << DBG_V_INTR)
#define DBG_TRACE (1 << DBG_V_TRACE)
#define DBG_ITRACE (1 << DBG_V_ITRACE)
#define DBG_TARGET (1 << DBG_V_TARGET)
#define DBG_INPUT (1 << DBG_V_INPUT)
#define DBG_OUTPUT (1 << DBG_V_OUTPUT)
#define DBG_FULL (1 << DBG_V_FULL)
#define DBG_INTLVL (1 << DBG_V_INTLVL)
#define DBG_PROTECT (1 << DBG_V_PROTECT)
#define DBG_MISSING (1 << DBG_V_MISSING)
/*
* Default device radix
*/
#define DEV_RDX 16
/*
* Private unit flags
*/
#define UNIT_V_7TRACK (MTUF_V_UF + 0) /* 7-track tape transport */
#define UNIT_V_WPROT (MTUF_V_UF + 1) /* Write protected */
#define UNIT_V_854 (UNIT_V_UF + 0) /* 854 vs. 853 disk pack drive */
#define UNIT_V_856_4 (UNIT_V_UF + 0) /* 856_4 vs. 856_2 drive */
#define UNIT_7TRACK (1 << UNIT_V_7TRACK)
#define UNIT_WPROT (1 << UNIT_V_WPROT)
#define UNIT_854 (1 << UNIT_V_854)
#define UNIT_856_4 (1 << UNIT_V_856_4)
/*
* CPU
*/
#define MAXMEMSIZE 65536
#define DEFAULTMEMSIZE 32768
/*
* Compute the actual memory address based on the amount of memory installed
* on the system. Note we only support power of 2 memories like the real
* hardware - the system reference manual says that 12K and 24K systems are
* possible but not supported by standard software.
*/
#define MEMADDR(p) ((p) & (cpu_unit.capac - 1))
/*
* Protect bit access
*/
#define SETPROTECT(a) P[MEMADDR(a)] = 1
#define CLRPROTECT(a) P[MEMADDR(a)] = 0
#define ISPROTECTED(a) P[MEMADDR(a)]
/*
* Max count of indirect addressing. Used to avoid infinite loops.
*/
#define MAXINDIRECT 10000
/*
* Register access
*/
#define INCP Preg = MEMADDR(Preg + 1)
/*
* I/O operations
*/
enum IOstatus {
IO_REPLY, /* Device sent a reply */
IO_REJECT, /* Device sent a reject */
IO_INTERNALREJECT /* I/O rejected internally */
};
#define SIGN 0x8000
#define MAXPOS 0x7FFF
#define MAXNEG 0xFFFF
#define ABS(v) (((v) & SIGN) ? ~(v) : (v))
/*
* Instruction layout:
*
* Storage reference instructions:
*
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* | op |re|in|i1|i2| delta |
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*
* Register reference instructions:
*
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* | 0 0 0 0| F1 | modifier |
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*
* Inter-register instructions:
*
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* | 0 0 0 0| 1 0 0 0|lp|xr| origin | dest |
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*
* Shift instructions:
*
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* | 0 0 0 0| 1 1 1 1|LR| A| Q| count |
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*
* Skip instructions:
*
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* | 0 0 0 0| 0 0 0 1| type | count |
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
#define MOD_RE 0x800
#define MOD_IN 0x400
#define MOD_I1 0x200
#define MOD_I2 0x100
#define ISCONSTANT(i) ((i & (MOD_RE | MOD_IN | 0xFF)) == 0)
#define OPC_MASK 0xF000
#define OPC_ADQ 0xF000
#define OPC_LDQ 0xE000
#define OPC_RAO 0xD000
#define OPC_LDA 0xC000
#define OPC_EOR 0xB000
#define OPC_AND 0xA000
#define OPC_SUB 0x9000
#define OPC_ADD 0x8000
#define OPC_SPA 0x7000
#define OPC_STA 0x6000
#define OPC_RTJ 0x5000
#define OPC_STQ 0x4000
#define OPC_DVI 0x3000
#define OPC_MUI 0x2000
#define OPC_JMP 0x1000
#define OPC_SPECIAL 0x0000
#define OPC_SPECIALMASK 0x0F00
#define OPC_SLS 0x0000
#define OPC_SKIPS 0x0100
#define OPC_SKIPMASK 0x00F0
#define OPC_SKIPCOUNT 0x000F
#define OPC_SAZ (OPC_SKIPS | 0x00)
#define OPC_SAN (OPC_SKIPS | 0x10)
#define OPC_SAP (OPC_SKIPS | 0x20)
#define OPC_SAM (OPC_SKIPS | 0x30)
#define OPC_SQZ (OPC_SKIPS | 0x40)
#define OPC_SQN (OPC_SKIPS | 0x50)
#define OPC_SQP (OPC_SKIPS | 0x60)
#define OPC_SQM (OPC_SKIPS | 0x70)
#define OPC_SWS (OPC_SKIPS | 0x80)
#define OPC_SWN (OPC_SKIPS | 0x90)
#define OPC_SOV (OPC_SKIPS | 0xA0)
#define OPC_SNO (OPC_SKIPS | 0xB0)
#define OPC_SPE (OPC_SKIPS | 0xC0)
#define OPC_SNP (OPC_SKIPS | 0xD0)
#define OPC_SPF (OPC_SKIPS | 0xE0)
#define OPC_SNF (OPC_SKIPS | 0xF0)
#define OPC_INP 0x0200
#define OPC_OUT 0x0300
#define OPC_EIN 0x0400
#define OPC_IIN 0x0500
#define OPC_ECA 0x0580
#define OPC_DCA 0x05C0
#define OPC_SPB 0x0600
#define OPC_CPB 0x0700
#define OPC_INTER 0x0800
#define MOD_LP 0x80
#define MOD_XR 0x40
#define MOD_O_A 0x20
#define MOD_O_Q 0x10
#define MOD_O_M 0x08
#define MOD_D_A 0x04
#define MOD_D_Q 0x02
#define MOD_D_M 0x01
#define OPC_AAM (OPC_INTER | MOD_O_A | MOD_O_M)
#define OPC_AAQ (OPC_INTER | MOD_O_A | MOD_O_Q)
#define OPC_AAB (OPC_INTER | MOD_O_A | MOD_O_Q | MOD_O_M)
#define OPC_CLR (OPC_INTER | MOD_XR)
#define OPC_TCM (OPC_INTER | MOD_XR | MOD_O_M)
#define OPC_TCQ (OPC_INTER | MOD_XR | MOD_O_Q)
#define OPC_TCB (OPC_INTER | MOD_XR | MOD_O_Q | MOD_O_M)
#define OPC_TCA (OPC_INTER | MOD_XR | MOD_O_A)
#define OPC_EAM (OPC_INTER | MOD_XR | MOD_O_A | MOD_O_M)
#define OPC_EAQ (OPC_INTER | MOD_XR | MOD_O_A | MOD_O_Q)
#define OPC_EAB (OPC_INTER | MOD_XR | MOD_O_A | MOD_O_Q | MOD_O_M)
#define OPC_SET (OPC_INTER | MOD_LP)
#define OPC_TRM (OPC_INTER | MOD_LP | MOD_O_M)
#define OPC_TRQ (OPC_INTER | MOD_LP | MOD_O_Q)
#define OPC_TRB (OPC_INTER | MOD_LP | MOD_O_Q | MOD_O_M)
#define OPC_TRA (OPC_INTER | MOD_LP | MOD_O_A)
#define OPC_LAM (OPC_INTER | MOD_LP | MOD_O_A | MOD_O_M)
#define OPC_LAQ (OPC_INTER | MOD_LP | MOD_O_A | MOD_O_Q)
#define OPC_LAB (OPC_INTER | MOD_LP | MOD_O_A | MOD_O_Q | MOD_O_M)
#define OPC_CAM (OPC_INTER | MOD_LP | MOD_XR | MOD_O_A | MOD_O_M)
#define OPC_CAQ (OPC_INTER | MOD_LP | MOD_XR | MOD_O_A | MOD_O_Q)
#define OPC_CAB (OPC_INTER | MOD_LP | MOD_XR | MOD_O_A | MOD_O_Q | MOD_O_M)
#define OPC_INA 0x0900
#define OPC_ENA 0x0A00
#define OPC_NOP 0x0B00
#define OPC_ENQ 0x0C00
#define OPC_INQ 0x0D00
#define OPC_EXI 0x0E00
#define OPC_MODMASK 0x00FF
#define EXTEND16(v) ((v) & 0x8000) ? (v) | 0xFFFF0000 : (v)
#define EXTEND8(v) ((v) & 0x80) ? (v) | 0xFF00 : (v)
#define EXTEND4(v) ((v) & 0x8) ? (v) | 0xFFF0 : (v)
#define TRUNC16(v) ((v) & 0xFFFF)
#define CANEXTEND8(v) (((v) & 0xFF80) == 0xFF80)
#define OPC_SHIFTS 0x0F00
#define OPC_SHIFTMASK 0x00E0
#define MOD_LR 0x80
#define MOD_S_A 0x40
#define MOD_S_Q 0x20
#define OPC_SHIFTCOUNT 0x001F
#define OPC_ADDRMASK 0x00FF
#define OPC_QRS (OPC_SHIFTS | MOD_S_Q)
#define OPC_ARS (OPC_SHIFTS | MOD_S_A)
#define OPC_LRS (OPC_SHIFTS | MOD_S_A | MOD_S_Q)
#define OPC_QLS (OPC_SHIFTS | MOD_LR | MOD_S_Q)
#define OPC_ALS (OPC_SHIFTS | MOD_LR | MOD_S_A)
#define OPC_LLS (OPC_SHIFTS | MOD_LR | MOD_S_A | MOD_S_Q)
/*
* Interrupt vector definitions
*/
#define INTERRUPT_BASE 0x100
#define INTERRUPT_00 (INTERRUPT_BASE + 0x00)
#define INTERRUPT_01 (INTERRUPT_BASE + 0x04)
#define INTERRUPT_02 (INTERRUPT_BASE + 0x08)
#define INTERRUPT_03 (INTERRUPT_BASE + 0x0C)
#define INTERRUPT_04 (INTERRUPT_BASE + 0x10)
#define INTERRUPT_05 (INTERRUPT_BASE + 0x14)
#define INTERRUPT_06 (INTERRUPT_BASE + 0x18)
#define INTERRUPT_07 (INTERRUPT_BASE + 0x1C)
#define INTERRUPT_08 (INTERRUPT_BASE + 0x20)
#define INTERRUPT_09 (INTERRUPT_BASE + 0x24)
#define INTERRUPT_10 (INTERRUPT_BASE + 0x28)
#define INTERRUPT_11 (INTERRUPT_BASE + 0x2C)
#define INTERRUPT_12 (INTERRUPT_BASE + 0x30)
#define INTERRUPT_13 (INTERRUPT_BASE + 0x34)
#define INTERRUPT_14 (INTERRUPT_BASE + 0x38)
#define INTERRUPT_15 (INTERRUPT_BASE + 0x3C)
#define INTR_BASIC 2
#define INTR_1705 16
/*
* I/O definitions.
*/
#define IO_CONTINUE 0x8000
#define IO_W 0x7800
#define IO_EQUIPMENT 0x0780
#define IO_COMMAND 0x007F
/*
* Standard director functions
*/
#define IO_DIR_STOP 0x0040 /* Stop motion */
#define IO_DIR_START 0x0020 /* Start motion */
#define IO_DIR_ALARM 0x0010 /* Alarm int req. */
#define IO_DIR_EOP 0x0008 /* End of operation int req. */
#define IO_DIR_DATA 0x0004 /* Data int req. */
#define IO_DIR_CINT 0x0002 /* Clear interrupts */
#define IO_DIR_CCONT 0x0001 /* Clear controller */
/*
* Illegal combination of functions - Start + Stop
*/
#define STARTSTOP(v) (((v) & \
(IO_DIR_START | IO_DIR_STOP)) == \
(IO_DIR_START | IO_DIR_STOP))
/*
* Standard status bits
*/
#define IO_ST_PARITY 0x0100 /* Parity error */
#define IO_ST_PROT 0x0080 /* Protected */
#define IO_ST_LOST 0x0040 /* Lost data */
#define IO_ST_ALARM 0x0020 /* Alarm */
#define IO_ST_EOP 0x0010 /* End of operation */
#define IO_ST_DATA 0x0008 /* Data */
#define IO_ST_INT 0x0004 /* Interrupt */
#define IO_ST_BUSY 0x0002 /* Device busy */
#define IO_ST_READY 0x0001 /* Device ready */
/*
* The following type/values may be used to differentiate processing when
* a single device driver is used to emulate multiple controller types (e.g.
* the LP device driver emulates both 1740 and 1742-30/-120 controllers).
*/
enum IOdevtype {
IOtype_default, /* Initial value */
IOtype_dev1, /* Device specific values */
IOtype_dev2,
IOtype_dev3,
IOtype_dev4,
IOtype_dev5,
IOtype_dev6,
IOtype_dev7,
IOtype_dev8
};
/*
* I/O framework device structure
*/
struct io_device {
const char *iod_name;
const char *iod_model;
enum IOdevtype iod_type;
uint8 iod_equip;
uint8 iod_station;
uint16 iod_interrupt;
uint16 iod_dcbase;
DEVICE *iod_indev;
DEVICE *iod_outdev;
UNIT *iod_unit;
t_bool (*iod_reject)(struct io_device *, t_bool, uint8);
enum IOstatus (*iod_IOread)(struct io_device *, uint8);
enum IOstatus (*iod_IOwrite)(struct io_device *, uint8);
enum IOstatus (*iod_BDCread)(struct io_device *, uint16 *, uint8);
enum IOstatus (*iod_BDCwrite)(struct io_device *, uint16 *, uint8);
void (*iod_state)(const char *, DEVICE *, struct io_device *);
t_bool (*iod_intr)(struct io_device *);
uint16 (*iod_raised)(DEVICE *);
void (*iod_clear)(DEVICE *);
uint16 iod_ienable;
uint16 iod_oldienable;
uint16 iod_imask;
uint16 iod_dmask;
uint16 iod_smask;
uint16 iod_cmask;
uint16 iod_rmask;
uint8 iod_regs;
uint8 iod_validmask;
uint8 iod_readmap;
uint8 iod_rejmapR;
uint8 iod_rejmapW;
uint8 iod_flags;
uint8 iod_dc;
uint16 iod_readR[8];
uint16 iod_writeR[8];
uint16 iod_prevR[8];
uint16 iod_forced;
t_uint64 iod_event;
uint16 iod_private;
void *iod_private2;
uint16 iod_private3;
t_bool iod_private4;
const char *iod_private5;
uint16 iod_private6;
uint16 iod_private7;
uint16 iod_private8;
uint8 iod_private9;
t_bool iod_private10;
};
#define STATUS iod_readR[1]
#define DEVSTATUS(iod) ((iod)->iod_readR[1])
#define DCSTATUS(iod) ((iod)->iod_readR[2])
#define FUNCTION iod_writeR[1]
#define IENABLE iod_ienable
#define OLDIENABLE iod_oldienable
#define ENABLED(iod) ((iod)->iod_ienable)
#define ISENABLED(iod, mask) \
(((iod)->iod_ienable & mask) != 0)
#define SETSTICKY(iod, reg, value) \
((iod)->iod_sticky[reg] |= value)
#define CLRSTICKY(iod, reg, value) \
((iod)->iod_sticky[reg] &= ~value)
#define MASK_REGISTER0 0x01
#define MASK_REGISTER1 0x02
#define MASK_REGISTER2 0x04
#define MASK_REGISTER3 0x08
#define MASK_REGISTER4 0x10
#define MASK_REGISTER5 0x20
#define MASK_REGISTER6 0x40
#define MASK_REGISTER7 0x80
#define STATUS_ZERO 0x01
#define DEVICE_DC 0x02
#define AQ_ONLY 0x04
#define IODEV(name, model, id, equ, sta, base, busy, ior, iow, bdcr, bdcw, dump, intr, raised, clear, mask, regs, valid, map, rejR, rejW, flags, dc, devspec) \
{ name, model, IOtype_default, equ, sta, 0, base, \
NULL, NULL, NULL, \
busy, ior, iow, bdcr, bdcw, dump, intr, raised, clear, \
0, 0, IO_##id##_INTR, IO_##id##_DIRMSK, IO_##id##_STMSK, \
IO_##id##_STCINT | IO_ST_INT, \
mask, regs, valid, map, rejR, rejW, flags, dc, \
{ 0, 0, 0, 0, 0, 0, 0, 0, }, \
{ 0, 0, 0, 0, 0, 0, 0, 0, }, \
{ 0, 0, 0, 0, 0, 0, 0, 0, }, \
0, 0, 0, devspec, 0, FALSE, NULL, 0, 0, 0, 0, FALSE \
}
typedef struct io_device IO_DEVICE;
#define IODEVICE(dev) ((IO_DEVICE *)dev->ctxt)
#define CHANGED(iod, n) ((iod)->iod_writeR[n] ^ (iod)->iod_prevR[n])
#define ICHANGED(iod) ((iod)->iod_ienable ^ (iod)->iod_oldienable)
#define DEVRESET(iod) \
(iod)->iod_ienable = 0; \
(iod)->iod_oldienable = 0; \
(iod)->iod_forced = 0
/*
* Routine type to return interrupt mask for a device.
*/
typedef uint16 devINTR(DEVICE *);
/*
* Generic device flags
*/
#define DBG_V_DTRACE 0 /* Trace device ops */
#define DBG_V_DSTATE 1 /* Dump device state */
#define DBG_V_DINTR 2 /* Trace device interrupts */
#define DBG_V_DERROR 3 /* Trace device errors */
#define DBG_V_LOC 4 /* Dump instruction location */
#define DBG_V_FIRSTREJ 5 /* Dump only first Reject */
#define DBG_SPECIFIC 6 /* Start of device-specific */
/* flags */
#define DBG_DTRACE (1 << DBG_V_DTRACE)
#define DBG_DSTATE (1 << DBG_V_DSTATE)
#define DBG_DINTR (1 << DBG_V_DINTR)
#define DBG_DERROR (1 << DBG_V_DERROR)
#define DBG_DLOC (1 << DBG_V_LOC)
#define DBG_DFIRSTREJ (1 << DBG_V_FIRSTREJ)
/*
* Device specific values
*/
/*
* CPU is treated as a device but has no interrupts, director functions or
* status bits.
*/
#define IO_CPU_INTR 0
#define IO_CPU_DIRMSK 0
#define IO_CPU_STMSK 0
#define IO_CPU_STCINT 0
/*
* 1706-A Buffered Data Channel
*/
#define IO_1706_1_A 0x1000 /* 1706-A #1 */
#define IO_1706_1_B 0x1800
#define IO_1706_1_C 0x2000
#define IO_1706_1_D 0x2800
#define IO_1706_2_A 0x3800 /* 1706-A #2 */
#define IO_1706_2_B 0x4000
#define IO_1706_2_C 0x4800
#define IO_1706_2_D 0x5000
#define IO_1706_3_A 0x6000 /* 1706-A #3 */
#define IO_1706_3_B 0x6800
#define IO_1706_3_C 0x7000
#define IO_1706_3_D 0x7800
#define IO_1706_SET 0x8000 /* Set/clear for ones */
#define IO_1706_EOP 0x0001 /* Enable interrupt on EOP */
#define IO_1706_PROT 0x0040 /* Program protect fault */
#define IO_1706_REPLY 0x0200 /* Device reply */
#define IO_1706_REJECT 0x0100 /* Device reject */
#define IO_1706_STMSK (IO_1706_REPLY | IO_1706_REJECT | IO_1706_PROT | \
IO_ST_EOP | IO_ST_BUSY | IO_ST_READY)
/*
* A 1706-A has no interrupts, director functions or status bits of it's own
* that are accessible through normal I/O requests.
*/
#define IO_DC_INTR 0
#define IO_DC_DIRMSK 0
#define IO_DC_STMSK 0
#define IO_DC_STCINT 0
#define IO_1706_MAX 3 /* Max # of 1706's allowed */
#define IO_1706_DEVS 8 /* Max devices per channel */
#define IDX_FROM_CHAN(c) (c - 1)
/*
* 1711-A/B, 1712-A Teletypewriter
*/
#define IO_1711_A 0x0090
#define IO_1711_B 0x0091
#define IO_1711_SREAD 0x0200 /* Select read mode */
#define IO_1711_SWRITE 0x0100 /* Select write mode */
#define IO_1711_DIRMSK (IO_1711_SREAD | IO_1711_SWRITE | IO_DIR_ALARM | \
IO_DIR_EOP | IO_DIR_DATA | IO_DIR_CINT | IO_DIR_CCONT)
#define IO_1711_INTR (IO_DIR_ALARM |IO_DIR_EOP | IO_DIR_DATA)
#define IO_1711_MANUAL 0x0800 /* Manual interrupt */
#define IO_1711_MON 0x0400 /* Motor on */
#define IO_1711_RMODE 0x0200 /* Read mode */
#define IO_1711_STMSK (IO_1711_MANUAL | IO_1711_MON | IO_1711_RMODE | \
IO_ST_LOST | IO_ST_ALARM | IO_ST_EOP \
| IO_ST_DATA | IO_ST_INT | IO_ST_BUSY | IO_ST_READY)
#define IO_1711_STCINT (IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA)
/*
* 1721-A/B/C/D, 1722-A/B Paper Tape Reader
*/
#define IO_1721_A 0x00A0
#define IO_1721_B 0x00A1
#define IO_1721_DIRMSK (IO_DIR_STOP | IO_DIR_START | IO_DIR_ALARM | \
IO_DIR_DATA | IO_DIR_CINT | IO_DIR_CCONT)
#define IO_1721_INTR (IO_DIR_ALARM | IO_DIR_DATA)
#define IO_1721_POWERON 0x0400 /* Power on */
#define IO_1721_MOTIONF 0x0200 /* Paper motion failure */
#define IO_1721_EXIST 0x0100 /* Existence code */
#define IO_1721_STMSK (IO_1721_POWERON | IO_1721_MOTIONF | IO_1721_EXIST | \
IO_ST_PROT | IO_ST_LOST | IO_ST_ALARM | \
IO_ST_DATA | IO_ST_INT | IO_ST_BUSY | IO_ST_READY)
#define IO_1721_STCINT (IO_ST_ALARM | IO_ST_DATA)
/*
* 1723-A/B, 1724-A/B Paper Tape Punch
*/
#define IO_1723_A 0x00C0
#define IO_1723_B 0x00C1
#define IO_1723_DIRMSK (IO_DIR_STOP | IO_DIR_START | IO_DIR_ALARM | \
IO_DIR_DATA | IO_DIR_CINT | IO_DIR_CCONT)
#define IO_1723_INTR (IO_DIR_ALARM | IO_DIR_DATA)
#define IO_1723_TAPELOW 0x0800 /* Tape supply low */
#define IO_1723_POWERON 0x0400 /* Power on */
#define IO_1723_BREAK 0x0200 /* Tape break */
#define IO_1723_EXIST 0x0100 /* Existence code */
#define IO_1723_STMSK (IO_1723_TAPELOW | IO_1723_POWERON | IO_1723_BREAK | \
IO_1723_EXIST | IO_ST_PROT | IO_ST_ALARM | \
IO_ST_DATA | IO_ST_INT | IO_ST_BUSY | IO_ST_READY)
#define IO_1723_STCINT (IO_ST_ALARM | IO_ST_DATA)
/*
* 1726 Card Reader
*/
#define IO_1726_GATE 0x0200 /* gate card */
#define IO_1726_NHOL 0x0400 /* Negate hollerith to acsii */
#define IO_1726_RHOL 0x0800 /* Rel. hollerith to ascii */
#define IO_1726_RELOAD 0x1000 /* Reload memory */
#define IO_1726_DIRMSK (IO_1726_RELOAD | IO_1726_RHOL | IO_1726_NHOL | \
IO_1726_GATE | IO_DIR_ALARM | IO_DIR_EOP | \
IO_DIR_DATA | IO_DIR_CINT | IO_DIR_CCONT)
#define IO_1726_INTR (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA)
#define IO_1726_ERROR 0x0100 /* Error */
#define IO_1726_BINARY 0x0200 /* Binary card */
#define IO_1726_SEP 0x0400 /* Separator card */
#define IO_1726_FEED 0x0800 /* Fail to feed */
#define IO_1726_JAM 0x1000 /* Stacker full or jam */
#define IO_1726_EMPTY 0x2000 /* Input tray empty */
#define IO_1726_EOF 0x4000 /* End of file */
#define IO_1726_PWROFF 0x8000 /* Motor power off */
#define IO_1726_STMSK (IO_1726_PWROFF | IO_1726_EOF | IO_1726_EMPTY | \
IO_1726_JAM | IO_1726_FEED | IO_1726_SEP | \
IO_1726_BINARY | IO_1726_ERROR | IO_ST_PROT | \
IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA | \
IO_ST_INT | IO_ST_BUSY | IO_ST_READY)
#define IO_1726_STCINT (IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA)
/*
* 1729-A/B Card Reader
*/
#define IO_1729_A 0x00E0
#define IO_1729_B 0x00E1
#define IO_1729_IEOR 0x0008 /* Interrupt on End of Record */
#define IO_1729_DIRMSK (IO_DIR_STOP | IO_DIR_START | IO_DIR_ALARM | \
IO_1729_IEOR | IO_DIR_DATA | IO_DIR_CINT | \
IO_DIR_CCONT)
#define IO_1729_INTR (IO_DIR_ALARM | IO_1729_IEOR | IO_DIR_DATA)
#define IO_1729_EMPTY 0x0200 /* Read station empty */
#define IO_1729_EXIST 0x0100 /* Existence code */
#define IO_1729_EOR 0x0010 /* End of Record */
#define IO_1729_STMSK (IO_1729_EMPTY | IO_1729_EXIST | IO_ST_PROT | \
IO_ST_LOST | IO_ST_ALARM | IO_1729_EOR | \
IO_ST_DATA | IO_ST_INT | IO_ST_BUSY | \
IO_ST_READY)
#define IO_1729_STCINT (IO_ST_ALARM | IO_1729_EOR | IO_ST_DATA)
/*
* 1732-3 Magnetic Tape Controller
*/
#define IO_1732_WRITE 0x0080 /* Write motion */
#define IO_1732_READ 0x0100 /* Read motion */
#define IO_1732_BACKSP 0x0180 /* Backspace */
#define IO_1732_WFM 0x0280 /* Write file mark/tape mark */
#define IO_1732_SFWD 0x0300 /* Search FM/TM forward */
#define IO_1732_SBACK 0x0380 /* Search FM/TM backward */
#define IO_1732_REWL 0x0400 /* Rewind load */
#define IO_1732_MOTION 0x0780 /* Motion field mask */
#define IO_1732_LRT 0x1000 /* Select low read threshold */
#define IO_1732_DESEL 0x0800 /* Deselect tape unit */
#define IO_1732_SEL 0x0400 /* Select tape unit */
#define IO_1732_UNIT 0x0180 /* Unit mask */
#define IO_1732_ASSEM 0x0040 /* Assembly/Disassembly */
#define IO_1732_1600 0x0020 /* Select 1600 BPI */
#define IO_1732_556 0x0010 /* Select 556 BPI */
#define IO_1732_800 0x0008 /* Select 800 BPI */
#define IO_1732_BINARY 0x0004 /* Binary mode */
#define IO_1732_BCD 0x0002 /* BCD mode */
#define IO_1732_PARITY 0x0006 /* Parity mask */
#define IO_1732_CHAR 0x0001 /* Character mode */
/* 1732-A/B changes */
#define IO_1732A_REWU 0x0600 /* Rewind and unload */
#define IO_1732A_UNIT 0x0380 /* Unit mask */
#define IO_1732A_200 0x0020 /* Select 200 BPI */
#define IO_1732_DIRMSK (IO_1732_MOTION | IO_DIR_ALARM | IO_DIR_EOP | \
IO_DIR_DATA | IO_DIR_CINT | IO_DIR_CCONT)
#define IO_1732_INTR (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA)
#define IO_1732_PROT 0x8000 /* Protect fault */
#define IO_1732_SPE 0x4000 /* Storage parity error */
#define IO_1732_FILL 0x2000 /* Odd byte record in */
/* assembly mode */
#define IO_1732_ACTIVE 0x1000 /* Controller active */
#define IO_1732_FMARK 0x0800 /* At file mark */
#define IO_1732_BOT 0x0400 /* At BOT */
#define IO_1732_EOT 0x0200 /* At EOT */
#define IO_1732_STMSK (IO_1732_PROT | IO_1732_SPE | IO_1732_FILL | \
IO_1732_ACTIVE | IO_1732_FMARK | IO_1732_BOT | \
IO_1732_EOT | IO_ST_PARITY | IO_ST_PROT | \
IO_ST_LOST | IO_ST_ALARM | IO_ST_EOP | \
IO_ST_DATA | IO_ST_INT | IO_ST_BUSY | \
IO_ST_READY)
#define IO_1732_STCINT (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA)
#define IO_ST2_LRT 0x0200 /* Low read threshold */
#define IO_ST2_IDABORT 0x0100 /* ID abort */
#define IO_ST2_PETRANS 0x0080 /* PE capable transport */
#define IO_ST2_PELOST 0x0040 /* PE - lost data */
#define IO_ST2_PEWARN 0x0020 /* PE - error warning */
#define IO_ST2_WENABLE 0x0010 /* Write enable */
#define IO_ST2_7TRACK 0x0008 /* Seven track transport */
#define IO_ST2_1600 0x0004 /* 1600 BPI */
#define IO_ST2_800 0x0002 /* 800 BPI */
#define IO_ST2_556 0x0001 /* 556 BPI */
#define IO_1732_ST2MSK (IO_ST2_LRT | IO_ST2_IDABORT | IO_ST2_PETRANS | \
IO_ST2_PELOST | IO_ST2_PEWARN | IO_ST2_WENABLE | \
IO_ST2_7TRACK | IO_ST2_1600 | IO_ST2_800 | \
IO_ST2_556)
#define IO_1732A_ST2MSK (IO_ST2_WENABLE | IO_ST2_7TRACK | IO_ST2_800 | \
IO_ST2_556)
/*
* 1733-2 Cartridge Disk Drive Controller
*/
#define IO_1733_USC 0x0600 /* Unit select code */
#define IO_1733_USEL 0x0100 /* Unit select */
#define IO_1733_UDSEL 0x0080 /* Unit de-select */
#define IO_1733_RBINT 0x0004 /* Ready and not busy int */
#define IO_1733_DIRMSK (IO_1733_USC | IO_1733_USEL | IO_1733_UDSEL | \
IO_DIR_ALARM | IO_DIR_EOP | IO_1733_RBINT | \
IO_DIR_CINT)
#define IO_1733_INTR (IO_DIR_ALARM | IO_DIR_EOP | IO_1733_RBINT)
#define IO_1733_DSEEK 0x8000 /* Drive seek error */
#define IO_1733_SPROT 0x4000 /* Storage protect fault */
#define IO_1733_SPAR 0x2000 /* Storage parity error */
#define IO_1733_SINGLE 0x1000 /* Single density */
#define IO_1733_CSEEK 0x0800 /* Controller seek error */
#define IO_1733_ADDRERR 0x0400 /* Address error */
#define IO_1733_LOST 0x0200 /* Lost data */
#define IO_1733_CWERR 0x0100 /* Checkword error */
#define IO_1733_NOCOMP 0x0040 /* No compare */
#define IO_1733_ONCYL 0x0008 /* On cylinder */
#define IO_1733_STMSK (IO_1733_DSEEK | IO_1733_SPROT | IO_1733_SPAR | \
IO_1733_SINGLE | IO_1733_CSEEK | IO_1733_ADDRERR | \
IO_1733_LOST | IO_1733_CWERR | IO_ST_PROT | \
IO_1733_NOCOMP | IO_ST_ALARM | IO_ST_EOP | \
IO_1733_ONCYL | IO_ST_INT | IO_ST_BUSY | \
IO_ST_READY)
#define IO_1733_STCINT (IO_ST_ALARM | IO_ST_EOP)
/*
* 1738-A/B Disk Pack Controller
*/
#define IO_1738_USC 0x0200 /* Unit select code */
#define IO_1738_USEL 0x0100 /* Unit select */
#define IO_1738_REL 0x0080 /* Release */
#define IO_1738_RBINT 0x0004 /* Ready and not busy int */
#define IO_1738_DIRMSK (IO_1738_USC | IO_1738_USEL | IO_1738_REL | \
IO_DIR_ALARM | IO_DIR_EOP | IO_1738_RBINT | \
IO_DIR_CINT)
#define IO_1738_INTR (IO_DIR_ALARM | IO_DIR_EOP | IO_1738_RBINT)
#define IO_1738_SPROT 0x4000 /* Storage protect fault */
#define IO_1738_SPAR 0x2000 /* Storage parity error */
#define IO_1738_DEFECT 0x1000 /* Defective track */
#define IO_1738_ADDRERR 0x0800 /* Address error */
#define IO_1738_SKERR 0x0400 /* Seek error */
#define IO_1738_LOST 0x0200 /* Lost data */
#define IO_1738_CWERR 0x0100 /* Checkword error */
#define IO_1738_NOCOMP 0x0040 /* No compare */
#define IO_1738_ONCYL 0x0008 /* On cylinder */
#define IO_1738_STMSK (IO_1738_SPROT | IO_1738_SPAR | IO_1738_DEFECT | \
IO_1738_ADDRERR | IO_1738_SKERR | IO_1738_LOST | \
IO_1738_CWERR | IO_ST_PROT | IO_1738_NOCOMP | \
IO_ST_ALARM | IO_ST_EOP | IO_1738_ONCYL | \
IO_ST_INT | IO_ST_BUSY | IO_ST_READY)
#define IO_1738_STCINT (IO_ST_ALARM | IO_ST_EOP)
/*
* 1740 - Line Printer Controller
*/
#define IO_1740_CPRINT 0x0001 /* Clear printer */
#define IO_1740_DIRMSK (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA | \
IO_DIR_CINT | IO_1740_CPRINT)
#define IO_1740_INTR (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA)
#define IO_1740_L12 0x4000 /* Level 12 */
#define IO_1740_L7 0x0200 /* Level 7 */
#define IO_1740_L6 0x0100 /* Level 6 */
#define IO_1740_L5 0x0080 /* Level 5 */
#define IO_1740_L4 0x0040 /* Level 4 */
#define IO_1740_L3 0x0020 /* Level 3 */
#define IO_1740_L2 0x0010 /* Level 2 */
#define IO_1740_L1 0x0008 /* Level 1 */
#define IO_1740_DSP 0x0004 /* Double space */
#define IO_1740_SSP 0x0002 /* Single space */
#define IO_1740_PRINT 0x0001 /* Print */
#define IO_1740_DIR2MSK (IO_1740_L12 | IO_1740_L7 | IO_1740_L6 | \
IO_1740_L5 | IO_1740_L4 | IO_1740_L3 | \
IO_1740_L2 | IO_1740_L1 | IO_1740_DSP | \
IO_1740_SSP | IO_1740_PRINT)
#define IO_1740_LEVELS (IO_1740_L1 | IO_1740_L2 | IO_1740_L3 | \
IO_1740_L4 | IO_1740_L5 | IO_1740_L6 | \
IO_1740_L7 | IO_1740_L12)
#define IO_1740_MOTION (IO_1740_SSP | IO_1740_DSP | IO_1740_LEVELS)
#define IO_1740_STMSK (IO_ST_PROT | IO_ST_ALARM | IO_ST_EOP | \
IO_ST_DATA | IO_ST_INT | IO_ST_BUSY | \
IO_ST_READY)
#define IO_1740_STCINT (IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA)
/*
* 1742-30/-120 Line Printer
*/
#define IO_1742_PRINT 0x0020 /* Print */
#define IO_1742_DIRMSK (IO_1742_PRINT | IO_DIR_ALARM | IO_DIR_EOP | \
IO_DIR_DATA | IO_DIR_CINT | IO_DIR_CCONT)
#define IO_1742_INTR (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA)
#define IO_1742_LIMAGE 0x0100 /* Load image (-120 only) */
#define IO_1742_ERROR 0x0040 /* Device error */
#define IO_1742_STMSK (IO_1742_LIMAGE | IO_ST_PROT | IO_1742_ERROR | \
IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA | \
IO_ST_INT | IO_ST_BUSY | IO_ST_READY)
#define IO_1742_STCINT (IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA)
/*
* 10336-1 Real-Time Clock
*/
#define IO_10336_ACK 0x0002 /* Acknowledge interrupt */
#define IO_10336_STOP 0x0040 /* Stop clock */
#define IO_10336_START 0x0080 /* Start clock */
#define IO_10336_DIS 0x4000 /* Disable interrupt */
#define IO_10336_ENA 0x8000 /* Enable interrupt */
#define IO_10336_DIRMSK (IO_10336_ENA | IO_10336_DIS | IO_10336_START | \
IO_10336_STOP | IO_10336_ACK | IO_DIR_CCONT)
#define IO_10336_INTR 0
#define IO_10336_STMSK 0
#define IO_10336_STCINT 0
/*
* Timing parameters
*/
#define TT_OUT_WAIT 200 /* TTY output wait time */
#define TT_IN_XFER 60 /* TTY input transfer delay */
#define TT_IN_MOTION 500 /* TTY paper motion delay */
#define PTP_OUT_WAIT 500 /* Punch output wait time */
#define PTR_IN_WAIT 450 /* Reader input wait time */
#define LP_OUT_WAIT 15 /* Line printer output wait time */
#define LP_PRINT_WAIT 3000 /* Print line wait time */
#define LP_CC_WAIT 300 /* Control char wait time */
#define MT_MOTION_WAIT 150 /* Magtape motion delay */
#define MT_RDATA_DELAY 46 /* Read data avail. period */
#define MT_WDATA_DELAY 46 /* Write data ready period */
#define MT_200_WAIT 134 /* I/O latency (200 bpi) */
#define MT_556_WAIT 48 /* I/O latency (556 bpi) */
#define MT_800_WAIT 33 /* I/O latency (800 bpi) */
#define MT_1600_WAIT 16 /* I/O latency (1600 bpi) */
#define MT_MIN_WAIT 10 /* Minimum I/O latency */
#define MT_REC_WAIT 100 /* Magtape record latency */
#define MT_TM_WAIT 200 /* Magtape write TM latency */
#define MT_EOP_WAIT 100 /* Magtape EOP latency */
#define DP_XFER_WAIT 300 /* Control info xfer time */
#define DP_SEEK_WAIT 2000 /* Seek wait time */
#define DP_IO_WAIT 1000 /* Sector I/O wait time */
#define CD_SEEK_WAIT 1100 /* Seek wait time */
#define CD_IO_WAIT 800 /* Sector I/O wait time */
#define CD_RTZS_WAIT 200 /* Return to zero seek wait */
#define DC_START_WAIT 4 /* Startup delay */
#define DC_IO_WAIT 4 /* I/O transfer delay */
#define DC_EOP_WAIT 5 /* EOP delay */
#endif

1497
CDC1700/cdc1700_dev1.c Normal file

File diff suppressed because it is too large Load diff

325
CDC1700/cdc1700_dis.c Normal file
View file

@ -0,0 +1,325 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_dis.c: CDC1700 disassembler
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cdc1700_defs.h"
extern uint16 Areg, Mreg, Preg, Qreg, RelBase;
extern uint16 LoadFromMem(uint16);
extern uint8 P[];
extern DEVICE cpu_dev;
extern UNIT cpu_unit;
extern t_stat disEffectiveAddr(uint16, uint16, uint16 *, uint16 *);
extern uint16 doADDinternal(uint16, uint16);
const char *opName[] = {
"???", "JMP", "MUI", "DVI", "STQ", "RTJ", "STA", "SPA",
"ADD", "SUB", "AND", "EOR", "LDA", "RAO", "LDQ", "ADQ"
};
const char *idxName[] = {
"", ",I", ",Q", ",B"
};
const char *spcName[] = {
"SLS", "???", "INP", "OUT", "EIN", "IIN", "SPB", "CPB",
"???", "INA", "ENA", "NOP", "ENQ", "INQ", "EXI", "???"
};
const char *skpName[] = {
"SAZ", "SAN", "SAP", "SAM", "SQZ", "SQN", "SQP", "SQM",
"SWS", "SWN", "SOV", "SNO", "SPE", "SNP", "SPF", "SNF"
};
const char *interName[] = {
"SET", "TRM", "TRQ", "TRB", "TRA", "AAM", "AAQ", "AAB",
"CLR", "TCM", "TCQ", "TCB", "TCA", "EAM", "EAQ", "EAB",
"SET", "TRM", "TRQ", "TRB", "TRA", "LAM", "LAQ", "LAB",
"NOOP", NULL, NULL, NULL, NULL, "CAM", "CAQ", "CAB"
};
const char *destName[] = {
"", "M", "Q", "Q,M", "A", "A,M", "A,Q", "A,Q,M"
};
const char *shiftName[] = {
NULL, "QRS", "ARS", "LRS", NULL, "QLS", "ALS", "LLS"
};
/*
* Generate a single line of text for an instruction. Format is:
*
* c xxxx yyyy zzzz <instr> <targ>
*
* where:
*
* |P Normal/Protected location
* xxxx Memory address of instruction in hex
* yyyy First word of instruction in hex
* zzzz Second word of inctruction in hex, replaced by spaces if
* not present
* <instr> Disassmbled instruction
* <targ> Optional target address and contents
*
* Returns:
* # of words consumed by the instruction
*/
int disassem(char *buf, uint16 addr, t_bool dbg, t_bool targ, t_bool exec)
{
int consumed = 1;
char prot = ISPROTECTED(addr) ? 'P' : ' ';
char mode[8], optional[8], temp[8], decoded[64];
const char *spc, *shift, *inter, *dest;
uint16 instr = LoadFromMem(addr);
uint16 delta = instr & OPC_ADDRMASK;
uint16 t;
strcpy(optional, " ");
strcpy(decoded, "UNDEF");
if ((instr & OPC_MASK) != 0) {
strcpy(decoded, opName[(instr & OPC_MASK) >> 12]);
if ((instr & MOD_RE) == 0)
strcpy(mode, delta == 0 ? "+ " : "- ");
else strcpy(mode, "* ");
switch (instr & OPC_MASK) {
case OPC_ADQ:
case OPC_LDQ:
case OPC_LDA:
case OPC_EOR:
case OPC_AND:
case OPC_SUB:
case OPC_ADD:
case OPC_DVI:
case OPC_MUI:
if (ISCONSTANT(instr))
strcat(mode, "=");
break;
}
if (delta == 0) {
consumed++;
sprintf(optional, "%04X", LoadFromMem(addr + 1));
sprintf(temp, "$%04X", LoadFromMem(addr + 1));
} else sprintf(temp, "$%02X", delta);
strcat(decoded, mode);
if ((instr & MOD_IN) != 0)
strcat(decoded, "(");
strcat(decoded, temp);
if ((instr & MOD_IN) != 0)
strcat(decoded, ")");
strcat(decoded, idxName[(instr & (MOD_I1 | MOD_I2)) >> 8]);
} else {
spc = spcName[(instr & OPC_SPECIALMASK) >> 8];
switch (instr & OPC_SPECIALMASK) {
case OPC_EIN:
case OPC_IIN:
case OPC_SPB:
case OPC_CPB:
case OPC_NOP:
sprintf(decoded, "%s", spc);
break;
case OPC_EXI:
sprintf(decoded, "%s $%02X", spc, instr & OPC_MODMASK);
break;
case OPC_SKIPS:
sprintf(decoded, "%s $%01X",
skpName[(instr & OPC_SKIPMASK) >> 4], instr & OPC_SKIPCOUNT);
break;
case OPC_SLS:
case OPC_INP:
case OPC_OUT:
case OPC_INA:
case OPC_ENA:
case OPC_ENQ:
case OPC_INQ:
sprintf(decoded, "%s $%02X", spc, delta);
break;
case OPC_INTER:
t = instr & (MOD_LP | MOD_XR | MOD_O_A | MOD_O_Q | MOD_O_M);
inter = interName[t >> 3];
dest = destName[instr & (MOD_D_A | MOD_D_Q | MOD_D_M)];
if (inter != NULL)
sprintf(decoded, "%s %s", inter, dest);
break;
case OPC_SHIFTS:
shift = shiftName[(instr & OPC_SHIFTMASK) >> 5];
if (shift != NULL)
sprintf(decoded, "%s $%X", shift, instr & OPC_SHIFTCOUNT);
break;
}
}
if (dbg) {
sprintf(buf, "%c %04X %04X %s %s",
prot, addr, instr, optional, decoded);
} else {
sprintf(buf, "%c %04X %s %s",
prot, instr, optional, decoded);
}
if (targ) {
const char *rel = "";
t_bool indJmp = FALSE;
uint8 more = 0;
uint16 taddr, taddr2, base;
switch (instr & OPC_MASK) {
case OPC_ADQ:
case OPC_LDQ:
case OPC_RAO:
case OPC_LDA:
case OPC_EOR:
case OPC_AND:
case OPC_SUB:
case OPC_ADD:
case OPC_SPA:
case OPC_STA:
case OPC_STQ:
case OPC_DVI:
case OPC_MUI:
if (((instr & (MOD_IN | MOD_I1 | MOD_I2)) == 0) || exec)
if (disEffectiveAddr(addr, instr, &base, &taddr) == SCPE_OK) {
more = cpu_dev.dctrl & DBG_FULL ? 2 : 1;
taddr2 = taddr;
if (((instr & (MOD_RE | MOD_IN | MOD_I1 | MOD_I2)) == MOD_RE) &&
((sim_switches & SWMASK('R')) != 0)) {
taddr2 -= RelBase;
rel = "*";
}
}
break;
case OPC_JMP:
if (((instr & (MOD_IN | MOD_I1 | MOD_I2)) == MOD_IN) & !dbg) {
if (disEffectiveAddr(addr, instr & ~MOD_IN, &base, &taddr) == SCPE_OK) {
taddr2 = taddr;
indJmp = TRUE;
if (((instr & MOD_RE) != 0) && ((sim_switches & SWMASK('R')) != 0)) {
taddr2 -= RelBase;
rel = "*";
}
break;
}
}
/* FALLTHROUGH */
case OPC_RTJ:
if (((instr & (MOD_IN | MOD_I1 | MOD_I2)) != 0) & !dbg)
break;
if (disEffectiveAddr(addr, instr, &base, &taddr) == SCPE_OK) {
more = cpu_dev.dctrl & DBG_FULL ? 2 : 1;
taddr2 = taddr;
if (((instr & (MOD_RE | MOD_IN | MOD_I1 | MOD_I2)) == MOD_RE) &&
((sim_switches & SWMASK('R')) != 0)) {
taddr2 -= RelBase;
rel = "*";
}
}
break;
case OPC_SPECIAL:
switch (instr & OPC_SPECIALMASK) {
case OPC_SLS:
break;
case OPC_SKIPS:
taddr = doADDinternal(MEMADDR(addr + 1), instr & OPC_SKIPCOUNT);
taddr2 = taddr;
if ((sim_switches & SWMASK('R')) != 0)
taddr2 -= RelBase;
more = 1;
break;
case OPC_SPB:
case OPC_CPB:
if (exec) {
taddr = Qreg;
taddr2 = taddr;
if ((sim_switches & SWMASK('R')) != 0)
taddr2 -= RelBase;
more = 1;
}
break;
case OPC_INP:
case OPC_OUT:
case OPC_EIN:
case OPC_IIN:
case OPC_INTER:
case OPC_INA:
case OPC_ENA:
case OPC_NOP:
case OPC_ENQ:
case OPC_INQ:
case OPC_EXI:
case OPC_SHIFTS:
break;
}
break;
}
if (more || indJmp) {
int i, count = 48 - strlen(buf);
for (i = 0; i < count; i++)
strcat(buf, " ");
buf += strlen(buf);
if (indJmp) {
sprintf(buf, "[ => (%04X%s)", taddr2, rel);
} else {
if (more == 1)
sprintf(buf, "[ => %04X%s %s {%04X}", taddr2, rel,
P[MEMADDR(taddr)] ? "(P)" : "",
LoadFromMem(taddr));
else sprintf(buf, "[ => %04X%s (B:%04X%s) %s {%04X}",
taddr2, rel, base, rel,
P[MEMADDR(taddr)] ? "(P)" : "",
LoadFromMem(taddr));
}
}
}
return consumed;
}

1102
CDC1700/cdc1700_dp.c Normal file

File diff suppressed because it is too large Load diff

584
CDC1700/cdc1700_io.c Normal file
View file

@ -0,0 +1,584 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_io.c: CDC1700 I/O subsystem
*/
#include "cdc1700_defs.h"
extern char INTprefix[];
extern t_bool inProtectedMode(void);
extern uint16 dev1INTR(DEVICE *);
extern uint16 cpuINTR(DEVICE *);
extern uint16 dcINTR(void);
extern void RaiseExternalInterrupt(DEVICE *);
extern enum IOstatus fw_doIO(DEVICE *, t_bool);
extern uint16 Areg, Mreg, Preg, OrigPreg, Qreg, Pending, IOAreg, IOQreg, M[];
extern uint8 Protected, INTflag;
extern t_uint64 Instructions;
extern t_bool FirstRejSeen;
extern uint32 CountRejects;
extern DEVICE cpu_dev, dca_dev, dcb_dev, dcc_dev, tti_dev, tto_dev,
ptr_dev, ptp_dev, cdr_dev;
static const char *status[] = {
"REPLY", "REJECT", "INTERNALREJECT"
};
/*
* The I/O sub-system uses the Q-register to provide controller addressing:
*
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* | W | E | Command |
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*
* If W is non-zero, it addresses a 1706-A buffered data channel. If W
* is zero, it addresses a non-buffered controller.
*
* Note that buffered operations (DMA) can be performed by certain controllers
* (e.g. The Disk Pack Controller) using DSA (Direct Storage Access).
*/
typedef enum IOstatus devIO(DEVICE *, t_bool);
/*
* There can be up to 16 equipment addresses.
*/
devIO *IOcall[16];
DEVICE *IOdev[16];
devINTR *IOintr[16];
/*
* Display device debug status
*/
t_stat show_debug(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
DEVICE *dptr;
t_bool first = TRUE;
DEBTAB *tab;
if (uptr == NULL)
return SCPE_IERR;
dptr = find_dev_from_unit(uptr);
if (dptr == NULL)
return SCPE_IERR;
tab = dptr->debflags;
if (tab == NULL)
return SCPE_IERR;
fprintf(st, "Debug: ");
if (dptr->dctrl != 0) {
uint32 dctrl = dptr->dctrl;
while ((tab->name != NULL) && (dctrl != 0)) {
if ((dctrl & tab->mask) != 0) {
if (!first)
fprintf(st, ",");
fprintf(st, "%s", tab->name);
dctrl &= ~tab->mask;
first = FALSE;
}
tab++;
}
} else fprintf(st, "None");
return SCPE_OK;
}
/*
* Display equipment/station address, buffered data channel and optional
* additional information:
*
* Stop on Reject status
* Protected status
*/
t_stat show_addr(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
DEVICE *dptr;
IO_DEVICE *iod;
if (uptr == NULL)
return SCPE_IERR;
dptr = find_dev_from_unit(uptr);
if (dptr == NULL)
return SCPE_IERR;
iod = (IO_DEVICE *)dptr->ctxt;
fprintf(st, "equip: 0x");
fprint_val(st, (t_value)iod->iod_equip, DEV_RDX, 16, PV_LEFT);
if (iod->iod_station != 0xFF) {
fprintf(st, ", station: ");
fprint_val(st, (t_value)iod->iod_station, DEV_RDX, 8, PV_LEFT);
}
if (iod->iod_dc != 0)
fprintf(st, ", Buffered Data Channel: %c", '0' + iod->iod_dc);
if ((dptr->flags & DEV_REJECT) != 0)
fprintf(st, ", Stop on Reject");
if ((dptr->flags & DEV_PROTECTED) != 0)
fprintf(st, ", Protected");
return SCPE_OK;
}
/*
* Device stop on reject handling.
*/
t_stat set_stoponrej(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
DEVICE *dptr;
if (cptr != NULL)
return SCPE_ARG;
dptr = find_dev_from_unit(uptr);
if (dptr == NULL)
return SCPE_IERR;
dptr->flags |= DEV_REJECT;
return SCPE_OK;
}
t_stat clr_stoponrej(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
DEVICE *dptr;
if (cptr != NULL)
return SCPE_ARG;
dptr = find_dev_from_unit(uptr);
if (dptr == NULL)
return SCPE_IERR;
dptr->flags &= ~DEV_REJECT;
return SCPE_OK;
}
/*
* Protected device.
*/
t_stat set_protected(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
DEVICE *dptr;
if (cptr != NULL)
return SCPE_ARG;
dptr = find_dev_from_unit(uptr);
if (dptr == NULL)
return SCPE_IERR;
dptr->flags |= DEV_PROTECTED;
return SCPE_OK;
}
t_stat clear_protected(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
DEVICE *dptr;
if (cptr != NULL)
return SCPE_ARG;
dptr = find_dev_from_unit(uptr);
if (dptr == NULL)
return SCPE_IERR;
dptr->flags &= ~DEV_PROTECTED;
return SCPE_OK;
}
/*
* Device interrupt handling
*/
/*
* Interrupt status for a non-existent device
*/
uint16 noneINTR(DEVICE *dptr)
{
return 0;
}
/*
* Generic device interrupt status
*/
uint16 deviceINTR(DEVICE *dptr)
{
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
if ((iod->iod_flags & STATUS_ZERO) != 0)
return 0;
return (DEVSTATUS(iod) & IO_ST_INT) != 0 ? iod->iod_interrupt : 0;
}
/*
* Rebuild the pending interrupt status based on the current status of
* each device.
*/
void rebuildPending(void)
{
int i;
/*
* Leave the CPU interrupt pending bit alone.
*/
Pending &= 1;
for (i = 0; i < 16; i++) {
devINTR *rtn = IOintr[i];
Pending |= rtn(IOdev[i]);
}
Pending |= dcINTR();
}
/*
* Handle generic director function(s) for a device. The function request is
* in IOAreg and the bits will be cleared in IOAreg as they are processed.
* Return TRUE if an explicit change was made to the device interrupt mask.
*/
t_bool doDirectorFunc(DEVICE *dptr, t_bool allowStacked)
{
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
/*
* Mask out unsupported commands
*/
IOAreg &= iod->iod_dmask;
if ((IOAreg & (IO_DIR_CINT | IO_DIR_CCONT)) != 0) {
if ((IOAreg & IO_DIR_CCONT) != 0) {
/*
* Preferentially use a device specific "Clear Controller" routine
* over the device reset routine.
*/
if (iod->iod_clear != NULL) {
iod->iod_clear(dptr);
} else {
if (dptr->reset != NULL)
dptr->reset(dptr);
}
}
/*
* Clear all interrupt enables.
*/
iod->iod_ienable = 0;
iod->iod_oldienable = 0;
/*
* Clear all pending interrupts.
*/
DEVSTATUS(iod) &= ~iod->iod_cmask;
rebuildPending();
/*
* The device may allow other commands to be stacked along with Clear
* Interrupts and Clear Controller.
*/
if (!allowStacked) {
IOAreg = 0;
return FALSE;
}
IOAreg &= ~(IO_DIR_CINT | IO_DIR_CCONT);
}
if ((IOAreg & iod->iod_imask) != 0) {
/*
* This request is enabling one or more interrupts.
*/
iod->iod_oldienable = iod->iod_ienable;
iod->iod_ienable |= Areg & iod->iod_imask;
IOAreg &= ~iod->iod_imask;
return TRUE;
}
return FALSE;
}
/*
* Perform an I/O operation. Note that the "Continue" bit is only supported
* on the 1706 buffered data channel devices since it is not relevant in the
* emulation environment.
*/
enum IOstatus doIO(t_bool output, DEVICE **device)
{
enum IOstatus result;
DEVICE *dev;
devIO *rtn;
const char *name;
IO_DEVICE *iod;
/*
* Make a private copy of Areg and Qreg for use by I/O routines
*/
IOAreg = Areg;
IOQreg = Qreg;
/*
* Get the target device and access routine
*/
dev = IOdev[((IOQreg & IO_EQUIPMENT) >> 7) & 0xF];
rtn = IOcall[((IOQreg & IO_EQUIPMENT) >> 7) & 0xF];
if ((((IOQreg & IO_EQUIPMENT) >> 7) & 0xF) == 1) {
/*
* Device address 1 requires special processing. This address
* multiplexes the console teletypewriter, the paper tape reader and
* punch and the card reader using different station addresses:
*
* 001 - 1711/1712/1713 teletypewriter
* 010 - 1721/1722 paper tape reader
* 100 - 1723/1724 paper tape punch
* 110 - 1729 card reader
*/
switch ((IOQreg >> 4) & 0x7) {
case 0x01:
dev = &tti_dev;
break;
case 0x02:
dev = &ptr_dev;
break;
case 0x04:
dev = &ptp_dev;
break;
case 0x06:
dev = &cdr_dev;
break;
default:
return IO_INTERNALREJECT;
}
}
if ((IOQreg & IO_W) != 0) {
/*
* Buffered data channel access.
*/
/*
* Check if this device is only accessible on the AQ channel.
*/
if (dev != NULL) {
iod = (IO_DEVICE *)dev->ctxt;
if ((iod->iod_flags & AQ_ONLY) != 0) {
*device = dev;
return IO_INTERNALREJECT;
}
}
switch (IOQreg & IO_W) {
/*
* 1706-A Channel #1
*/
case IO_1706_1_A:
case IO_1706_1_B:
case IO_1706_1_C:
case IO_1706_1_D:
dev = &dca_dev;
break;
/*
* 1706-A Channel #2
*/
case IO_1706_2_A:
case IO_1706_2_B:
case IO_1706_2_C:
case IO_1706_2_D:
dev = &dcb_dev;
break;
/*
* 1706-A Channel #3
*/
case IO_1706_3_A:
case IO_1706_3_B:
case IO_1706_3_C:
case IO_1706_3_D:
dev = &dcc_dev;
break;
default:
return IO_INTERNALREJECT;
}
rtn = fw_doIO;
}
*device = dev;
if (dev != NULL) {
iod = (IO_DEVICE *)dev->ctxt;
name = iod->iod_name != NULL ? iod->iod_name : dev->name;
if ((dev->dctrl & DBG_DTRACE) != 0) {
if (!FirstRejSeen) {
/* Trace I/O before operation */
if ((Qreg & IO_W) != 0)
fprintf(DBGOUT,
"%s[%s: %s, A: %04X, Q: %04X (%04X/%04X), M: %04X, I: %c]\r\n",
INTprefix, name, output ? "OUT" : "INP", Areg, Qreg,
Qreg & IO_W, Qreg & (IO_EQUIPMENT | IO_COMMAND), Mreg,
INTflag ? '1' : '0');
else fprintf(DBGOUT,
"%s[%s: %s, A: %04X, Q: %04X, M: %04X, I: %c]\r\n",
INTprefix, name, output ? "OUT" : "INP", Areg, Qreg,
Mreg, INTflag ? '1' : '0');
if ((dev->dctrl & DBG_DSTATE) != 0) {
if (iod->iod_state != NULL)
(*iod->iod_state)("before", dev, iod);
}
}
}
if ((dev->dctrl & DBG_DLOC) != 0) {
if (!FirstRejSeen) {
/*
* Trace location of the I/O instruction + instruction count
*/
fprintf(DBGOUT, "%s[%s: P: %04X, Inst: %llu]\r\n",
INTprefix, name, OrigPreg, Instructions);
}
}
/*
* Reject I/O requests from non-protected instructions to protected
* devices unless it is a status register read.
*/
if (inProtectedMode()) {
if (!Protected) {
if ((dev->flags & DEV_PROTECT) != 0) {
if ((dev->flags & DEV_PROTECTED) == 0) {
if (output || ((Qreg & iod->iod_rmask) != 1)) {
if ((cpu_dev.dctrl & DBG_PROTECT) != 0) {
fprintf(DBGOUT,
"%sProtect REJECT\r\n", INTprefix);
}
return IO_REJECT;
}
}
}
}
}
}
result = rtn(dev, output);
if (dev != NULL) {
if ((dev->dctrl & DBG_DTRACE) != 0) {
if (!FirstRejSeen || (result == IO_REPLY)) {
/* Trace I/O after operation */
if ((dev->dctrl & DBG_DSTATE) != 0) {
if (iod->iod_state != NULL)
(*iod->iod_state)("after", dev, iod);
}
if (output)
fprintf(DBGOUT, "%s[%s: => %s]\r\n",
INTprefix, name, status[result]);
else fprintf(DBGOUT, "%s[%s: => %s, A: %04X]\r\n",
INTprefix, name, status[result], Areg);
}
}
}
return result;
}
/*
* Default I/O routine for devices which are not present
*/
static enum IOstatus notPresent(DEVICE *dev, t_bool output)
{
if ((cpu_dev.dctrl & DBG_MISSING) != 0) {
fprintf(DBGOUT,
"%sAccess to missing device (Q: %04X, Equipment: %2u)\r\n",
INTprefix, Qreg, (Qreg & 0x7800) >> 7);
}
return IO_INTERNALREJECT;
}
/*
* Build the I/O call table according to the enabled devices
*/
void buildIOtable(void)
{
DEVICE *dptr;
int i;
/*
* By default, all devices are marked "not present"
*/
for (i = 0; i < 16; i++) {
IOdev[i] = NULL;
IOcall[i] = notPresent;
IOintr[i] = noneINTR;
}
/*
* Scan the device table and add equipment devices.
*/
i = 0;
while ((dptr = sim_devices[i++]) != NULL) {
if ((dptr->flags & (DEV_NOEQUIP | DEV_DIS)) == 0) {
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
IOdev[iod->iod_equip] = dptr;
IOcall[iod->iod_equip] = fw_doIO;
IOintr[iod->iod_equip] =
iod->iod_raised != NULL ? iod->iod_raised : deviceINTR;
}
}
/*
* Set up fixed equipment code devices
*/
IOcall[1] = fw_doIO;
IOintr[1] = dev1INTR;
IOintr[0] = cpuINTR;
}
/*
* Load bootstrap code into memory
*/
void loadBootstrap(uint16 *code, int len, uint16 base, uint16 start)
{
while (len--) {
M[base++] = *code++;
}
Preg = start;
}

477
CDC1700/cdc1700_iofw.c Normal file
View file

@ -0,0 +1,477 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_iofw.c: CDC1700 I/O framework
*/
#include "cdc1700_defs.h"
extern char INTprefix[];
extern void buildIOtable(void);
extern void buildDCtables(void);
extern void RaiseExternalInterrupt(DEVICE *);
extern void rebuildPending(void);
extern uint16 Areg, Qreg, IOAreg, IOQreg;
extern DEVICE *sim_devices[];
extern DEVICE *IOdev[];
extern IO_DEVICE **CMap[];
t_bool IOFWinitialized = FALSE;
/*
* This I/O framework provides an implementation of a generic device. The
* framework provides for up to 8 read and 8 write device registers. The
* read device registers may be stored and read directly from the framework
* or may cause an entry to the device-specific portion of the device
* driver. The framework may be setup to dynamically reject I/O requests
* by setting the appropriate bit in iod_rejmapR/iod_rejmapW. Note that
* access to the status/function register (register 1) cannot be rejected by
* the framework and must be implemented by the device-specific code. This
* allows a device to go "offline" while it it processing requests. Each I/O
* device using the framework uses an IO_DEVICE structure. Each IO_DEVICE
* structure may be used by up to 2 DEVICEs (e.g. TTI and TTO).
*
* The framework provides support for 3 classes of interrupts:
*
* 1. One or more of the standard 3 interrupts (DATA, EOP and ALARM)
*
* The framework handles this class by default. Most devices fall into
* this class.
*
* 2. As 1 above but one or more additional interrupts generated by other
* status bits.
*
* The IO_DEVICE structure must include the iod_intr entry to handle
* the additional interrupt(s). The CD and DP device drivers use this
* mechanism for the "Ready and not busy" interrupt.
*
* 3. Completely non-standard interrupts.
*
* Most of the framework is not used in this case. The IO_DEVICE
* structure must include the iod_raised entry to handle all of it's
* interrupts. The RTC device driver uses this mechanism.
*
*
* The following fields are present in the IO_DEVICE structure:
*
* char *iod_name; - Generic device name override
* char *iod_model; - Device model name
* enum IOdevtype iod_type; - Device type
* when driver supports multiple
* device types
* uint8 iod_equip; - Equipment number/interrupt
* uint8 iod_station; - Station number
* uint16 iod_interrupt; - Interrupt mask bit
* uint16 iod_dcbase; - Base address of DC (or zero)
* DEVICE *iod_indev; - Pointer to input device
* DEVICE *iod_outdev; - Pointer to output device
* UNIT *iod_unit; - Currently selected unit
* t_bool (*iod_reject)(IO_DEVICE *, t_bool, uint8);
* - Check if should reject I/O
* enum IOstatus (*iod_IOread)(IO_DEVICE *, uint8);
* enum IOstatus (*iod_IOwrite)(IO_DEVICE *, uint8);
* - Device read/write routines
* enum IOstatus (*iod_BDCread)(struct io_device *, uint16 *, uint8);
* enum IOstatus (*iod_BDCwrite)(struct io_device *, uint16 *, uint8);
* - Device read/write routines entered
* from 1706 buffered data channel
* void (*iod_state)(char *, DEVICE *, IO_DEVICE *);
* - Dump device state for debug
* t_bool (*iod_intr)(IO_DEVICE *);
* - Check for non-standard interrupts
* uint16 (*iod_raised)(DEVICE *);
* - For completely non-standard
* interrupt handling
* void (*iod_clear)(DEVICE *);
* - Perform clear controller operation
* uint16 iod_ienable; - Device interrupt enables
* uint16 iod_oldienable; - Previous iod_ienable
* uint16 iod_imask; - Valid device interrupts
* uint16 iod_dmask; - Valid director command bits
* uint16 iod_smask; - Valid status bits
* uint16 iod_cmask; - Status bits to clear on
* "clear interrupts"
* uint16 iod_rmask; - Register mask (vs. station addr)
* uint8 iod_regs; - # of device registers
* uint8 iod_validmask; - Bitmap of valid registers
* uint8 iod_readmap; - Bitmap of read registers
* uint8 iod_rejmapR; - Bitmaps of register R/W
* uint8 iod_rejmapW; access to be rejected
* uint8 iod_flags; - Device flags
* #define STATUS_ZERO 0x01 - Status register read returns 0
* #define DEVICE_DC 0x02 - Device is buffered data channel
* #define AQ_ONLY 0x04 - Device only works on the AQ channel
* uint8 iod_dc; - Buffered Data Channel (0 => None)
* uint16 iod_readR[8]; - Device read registers
* uint16 iod_writeR[8]; - Device write registers
* uint16 iod_prevR[8]; - Previous device write registers
* uint16 iod_forced; - Status bits forced to 1
* t_uint64 iod_event; - Available for timestamping
* uint16 iod_private; - Device-specific use
* void *iod_private2; - Device-specific use
* uint16 iod_private3; - Device-specific use
* t_bool iod_private4; - Device-specific use
* void *iod_private5; - Device-specific use
* uint16 iod_private6; - Device-specific use
* uint16 iod_private7; - Device-specific use
* uint16 iod_private8; - Device-specific use
* uint8 iod_private9; - Device-specific use
* t_bool iod_private10; - Device-specific use
*
* The macro CHANGED(iod, n) will return what bits have been changed in write
* register 'n' just after it has been written.
*
* The macro ICHANGED(iod) will return what interrupt enable bits have been
* changed just after a director function has been issued.
*/
/*
* Once-only initialization routine
*/
void fw_init(void)
{
DEVICE *dptr;
int i = 0;
/*
* Scan the device table and fill in the DEVICE back pointer(s)
*/
while ((dptr = sim_devices[i++]) != NULL) {
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
uint8 interrupt = iod->iod_equip;
if ((dptr->flags & DEV_INDEV) != 0)
iod->iod_indev = dptr;
if ((dptr->flags & DEV_OUTDEV) != 0)
iod->iod_outdev = dptr;
/*
* Fill in the interrupt mask bit.
*/
iod->iod_interrupt = 1 << interrupt;
}
/*
* Build the I/O device and buffered data channel tables.
*/
buildIOtable();
buildDCtables();
IOFWinitialized = TRUE;
}
/*
* Perform I/O operation - called directly from the IN/OUT instruction
* processing.
*/
enum IOstatus fw_doIO(DEVICE *dptr, t_bool output)
{
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
uint8 rej = (output ? iod->iod_rejmapW : iod->iod_rejmapR) & ~MASK_REGISTER1;
uint8 reg;
if ((iod->iod_flags & DEVICE_DC) != 0)
reg = ((IOQreg & IO_W) - iod->iod_dcbase) >> 11;
else reg = IOQreg & iod->iod_rmask;
/*
* Check for valid device address
*/
if (reg >= iod->iod_regs)
return IO_REJECT;
/*
* Check if we should reject this request
*/
if ((rej & (1 << reg)) != 0)
return IO_REJECT;
/*
* Check if we should reject this request
*/
if (iod->iod_reject != NULL)
if ((*iod->iod_reject)(iod, output, reg))
return IO_REJECT;
if (output) {
iod->iod_prevR[reg] = iod->iod_writeR[reg];
iod->iod_writeR[reg] = Areg;
return (*iod->iod_IOwrite)(iod, reg);
}
if ((iod->iod_readmap & (1 << reg)) != 0) {
Areg = iod->iod_readR[reg];
return IO_REPLY;
}
return (*iod->iod_IOread)(iod, reg);
}
/*
* Perform I/O operation - called from the buffered data channel controller.
*/
enum IOstatus fw_doBDCIO(IO_DEVICE *iod, uint16 *data, t_bool output, uint8 reg)
{
uint8 rej = (output ? iod->iod_rejmapW : iod->iod_rejmapR) & ~MASK_REGISTER1;
DEVICE *dptr = iod->iod_indev;
enum IOstatus status;
IOAreg = *data;
/*
* Check for valid device address
*/
if (reg >= iod->iod_regs)
return IO_REJECT;
/*
* Check if we should reject this request
*/
if ((rej & (1 << reg)) != 0)
return IO_REJECT;
/*
* Check if we should reject this request
*/
if (iod->iod_reject != NULL)
if ((*iod->iod_reject)(iod, output, reg))
return IO_REJECT;
if ((dptr->dctrl & DBG_DSTATE) != 0)
if (iod->iod_state != NULL)
(*iod->iod_state)("before BDC I/O", dptr, iod);
if (output) {
iod->iod_prevR[reg] = iod->iod_writeR[reg];
iod->iod_writeR[reg] = *data;
status = (*iod->iod_BDCwrite)(iod, data, reg);
} else {
if ((iod->iod_readmap & (1 << reg)) != 0) {
*data = iod->iod_readR[reg];
if ((dptr->dctrl & DBG_DSTATE) != 0)
if (iod->iod_state != NULL)
(*iod->iod_state)("after cached BDC I/O", dptr, iod);
return IO_REPLY;
}
status = (*iod->iod_BDCread)(iod, data, reg);
}
if ((dptr->dctrl & DBG_DSTATE) != 0)
if (iod->iod_state != NULL)
(*iod->iod_state)("after BDC I/O", dptr, iod);
return status;
}
/*
* Devices may support multiple interrupts (DATA, EOP and ALARM are standard)
* but there is only 1 active interrupt flag (IO_ST_INT). This means that we
* must make sure that the active interrupt flag is set whenever one or more
* interrupt source is active and the interrupt(s) have been enabled.
* Interrupts are typically generated when a status flag is raised but we also
* need to handle removing an interrupt souce when a flag is dropped.
*
* In addition, some devices have non-standard interrupts and we need to
* provide a callback to a device-specific routine to check for such
* interrupts.
*/
void fw_IOintr(t_bool other, DEVICE *dev, IO_DEVICE *iod, uint16 set, uint16 clr, uint16 mask, const char *why)
{
/*
* Set/clear the requested status bits.
*/
DEVSTATUS(iod) &= ~(clr | IO_ST_INT);
DEVSTATUS(iod) |= set | iod->iod_forced;
DEVSTATUS(iod) &= (mask & iod->iod_smask);
rebuildPending();
/*
* Check for any interrupts enabled.
*/
if (ISENABLED(iod, iod->iod_imask)) {
t_bool intr = FALSE;
/*
* Check standard interrupts
*/
if ((ISENABLED(iod, IO_DIR_ALARM) &&
(((DEVSTATUS(iod) & IO_ST_ALARM) != 0))) ||
(ISENABLED(iod, IO_DIR_EOP) &&
(((DEVSTATUS(iod) & IO_ST_EOP) != 0))) ||
(ISENABLED(iod, IO_DIR_DATA) &&
(((DEVSTATUS(iod) & IO_ST_DATA) != 0))))
intr = TRUE;
/*
* If the device has non-standard interrupts, call a device-specific
* routine to determine if IO_ST_INT should be set.
*/
if (other)
if (iod->iod_intr != NULL)
if (iod->iod_intr(iod))
intr = TRUE;
if (intr) {
DEVSTATUS(iod) |= IO_ST_INT;
if (why != NULL) {
if ((dev->dctrl & DBG_DINTR) != 0)
fprintf(DBGOUT, "%s%s Interrupt - %s, Ena: %04X, Sta: %04X\r\n",
INTprefix, dev->name, why, ENABLED(iod), DEVSTATUS(iod));
RaiseExternalInterrupt(dev);
} else rebuildPending();
}
}
}
/*
* The following routines are only valid if the framework handles the device
* status register and the function register (register 1) handles interrupt
* enable at end of processing.
*/
/*
* 1. Devices which use IO_ST_DATA to signal end of processing.
*/
void fw_IOunderwayData(IO_DEVICE *iod, uint16 clr)
{
DEVSTATUS(iod) &= ~(clr | IO_ST_READY | IO_ST_DATA);
DEVSTATUS(iod) |= IO_ST_BUSY;
DEVSTATUS(iod) |= iod->iod_forced;
DEVSTATUS(iod) &= iod->iod_smask;
}
void fw_IOcompleteData(t_bool other, DEVICE *dev, IO_DEVICE *iod, uint16 mask, const char *why)
{
fw_IOintr(other, dev, iod, IO_ST_READY | IO_ST_DATA, IO_ST_BUSY, mask, why);
}
/*
* 2. Devices which use IO_ST_EOP to signal end of processing.
*/
void fw_IOunderwayEOP(IO_DEVICE *iod, uint16 clr)
{
DEVSTATUS(iod) &= ~(clr | IO_ST_READY | IO_ST_EOP);
DEVSTATUS(iod) |= IO_ST_BUSY;
DEVSTATUS(iod) |= iod->iod_forced;
DEVSTATUS(iod) &= iod->iod_smask;
}
void fw_IOcompleteEOP(t_bool other, DEVICE *dev, IO_DEVICE *iod, uint16 mask, const char *why)
{
fw_IOintr(other, dev, iod, IO_ST_READY | IO_ST_EOP, IO_ST_BUSY, mask, why);
}
/*
* 3. Devices which use IO_ST_EOP to signal end of processing, but do not
* drop IO_ST_READY while I/O is in progress.
*/
void fw_IOunderwayEOP2(IO_DEVICE *iod, uint16 clr)
{
DEVSTATUS(iod) &= ~(clr | IO_ST_EOP);
DEVSTATUS(iod) |= IO_ST_BUSY;
DEVSTATUS(iod) |= iod->iod_forced;
DEVSTATUS(iod) &= iod->iod_smask;
}
void fw_IOcompleteEOP2(t_bool other, DEVICE *dev, IO_DEVICE *iod, uint16 mask, const char *why)
{
fw_IOintr(other, dev, iod, IO_ST_EOP, IO_ST_BUSY, mask, why);
}
void fw_IOalarm(t_bool other, DEVICE *dev, IO_DEVICE *iod, const char *why)
{
fw_IOintr(other, dev, iod, IO_ST_ALARM, IO_ST_BUSY, 0xFFFF, why);
}
/*
* The following routine manipulates "forced" status bits. This allows
* certain status bits to remain set while the basic I/O framework assumes
* that it will manipulate such bits, for example, IO_ST_BUSY and
* IO_ST_READY for the Paper Tape Reader.
*/
void fw_setForced(IO_DEVICE *iod, uint16 mask)
{
iod->iod_forced |= mask;
DEVSTATUS(iod) |= (mask & iod->iod_smask);
}
void fw_clearForced(IO_DEVICE *iod, uint16 mask)
{
iod->iod_forced &= ~mask;
DEVSTATUS(iod) &= ~mask;
}
/*
* Generic device reject check. If the device is not ready, reject all OUTs
* unless it is to the director function register (register 1).
*/
t_bool fw_reject(IO_DEVICE *iod, t_bool output, uint8 reg)
{
if (output && (reg != 1)) {
return (DEVSTATUS(iod) & IO_ST_READY) == 0;
}
return FALSE;
}
/*
* Generic dump routine for a simple device with a function and status
* register.
*/
void fw_state(char *where, DEVICE *dev, IO_DEVICE *iod)
{
fprintf(DBGOUT, "%s[%s %s state: Function: %04X, Status: %04x]\r\n",
INTprefix, dev->name, where, iod->FUNCTION, DEVSTATUS(iod));
}
/*
* Find a buffered data channel device which supports a specified I/O
* address. Note that since none of the current devices which can make use
* of a buffered data channel include a station address, we can just
* perform a simple range check.
*/
IO_DEVICE *fw_findChanDevice(IO_DEVICE *iod, uint16 addr)
{
DEVICE *dptr = iod->iod_indev;
DEVICE *target = IOdev[(addr & IO_EQUIPMENT) >> 7];
uint32 i;
if (target != NULL) {
for (i = 0; i < dptr->numunits; i++) {
UNIT *uptr = &dptr->units[i];
if (uptr->up8 == target->ctxt)
return (IO_DEVICE *)target->ctxt;
}
}
return NULL;
}

654
CDC1700/cdc1700_lp.c Normal file
View file

@ -0,0 +1,654 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_lp.c: 1740 and 1742-30 line printer support
* Simh devices: lp
*/
#include "cdc1700_defs.h"
#define COLUMNS 136
#define DEVTYPE_1740 IOtype_dev1 /* Device is 1740 */
#define DEVTYPE_1742 IOtype_dev2 /* Device is 1742-30 */
#define FUNCTION2 iod_writeR[3] /* 1740 only */
/*
* Printer mapping table. Maps from the 7-bit device character set to 8-bit
* ASCII. If The mapping is 0xFF, the character is illegal and results in the
* ALARM status bit being raised.
*/
uint8 LPmap[128] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
' ', '!', '"', '#', '$', '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
extern char INTprefix[];
extern void fw_IOalarm(t_bool, DEVICE *, IO_DEVICE *, const char *);
extern t_bool fw_reject(IO_DEVICE *, t_bool, uint8);
extern void fw_IOunderwayData(IO_DEVICE *, uint16);
extern void fw_IOcompleteData(t_bool, DEVICE *, IO_DEVICE *, uint16, const char *);
extern void fw_IOunderwayEOP(IO_DEVICE *, uint16);
extern void fw_IOcompleteEOP(t_bool, DEVICE *, IO_DEVICE *, uint16, const char *);
extern void fw_setForced(IO_DEVICE *, uint16);
extern void fw_clearForced(IO_DEVICE *, uint16);
extern void RaiseExternalInterrupt(DEVICE *);
extern t_bool doDirectorFunc(DEVICE *, t_bool);
extern t_stat checkReset(DEVICE *, uint8);
extern t_stat show_debug(FILE *, UNIT *, int32, CONST void *);
extern t_stat show_addr(FILE *, UNIT *, int32, CONST void *);
extern t_stat set_stoponrej(UNIT *, int32, CONST char *, void *);
extern t_stat clr_stoponrej(UNIT *, int32, CONST char *, void *);
extern t_stat set_protected(UNIT *, int32, CONST char *, void *);
extern t_stat clear_protected(UNIT *, int32, CONST char *, void *);
extern t_stat set_equipment(UNIT *, int32, CONST char *, void *);
extern uint16 Areg, IOAreg;
extern t_bool IOFWinitialized;
t_stat lp_show_type(FILE *, UNIT *, int32, CONST void *);
t_stat lp_set_type(UNIT *, int32, CONST char *, void *);
t_stat lp_svc(UNIT *);
t_stat lp_reset(DEVICE *);
void LPstate(const char *, DEVICE *, IO_DEVICE *);
enum IOstatus LPin(IO_DEVICE *, uint8);
enum IOstatus LPout(IO_DEVICE *, uint8);
uint8 LPbuf[COLUMNS];
/*
1740, 1742-30 Line Printer
Addresses
Computer Instruction
Q Register Output From A Input to A
(Bits 01-00)
00 Write
01 Director Function 1 Director Status
11 Director Function 2
Notes:
1. The documentation is incorrect about the location of Director Status.
Confirmed by the SMM17 LP1 diagnostic code.
2. Device register 3 (Director Function 2) is only present on the 1740
Controller.
Operations:
Director Function 1
15 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X | X | X | X | X | X | X | X | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | |
| | | | | Clr Printer
| | | | Clr Interrupts
| | | Data Interrupt Req.
| | EOP Interrupt Req.
| Interrupt on Alarm
Print (1742-30 only)
Director Function 2 (1740 only)
15 14 13 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | | X | X | X | X | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | |
| | | | | | | | | | Print
| | | | | | | | | Single Space
| | | | | | | | Double Space
| | | | | | | Level 1
| | | | | | Level 2
| | | | | Level 3
| | | | Level 4
| | | Level 5
| | Level 6
| Level 7
Level 12
Status Response:
Director Status
15 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X | X | X | X | X | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | |
| | | | | | | | Ready
| | | | | | | Busy
| | | | | | Interrupt
| | | | | Data
| | | | End of Operation
| | | Alarm
| | Error (1742-30 only)
| Protected
Load Image (1742 only)
*/
IO_DEVICE LPdev = IODEV(NULL, "Line Printer", 1740, 4, 0xFF, 0,
fw_reject, LPin, LPout, NULL, NULL,
NULL, NULL, NULL, NULL,
0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | MASK_REGISTER3,
MASK_REGISTER1,
MASK_REGISTER0 | MASK_REGISTER2, MASK_REGISTER2,
0, 0, LPbuf);
/*
* Define usage for "private" IO_DEVICE data areas.
*/
#define iod_LPstate iod_private
#define iod_LPbuffer iod_private2
#define iod_LPcolumn iod_private3
#define iod_LPccpend iod_private4 /* 1742-30 only */
#define iod_LPoverwrite iod_private10 /* 1740 only */
/*
* Current state of the device.
*/
#define IODP_LPNONE 0x0000
#define IODP_LPCHARWAIT 0x0001
#define IODP_LPPRINTWAIT 0x0002
#define IODP_LPCCWAIT 0x0003
/* LP data structures
lp_dev LP device descriptor
lp_unit LP unit descriptor
lp_reg LP register list
lp_mod LP modifiers list
*/
UNIT lp_unit = {
UDATA(&lp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), LP_OUT_WAIT
};
REG lp_reg_1740[] = {
{ HRDATA(FUNCTION, LPdev.FUNCTION, 16) },
{ HRDATA(FUNCTION2, LPdev.FUNCTION2, 16) },
{ HRDATA(STATUS, LPdev.STATUS, 16) },
{ HRDATA(IENABLE, LPdev.IENABLE, 16) },
{ NULL }
};
REG lp_reg_1742[] = {
{ HRDATA(FUNCTION, LPdev.FUNCTION, 16) },
{ HRDATA(STATUS, LPdev.STATUS, 16) },
{ HRDATA(IENABLE, LPdev.IENABLE, 16) },
{ NULL }
};
MTAB lp_mod[] = {
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, NULL, "TYPE", &lp_set_type, NULL, NULL,
"TYPE={1740|1742}" },
{ MTAB_XTD|MTAB_VDV, 0, "TYPE", NULL, NULL, &lp_show_type, NULL, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, NULL, "EQUIPMENT", &set_equipment, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "EQUIPMENT", NULL, NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DEBUG", NULL, NULL, &show_debug, NULL },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "STOPONREJECT", &set_stoponrej, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOSTOPONREJECT", &clr_stoponrej, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "PROTECT", &set_protected, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOPROTECT", &clear_protected, NULL, NULL },
{ 0 }
};
/*
* LP debug flags
*/
#define DBG_V_CC (DBG_SPECIFIC+0)/* Carriage control characters */
#define DBG_CC (1 << DBG_V_CC)
DEBTAB lp_deb[] = {
{ "TRACE", DBG_DTRACE },
{ "STATE", DBG_DSTATE },
{ "INTR", DBG_DINTR },
{ "LOCATION", DBG_DLOC },
{ "FIRSTREJ", DBG_DFIRSTREJ },
{ "ALL", DBG_DTRACE | DBG_DSTATE | DBG_DINTR | DBG_DLOC },
{ "CC", DBG_CC },
{ NULL }
};
DEVICE lp_dev = {
"LP", &lp_unit, NULL, lp_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &lp_reset,
NULL, NULL, NULL,
&LPdev,
DEV_DEBUG | DEV_DISABLE | DEV_OUTDEV | DEV_PROTECT, 0, lp_deb,
NULL,
NULL
};
t_stat lp_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
switch (LPdev.iod_type) {
case DEVTYPE_1740:
fprintf(st, "1740");
break;
case DEVTYPE_1742:
fprintf(st, "1742-30");
break;
default:
return SCPE_IERR;
}
return SCPE_OK;
}
t_stat lp_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (!cptr)
return SCPE_IERR;
if ((uptr->flags & UNIT_ATT) != 0)
return SCPE_ALATT;
if (!strcmp(cptr, "1740")) {
LPdev.iod_type = DEVTYPE_1740;
LPdev.iod_model = "1740";
lp_dev.registers = lp_reg_1740;
} else {
if (!strcmp(cptr, "1742") ||
!strcmp(cptr, "1742-30")) {
LPdev.iod_type = DEVTYPE_1742;
LPdev.iod_model = "1742-30";
lp_dev.registers = lp_reg_1742;
} else return SCPE_ARG;
}
return SCPE_OK;
}
/*
* Dump the current internal state of the LP device.
*/
const char *LPprivateState[4] = {
"", "CHARWAIT", "PRINTWAIT", "CCWAIT"
};
void LPstate(const char *where, DEVICE *dev, IO_DEVICE *iod)
{
fprintf(DBGOUT,
"%s[%s %s: Func: %04X, Func2: %04X, Sta: %04X, Ena: %04x, Count: %d, \
Private: %s%s\r\n",
INTprefix, dev->name, where,
iod->FUNCTION, iod->FUNCTION2, iod->STATUS, iod->IENABLE,
iod->iod_LPcolumn,
LPprivateState[iod->iod_LPstate],
iod->iod_LPoverwrite ? ",Overwrite" : "");
}
/* Unit service */
t_stat lp_svc(UNIT *uptr)
{
if ((lp_dev.dctrl & DBG_DTRACE) != 0) {
fprintf(DBGOUT, "%s[LP: lp_svc() entry]\r\n", INTprefix);
if ((lp_dev.dctrl & DBG_DSTATE) != 0)
LPstate("svc_entry", &lp_dev, &LPdev);
}
switch (LPdev.iod_LPstate) {
case IODP_LPCHARWAIT:
/*
* Generate an interrupt indicating that the device can accept more
* characters.
*/
LPdev.iod_LPstate = IODP_LPNONE;
fw_IOcompleteData(FALSE, &lp_dev, &LPdev, 0xFFFF, "Output done");
break;
case IODP_LPPRINTWAIT:
/*
* Generate an interrupt indicating that the print/motion operation
* has completed.
*/
LPdev.iod_LPstate = IODP_LPNONE;
if (LPdev.iod_type == DEVTYPE_1742)
LPdev.iod_LPccpend = TRUE;
fw_IOcompleteEOP(FALSE, &lp_dev, &LPdev, 0xFFFF, "EOP interrupt");
break;
case IODP_LPCCWAIT:
/*
* Generate an interrupt indicating that the motion operation has
* completed.
*/
LPdev.iod_LPstate = IODP_LPNONE;
LPdev.iod_LPccpend = FALSE;
fw_IOcompleteData(FALSE, &lp_dev, &LPdev, 0xFFFF, "Control Char. Done");
break;
default:
return SCPE_IERR;
}
if ((lp_dev.dctrl & DBG_DTRACE) != 0) {
fprintf(DBGOUT, "%s[LP: lp_svc() exit]\r\n", INTprefix);
if ((lp_dev.dctrl & DBG_DSTATE) != 0)
LPstate("svc exit", &lp_dev, &LPdev);
}
return SCPE_OK;
}
/* Reset routine */
t_stat lp_reset(DEVICE *dptr)
{
t_stat r;
if (LPdev.iod_type == IOtype_default) {
/*
* Setup the default device type.
*/
LPdev.iod_type = DEVTYPE_1740;
LPdev.iod_model = "1740";
lp_dev.registers = lp_reg_1740;
}
if (IOFWinitialized)
if ((dptr->flags & DEV_DIS) == 0)
if ((r = checkReset(dptr, LPdev.iod_equip)) != SCPE_OK)
return r;
DEVRESET(&LPdev);
LPdev.iod_LPcolumn = 0;
if (LPdev.iod_type == DEVTYPE_1742)
LPdev.iod_LPccpend = TRUE;
fw_setForced(&LPdev, IO_ST_READY);
LPdev.STATUS |= IO_ST_DATA | IO_ST_EOP;
return SCPE_OK;
}
/* Perform I/O */
enum IOstatus LPin(IO_DEVICE *iod, uint8 reg)
{
/*
* The framework only passes IN operations for the data register.
*/
return IO_REJECT;
}
enum IOstatus LPout(IO_DEVICE *iod, uint8 reg)
{
uint8 *buffer = (uint8 *)iod->iod_LPbuffer;
t_bool printwait = FALSE, changed;
/*
* 1742-30 does not have a register 3
*/
if (reg == 0x03)
if (LPdev.iod_type == DEVTYPE_1742)
return IO_REJECT;
if ((lp_dev.dctrl & DBG_DSTATE) != 0)
LPstate("before", &lp_dev, &LPdev);
switch (reg) {
case 0x00:
if (iod->iod_LPcolumn < COLUMNS) {
if (iod->iod_type == DEVTYPE_1740) {
uint8 ch1, ch2;
ch1 = (Areg >> 8) & 0x7F;
ch2 = Areg & 0x7F;
if ((LPmap[ch1] == 0xFF) || (LPmap[ch2] == 0xFF)) {
if ((lp_dev.dctrl & DBG_DTRACE) != 0)
fprintf(DBGOUT,
"%sLP: Invalid code (0x%02x, 0x%02x) ==> [0x%02x, 0x%02x]\r\\n",
INTprefix, ch1, ch2, LPmap[ch1], LPmap[ch2]);
fw_IOalarm(FALSE, &lp_dev, iod, "Invalid code");
break;
}
/*
* Put both characters in the print buffer.
*/
buffer[iod->iod_LPcolumn++] = LPmap[ch1];
buffer[iod->iod_LPcolumn++] = LPmap[ch2];
}
if (iod->iod_type == DEVTYPE_1742) {
uint8 ch = LPmap[Areg & 0x7F];
/*
* If this is the first character after a "Print" command, it
* controls the vertical motion of the paper.
* TODO: Implement format tape operations.
* For now, all format tape operations generate a single
* space motion
*/
if (LPdev.iod_LPccpend) {
const char *ccontrol = "\n";
if ((lp_dev.dctrl & DBG_CC) != 0)
fprintf(DBGOUT, "%s[LP: CC: 0x%02X]\r\n", INTprefix, Areg);
if ((Areg & 0x40) == 0) {
switch (Areg & 0x03) {
case 0x0:
ccontrol = "\r";
break;
case 0x1:
ccontrol = "\n";
break;
case 0x2:
ccontrol = "\n\n";
break;
case 0x3:
ccontrol = "\n\n\n";
break;
}
} else {
/*** TODO: implement format tape decoding ***/
}
if ((lp_unit.flags & UNIT_ATT) != 0) {
if (fputs(ccontrol, lp_unit.fileref) == EOF) {
perror("LP I/O error");
clearerr(lp_unit.fileref);
}
}
fw_IOunderwayData(&LPdev, 0);
LPdev.iod_LPstate = IODP_LPCCWAIT;
sim_activate(&lp_unit, LP_CC_WAIT);
break;
}
/*
* Put non-control characters in the print buffer.
*/
if (ch != 0xFF)
buffer[iod->iod_LPcolumn++] = ch;
}
fw_IOunderwayData(&LPdev, 0);
LPdev.iod_LPstate = IODP_LPCHARWAIT;
sim_activate(&lp_unit, lp_unit.wait);
}
break;
case 0x01:
changed = doDirectorFunc(&lp_dev, TRUE);
if ((Areg & (IO_DIR_CINT | IO_DIR_CCONT)) != 0)
LPdev.STATUS |= IO_ST_DATA | IO_ST_EOP;
if (changed) {
/*
* The device interrupt mask has been explicitly changed. If the
* interrupt on data was just set and the device can accept more
* data, generate an interrupt.
*/
if ((ICHANGED(&LPdev) & IO_DIR_DATA) != 0) {
if ((LPdev.STATUS & IO_ST_DATA) != 0) {
if ((lp_dev.dctrl & DBG_DINTR) != 0)
fprintf(DBGOUT,
"%sLP: DATA Interrupt from mask change\r\n", INTprefix);
RaiseExternalInterrupt(&lp_dev);
}
}
}
if (iod->iod_type == DEVTYPE_1742) {
if ((Areg & IO_1742_PRINT) != 0) {
LPdev.STATUS &= ~IO_ST_ALARM;
if (iod->iod_LPcolumn != 0) {
if ((lp_unit.flags & UNIT_ATT) != 0) {
int i;
for (i = 0; i < iod->iod_LPcolumn; i++) {
if (putc(buffer[i], lp_unit.fileref) == EOF) {
perror("LP I/O error");
clearerr(lp_unit.fileref);
}
}
}
}
fw_IOunderwayEOP(&LPdev, IO_ST_INT);
LPdev.iod_LPstate = IODP_LPPRINTWAIT;
sim_activate(&lp_unit, LP_PRINT_WAIT);
}
}
break;
case 0x3:
if ((Areg & (IO_1740_MOTION | IO_1740_PRINT)) != 0) {
/*
* Here we need to print something, buffered data or vertical motion.
* Note that we will try to do the "right" thing with respect to
* stacked operations even though the physical hardware may not be
* able to do so.
*/
if ((Areg & IO_1740_PRINT) != 0) {
LPdev.STATUS &= ~IO_ST_ALARM;
if (iod->iod_LPcolumn != 0) {
if ((lp_unit.flags & UNIT_ATT) != 0) {
int i;
if (iod->iod_LPoverwrite) {
if (putc('\r', lp_unit.fileref) == EOF) {
perror("LP I/O error");
clearerr(lp_unit.fileref);
}
}
for (i = 0; i < iod->iod_LPcolumn; i++) {
if (putc(buffer[i], lp_unit.fileref) == EOF) {
perror("LP I/O error");
clearerr(lp_unit.fileref);
}
}
iod->iod_LPoverwrite = TRUE;
}
}
printwait = TRUE;
}
if ((Areg & IO_1740_MOTION) != 0) {
/*** TODO: Implement format tape operations.
For now, all operations generate a single space motion ***/
if ((lp_unit.flags & UNIT_ATT) != 0) {
if (putc('\n', lp_unit.fileref) == EOF) {
perror("LP I/O error");
clearerr(lp_unit.fileref);
}
if ((Areg & IO_1740_DSP) != 0) {
if (putc('\n', lp_unit.fileref) == EOF) {
perror("LP I/O error");
clearerr(lp_unit.fileref);
}
}
}
iod->iod_LPoverwrite = FALSE;
printwait = TRUE;
}
if (printwait) {
fw_IOunderwayEOP(&LPdev, IO_ST_INT);
LPdev.iod_LPstate = IODP_LPPRINTWAIT;
sim_activate(&lp_unit, LP_PRINT_WAIT);
}
}
break;
default:
if ((lp_dev.dctrl & DBG_DSTATE) != 0)
fprintf(DBGOUT, "%sLP: REJECT response\r\n", INTprefix);
return IO_REJECT;
}
if ((lp_dev.dctrl & DBG_DSTATE) != 0)
LPstate("after", &lp_dev, &LPdev);
return IO_REPLY;
}

1973
CDC1700/cdc1700_mt.c Normal file

File diff suppressed because it is too large Load diff

341
CDC1700/cdc1700_rtc.c Normal file
View file

@ -0,0 +1,341 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_rtc.c: 10336-1 Real-time clock support
* Simh devices: rtc
*/
#include "cdc1700_defs.h"
#define HOLDREG iod_writeR[0] /* Holding register */
#define COUNTER iod_readR[1] /* Counter */
extern char INTprefix[];
extern t_stat checkReset(DEVICE *, uint8);
extern t_stat show_debug(FILE *, UNIT *, int32, CONST void *);
extern t_stat show_addr(FILE *, UNIT *, int32, CONST void *);
extern t_stat set_equipment(UNIT *, int32, CONST char *, void *);
extern void RaiseExternalInterrupt(DEVICE *);
extern void rebuildPending(void);
extern uint16 Areg;
extern t_bool IOFWinitialized;
t_stat rtc_show_rate(FILE *, UNIT *, int32, CONST void *);
t_stat rtc_set_rate(UNIT *, int32, CONST char *, void *);
void RTCstate(char *, DEVICE *, IO_DEVICE *);
uint16 RTCraised(DEVICE *);
enum IOstatus RTCin(IO_DEVICE *, uint8);
enum IOstatus RTCout(IO_DEVICE *, uint8);
t_stat rtc_svc(UNIT *);
t_stat rtc_reset(DEVICE *);
/*
10336-1 Real-Time Clock
Addresses
Computer Instruction
Q Register Output From A Input to A
(Bits 01-00)
00 Load Register
01 Director Function Read Counter
Operations:
Director Function 1
15 14 7 6 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | X | X | X | X | X | X | | | X | X | X | X | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | |
| | | | | Clr Controller
| | | | Ack. Interrupt
| | | Stop Clock
| | Start Clock
| Disable Interrupt
Enable Interrupt
The counter and register values are unsigned 16-bit values.
*/
IO_DEVICE RTCdev = IODEV(NULL, "10336-1", 10336, 13, 0xFF, 0,
NULL, RTCin, RTCout, NULL, NULL,
NULL, NULL, RTCraised, NULL,
0x7F, 2,
MASK_REGISTER0 | MASK_REGISTER1,
MASK_REGISTER1,
MASK_REGISTER0, 0,
AQ_ONLY, 0, NULL);
/*
* Define usage for "private" IO_DEVICE data areas.
*/
#define iod_RTCstate iod_private
#define iod_RTCraised iod_private4
/*
* Current state of the device.
*/
#define IODP_RTCIDLE 0x0000
#define IODP_RTCRUNNING 0x0001
#define IODP_RTCINTR 0x0002
/*
* The RTC operates at a user determined frequency (via a jumper plug).
* Basic time periods are:
*
* 1 uSec, 10 uSec, 100 uSec, 1 mSec, 10 mSec, 100 mSec and 1 second.
*
* We use CPU instruction execution as a proxy for generating these
* frequencies. If we assume an average execution time of 1.25 uSec (1784-2
* processor), each time period will be represented by the following
* instruction counts:
*
* 1, 8, 80, 800, 8000, 80000, 800000
*/
#define RTC_1USEC 1
#define RTC_10USEC 8
#define RTC_100USEC 80
#define RTC_1MSEC 800
#define RTC_10MSEC 8000
#define RTC_100MSEC 80000
#define RTC_1SEC 800000
struct RTCtimebase {
const char *name;
const char *rate;
int32 icount;
} timeBase[] = {
{ "1USEC", "1 uSec", RTC_1USEC },
{ "10USEC", "10 uSec", RTC_10USEC },
{ "100USEC", "100 uSec", RTC_100USEC },
{ "1MSEC", "1 mSec", RTC_1MSEC },
{ "10MSEC", "10 mSec", RTC_10MSEC },
{ "100MSEC", "100 mSec", RTC_100MSEC },
{ "1SEC", "1 Seccond", RTC_1SEC },
{ NULL }
};
/* RTC data structures
rtc_dev RTC device descriptor
rtc_unit RTC unit descriptor
rtc_reg RTC register list
rtc_mod RTC modifiers list
*/
UNIT rtc_unit = {
UDATA(&rtc_svc, 0, 0), RTC_10MSEC
};
REG rtc_reg[] = {
{ HRDATA(FUNCTION, RTCdev.FUNCTION, 16) },
{ HRDATA(COUNTER, RTCdev.COUNTER, 16) },
{ HRDATA(HOLDING, RTCdev.HOLDREG, 16) },
{ NULL }
};
MTAB rtc_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "10336-1", NULL, NULL, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, NULL, "RATE", &rtc_set_rate, NULL, NULL,
"val={1usec|10usec|100usec|1msec|10msec|100msec|1second}" },
{ MTAB_XTD|MTAB_VDV, 0, "RATE", NULL, NULL, &rtc_show_rate, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "EQUIPMENT", NULL, NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, NULL, "EQUIPMENT", &set_equipment, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DEBUG", NULL, NULL, &show_debug, NULL },
{ 0 }
};
DEBTAB rtc_deb[] = {
{ "TRACE", DBG_DTRACE },
{ NULL }
};
DEVICE rtc_dev = {
"RTC", &rtc_unit, rtc_reg, rtc_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &rtc_reset,
NULL, NULL, NULL,
&RTCdev,
DEV_DEBUG | DEV_DISABLE, 0, rtc_deb,
NULL,
NULL
};
t_stat rtc_show_rate(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
struct RTCtimebase *tb = timeBase;
while (tb->name != NULL) {
if (tb->icount == rtc_unit.wait) {
fprintf(st, "Timebase rate: %s", tb->rate);
return SCPE_OK;
}
tb++;
}
return SCPE_IERR;
}
t_stat rtc_set_rate(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (cptr) {
struct RTCtimebase *tb = timeBase;
while (tb->name != NULL) {
if (!strcmp(cptr, tb->name)) {
rtc_unit.wait = tb->icount;
return SCPE_OK;
}
tb++;
}
}
return SCPE_IERR;
}
/*
* Determine if the clock interrupt is asserted, returning the appropriate
* interrupt bit or 0.
*/
uint16 RTCraised(DEVICE *dptr)
{
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
return iod->iod_RTCraised ? iod->iod_interrupt : 0;
}
/* Unit service */
t_stat rtc_svc(UNIT *uptr)
{
if (RTCdev.iod_RTCstate != IODP_RTCIDLE) {
if ((RTCdev.iod_RTCstate & IODP_RTCRUNNING) != 0) {
RTCdev.COUNTER++;
if ((RTCdev.iod_RTCstate & IODP_RTCINTR) != 0) {
if (RTCdev.COUNTER == RTCdev.HOLDREG) {
RTCdev.COUNTER = 0;
RTCdev.iod_RTCraised = TRUE;
RaiseExternalInterrupt(&rtc_dev);
}
}
sim_activate(&rtc_unit, rtc_unit.wait);
}
}
return SCPE_OK;
}
/* Reset routine */
t_stat rtc_reset(DEVICE * dptr)
{
t_stat r;
if (IOFWinitialized)
if ((dptr->flags & DEV_DIS) == 0)
if ((r = checkReset(dptr, RTCdev.iod_equip)) != SCPE_OK)
return r;
RTCdev.iod_RTCstate = IODP_RTCIDLE;
RTCdev.iod_RTCraised = FALSE;
return SCPE_OK;
}
/* Perform I/O */
enum IOstatus RTCin(IO_DEVICE *iod, uint8 reg)
{
/*
* The framework only passes IN operations for the data register.
*/
return IO_REJECT;
}
enum IOstatus RTCout(IO_DEVICE *iod, uint8 reg)
{
switch (reg) {
case 0x00:
RTCdev.HOLDREG = Areg;
break;
case 0x01:
/*
* Check for illegal bit combinations
*/
if (((Areg & (IO_10336_ENA | IO_10336_DIS)) ==
(IO_10336_ENA | IO_10336_DIS)) ||
((Areg & (IO_10336_START | IO_10336_STOP)) ==
(IO_10336_START | IO_10336_STOP)))
return IO_REJECT;
if ((Areg & IO_DIR_CCONT) != 0) {
sim_cancel(&rtc_unit);
RTCdev.iod_RTCstate = IODP_RTCIDLE;
RTCdev.iod_RTCraised = FALSE;
rebuildPending();
RTCdev.HOLDREG = 0;
RTCdev.COUNTER = 0;
}
if ((Areg & IO_10336_STOP) != 0) {
RTCdev.iod_RTCstate &= ~IODP_RTCRUNNING;
sim_cancel(&rtc_unit);
}
if ((Areg & IO_10336_START) != 0) {
RTCdev.COUNTER = 0;
RTCdev.iod_RTCstate |= IODP_RTCRUNNING;
sim_activate(&rtc_unit, rtc_unit.wait);
}
if ((Areg & IO_10336_ACK) != 0) {
RTCdev.iod_RTCraised = FALSE;
rebuildPending();
}
if ((Areg & IO_10336_DIS) != 0) {
RTCdev.iod_RTCstate &= ~IODP_RTCINTR;
RTCdev.iod_RTCraised = FALSE;
rebuildPending();
}
if ((Areg & IO_10336_ENA) != 0)
RTCdev.iod_RTCstate |= IODP_RTCINTR;
break;
}
return IO_REPLY;
}

339
CDC1700/cdc1700_sym.c Normal file
View file

@ -0,0 +1,339 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_sym.c: symbolic assembler input for "deposit" command
*/
#include "cdc1700_defs.h"
#include <ctype.h>
extern UNIT cpu_unit;
extern uint16 doADDinternal(uint16, uint16);
/*
* Symbol tables
*/
#define I_DATA 0x10000 /* Data transmission */
#define I_ARITH 0x20000 /* Arithmetic */
#define I_LOG 0x30000 /* Logical */
#define I_JUMP 0x40000 /* Jumps */
#define I_REG 0x50000 /* Register reference */
#define I_SKIP 0x60000 /* Skip */
#define I_INTER 0x70000 /* Inter-register */
#define I_SHIFT 0x80000 /* Shift */
#define I_MASK 0xF0000
#define I_DMASK 0xFFFF
/*
* Modifiers for I_REG addressing.
*/
#define I_NONE 0x000000 /* No argument expected */
#define I_REL 0x100000 /* 8-bit relative address */
#define I_ABS 0x200000 /* 8-bit absolute value */
#define I_SIGNED 0x300000 /* 8-bit signed value */
#define I_MASK2 0x300000
#define I_NOARG I_REG + I_NONE
static const char *opcode[] = {
"ADQ", "LDQ", "RAO", "LDA",
"EOR", "AND", "SUB", "ADD",
"SPA", "STA", "RTJ", "STQ",
"DVI", "MUI", "JMP", "SLS",
"SAZ", "SAN", "SAP", "SAM",
"SQZ", "SQN", "SQP", "SQM",
"SWS", "SWN", "SOV", "SNO",
"SPE", "SNP", "SPF", "SNF",
"INP", "OUT", "EIN", "IIN",
"ECA", "DCA", "SPB", "CPB",
"AAM", "AAQ", "AAB", "CLR",
"TCM", "TCQ", "TCB", "TCA",
"EAM", "EAQ", "EAB", "SET",
"TRM", "TRQ", "TRB", "TRA",
"LAM", "LAQ", "LAB", "CAM",
"CAQ", "CAB", "INA", "ENA",
"NOP", "ENQ", "INQ", "EXI",
"QRS", "ARS", "LRS", "QLS",
"ALS", "LLS",
NULL
};
static const int32 opc_val[] = {
OPC_ADQ + I_ARITH, OPC_LDQ + I_DATA, OPC_RAO + I_ARITH, OPC_LDA + I_DATA,
OPC_EOR + I_LOG, OPC_AND + I_LOG, OPC_SUB + I_ARITH, OPC_ADD + I_ARITH,
OPC_SPA + I_DATA, OPC_STA + I_DATA, OPC_RTJ + I_JUMP, OPC_STQ + I_DATA,
OPC_DVI + I_ARITH, OPC_MUI + I_ARITH, OPC_JMP + I_JUMP, OPC_SLS + I_NOARG,
OPC_SAZ + I_SKIP, OPC_SAN + I_SKIP, OPC_SAP + I_SKIP, OPC_SAM + I_SKIP,
OPC_SQZ + I_SKIP, OPC_SQN + I_SKIP, OPC_SQP + I_SKIP, OPC_SQM + I_SKIP,
OPC_SWS + I_SKIP, OPC_SWN + I_SKIP, OPC_SOV + I_SKIP, OPC_SNO + I_SKIP,
OPC_SPE + I_SKIP, OPC_SNP + I_SKIP, OPC_SPF + I_SKIP, OPC_SNF + I_SKIP,
OPC_INP + I_REG + I_REL, OPC_OUT + I_REG + I_REL, OPC_EIN + I_NOARG, OPC_IIN + I_NOARG,
OPC_ECA + I_NOARG, OPC_DCA + I_NOARG, OPC_SPB + I_NOARG, OPC_CPB + I_NOARG,
OPC_AAM + I_INTER, OPC_AAQ + I_INTER, OPC_AAB + I_INTER, OPC_CLR + I_INTER,
OPC_TCM + I_INTER, OPC_TCQ + I_INTER, OPC_TCB + I_INTER, OPC_TCA + I_INTER,
OPC_EAM + I_INTER, OPC_EAQ + I_INTER, OPC_EAB + I_INTER, OPC_SET + I_INTER,
OPC_TRM + I_INTER, OPC_TRQ + I_INTER, OPC_TRB + I_INTER, OPC_TRA + I_INTER,
OPC_LAM + I_INTER, OPC_LAQ + I_INTER, OPC_LAB + I_INTER, OPC_CAM + I_INTER,
OPC_CAQ + I_INTER, OPC_CAB + I_INTER, OPC_INA + I_REG + I_SIGNED, OPC_ENA + I_REG + I_SIGNED,
OPC_NOP + I_NOARG, OPC_ENQ + I_REG + I_SIGNED, OPC_INQ + I_REG + I_SIGNED, OPC_EXI + I_REG + I_ABS,
OPC_QRS + I_SHIFT, OPC_ARS + I_SHIFT, OPC_LRS + I_SHIFT, OPC_QLS + I_SHIFT,
OPC_ALS + I_SHIFT, OPC_LLS + I_SHIFT,
};
/*
* Register (and pseudo-register) names.
*/
static const char *regname[] = {
"A", "Q", "M", "I", "B",
NULL
};
/*
* Usage value for each usage type (0 means invalid).
*/
static uint16 instIndex[] = {
0x0000, MOD_I1, 0x0000, MOD_I2, MOD_I1 | MOD_I2
};
static uint16 instInter[] = {
MOD_D_A, MOD_D_Q, MOD_D_M, 0x0000, 0x0000
};
#define NEXTSYMBOL(mchar) \
cptr = get_glyph(cptr, gbuf, mchar); \
for (j = 0; (regname[j] != NULL) && (strcmp(regname[j], gbuf) != 0); j++); \
if (regname[j] == NULL) return SCPE_ARG
t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
{
int32 cflag, i, j, l, rdx;
t_bool neg, cons;
t_value temp;
t_stat r, sta = SCPE_OK;
char gbuf[CBUFSIZE], mode;
const char *cptr2;
cflag = (uptr == NULL) || (uptr == &cpu_unit);
while (isspace(*cptr))
cptr++;
if ((sw & SWMASK('A')) || ((*cptr == '\'') && cptr++)) {
/* ASCII character */
if (cptr[0] == 0)
return SCPE_ARG;
val[0] = (t_value)cptr[0] | 0200;
return SCPE_OK;
}
if ((sw & SWMASK('C')) || ((*cptr == '"') && cptr++)) {
/* Packed ASCII characters (2 to a word) */
if (cptr[0] == 0)
val[0] = (((t_value)cptr[0] | 0200) << 8) | ((t_value)cptr[1] | 0200);
return SCPE_OK;
}
cptr = get_glyph(cptr, gbuf, 0);
l = strlen(gbuf);
if ((gbuf[l - 1] == '*') || (gbuf[l - 1] == '-') || (gbuf[l - 1] == '+')) {
mode = gbuf[l - 1];
gbuf[l - 1] = '\0';
} else mode = 0;
for (i = 0; (opcode[i] != NULL) && (strcmp(opcode[i], gbuf) != 0); i++);
if (opcode[i] == NULL)
return SCPE_ARG;
val[0] = opc_val[i] & I_DMASK;
while (isspace(*cptr))
cptr++;
cons = neg = FALSE;
rdx = 10;
switch (opc_val[i] & I_MASK) {
case I_DATA:
case I_ARITH:
case I_LOG:
if (*cptr == '=') {
cons = TRUE;
cptr++;
if (*cptr == '-') {
neg = TRUE;
cptr++;
}
if (*cptr == '$') {
rdx = 16;
cptr++;
}
temp = get_uint(cptr, rdx, MAXNEG, &r);
if (r != SCPE_OK)
return r;
if (neg) {
if (temp > MAXPOS)
return SCPE_ARG;
temp = (~temp) & 0xFFFF;
}
if ((mode == '*') || (mode == '-'))
return SCPE_ARG;
/*
* Constant addressing mode always occupies 2 words.
*/
val[1] = temp;
return -1;
}
/* FALLTHROUGH */
case I_JUMP:
if (*cptr == '(') {
cptr++;
if (*cptr == '$') {
rdx = 16;
cptr++;
}
temp = strtotv(cptr, &cptr2, rdx);
if ((cptr == cptr2) || (*cptr2++ != ')'))
return SCPE_ARG;
cptr = (char *)cptr2;
val[0] |= MOD_IN;
} else {
if (*cptr == '$') {
rdx = 16;
cptr++;
}
temp = strtotv(cptr, &cptr2, rdx);
if (cptr == cptr2)
return SCPE_ARG;
cptr = (char *)cptr2;
}
if (mode == '*') {
temp = doADDinternal(temp, ~addr);
if (CANEXTEND8(temp))
temp &= 0xFF;
val[0] |= MOD_RE;
}
if ((mode == '-') && ((temp & 0xFF00) != 0))
return SCPE_ARG;
/*
* Check for indexing modifier
*/
if (*cptr++ == ',') {
NEXTSYMBOL(0);
if (instIndex[j] == 0)
return SCPE_ARG;
val[0] |= instIndex[j];
}
if (((temp & 0xFF00) != 0) || (mode == '+')) {
val[1] = temp;
return -1;
}
val[0] |= temp;
return SCPE_OK;
case I_REG:
switch (opc_val[i] & I_MASK2) {
case I_NONE:
return SCPE_OK;
case I_REL:
case I_SIGNED:
if (*cptr == '-') {
neg = TRUE;
cptr++;
}
if (*cptr == '$') {
rdx = 16;
cptr++;
}
temp = get_uint(cptr, rdx, 127, &r);
if (r != SCPE_OK)
return r;
if (neg)
temp = (~temp) & 0xFF;
val[0] |= temp;
return SCPE_OK;
case I_ABS:
if (*cptr == '$') {
rdx = 16;
cptr++;
}
temp = get_uint(cptr, rdx, 255, &r);
if (r != SCPE_OK)
return r;
val[0] |= temp;
return SCPE_OK;
}
break;
case I_SKIP:
if (*cptr == '$') {
rdx = 16;
cptr++;
}
temp = get_uint(cptr, rdx, 15, &r);
if (r != SCPE_OK)
return r;
val[0] |= temp;
return SCPE_OK;
case I_INTER:
if (*cptr != 0) {
do {
NEXTSYMBOL(',');
if (instInter[j] == 0)
return SCPE_ARG;
val[0] |= instInter[j];
} while (*cptr != 0);
}
return SCPE_OK;
case I_SHIFT:
if (*cptr == '$') {
rdx = 16;
cptr++;
}
temp = get_uint(cptr, rdx, 31, &r);
if (r != SCPE_OK)
return r;
val[0] |= temp;
return SCPE_OK;
}
return SCPE_ARG;
}

342
CDC1700/cdc1700_sys.c Normal file
View file

@ -0,0 +1,342 @@
/*
Copyright (c) 2015-2016, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of John Forecast shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from John Forecast.
*/
/* cdc1700_sys.c: CDC1700 system description
*/
#include "cdc1700_defs.h"
#include <ctype.h>
extern void buildDCtables(void);
extern void buildIOtable(void);
extern int disassem(char *, uint16, t_bool, t_bool, t_bool);
extern uint16 M[];
extern REG cpu_reg[];
extern DEVICE cpu_dev, dca_dev, dcb_dev, dcc_dev,
tti_dev, tto_dev, ptr_dev, ptp_dev, cdr_dev, mt_dev, lp_dev, dp_dev,
cd_dev, rtc_dev;
extern UNIT cpu_unit;
t_stat autoload(int32, CONST char *);
t_stat CDautoload(void);
t_stat DPautoload(void);
t_bool RelValid = FALSE;
uint16 RelBase;
/* SCP data structures and interface routines
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/
char sim_name[] = "CDC1700";
REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 2;
DEVICE *sim_devices[] = {
&cpu_dev,
&rtc_dev,
&dca_dev,
&dcb_dev,
&dcc_dev,
&tti_dev,
&tto_dev,
&ptr_dev,
&ptp_dev,
#if 0
&cdr_dev,
#endif
&mt_dev,
&lp_dev,
&dp_dev,
&cd_dev,
NULL
};
const char *sim_stop_messages[] = {
"OK",
"Indirect addressing loop count exceeded",
"Selective Stop",
"Invalid bits set in EXI instruction",
"Breakpoint",
"Stop on reject"
};
/*
* New top-level command(s) for the CDC1700
*/
CTAB cdc1700_cmd[] = {
{ "AUTOLOAD", &autoload, 0,
"a{utoload} <controller> Autoload from default device on controller\n"
" Loads track 0 to location 0\n"
},
{ NULL }
};
/*
* Command post-processing routine.
*/
static void postUpdate(t_bool from_scp)
{
/*
* Rebuild the I/O device and buffered data channel tables in case the
* command the configuration.
*/
buildIOtable();
buildDCtables();
RelValid = FALSE;
}
/*
* Special address print routine for "Relative" display.
*/
static void printAddress(FILE *st, DEVICE *dptr, t_addr addr)
{
if ((dptr == sim_devices[0]) && ((sim_switches & SWMASK('R')) != 0)) {
if (!RelValid) {
RelBase = (uint16)addr;
RelValid = TRUE;
}
addr -= RelBase;
}
fprint_val(st, addr, dptr->aradix, dptr->awidth, PV_RZRO);
}
/*
* Once-only VM initialization
*/
static void VMinit(void)
{
sim_vm_fprint_addr = &printAddress;
sim_vm_post = &postUpdate;
sim_vm_cmd = cdc1700_cmd;
/*
* Initialize the "CPU" device to make sure the data structures are
* correctly initialized.
*/
(cpu_dev.reset)(&cpu_dev);
}
void (*sim_vm_init)(void) = &VMinit;
/*
* Check for duplicate equipment addresses.
*/
static t_bool checkDuplicate(DEVICE *dptr, uint8 equipment)
{
int i = 0;
DEVICE *dptr2;
while ((dptr2 = sim_devices[i++]) != NULL) {
if ((dptr2 != dptr) && ((dptr2->flags & DEV_DIS) == 0)) {
IO_DEVICE *iod = (IO_DEVICE *)dptr2->ctxt;
if (iod->iod_equip == equipment)
return TRUE;
}
}
return FALSE;
}
/*
* Common routine to change the equipment address of a peripheral. Some
* devices (e.g. TT, PTR etc) cannot have their equipment address changed.
*/
t_stat set_equipment(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
DEVICE *dptr;
IO_DEVICE *iod;
t_value v;
t_stat r;
if (cptr == NULL)
return SCPE_ARG;
v = get_uint(cptr, DEV_RDX, 15, &r);
if (r != SCPE_OK)
return r;
if (v == 0)
return SCPE_ARG;
/*
* Check to see if any other, non-disabled device is already using this
* address.
*/
if ((dptr = find_dev_from_unit(uptr)) != NULL) {
if (checkDuplicate(dptr, v))
return sim_messagef(SCPE_ARG, "Equipment address already in use\n");
iod = (IO_DEVICE *)dptr->ctxt;
iod->iod_equip = v;
iod->iod_interrupt = 1 << v;
return SCPE_OK;
}
return SCPE_NXDEV;
}
/*
* Check for a duplicate address when a device is reset. If a duplicate is
* found, the device being reset is disabled.
*/
t_stat checkReset(DEVICE *dptr, uint8 equipment)
{
if (checkDuplicate(dptr, equipment)) {
dptr->flags |= DEV_DIS;
return sim_messagef(SCPE_ARG, "Equipment address already in use\n");
}
return SCPE_OK;
}
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fname, int flag)
{
t_addr lo, hi;
if (flag == 0)
return SCPE_ARG;
/*
* We want to write the memory in some device-dependent format. sim_switches
* contains the command switches which will be used to determine the
* format:
*
* -p Paper tape format
*
* Command syntax is:
*
* dump <file> -p <loaddr>-<hiaddr>
*/
if ((sim_switches & SWMASK('P')) != 0) {
const char *tptr;
t_addr addr;
int temp, count = 0;
tptr = get_range(NULL, cptr, &lo, &hi, cpu_dev.aradix, cpu_unit.capac - 1, 0);
if (tptr != NULL) {
/*
* Output a couple of NULL frames to start the dump
*/
fputc(0, fileref);
fputc(0, fileref);
for (addr = lo; addr <= hi; addr++) {
temp = M[addr];
/*
* If the data is 0, map it to -0 (0xFFFF) since 0 terminates the
* sequence. We also count the number of times this happens and
* report it at the end.
*/
if (temp == 0) {
temp =0xFFFF;
count++;
}
fputc((temp >> 8) & 0xFF, fileref);
fputc(temp & 0xFF, fileref);
}
/*
* Terminate the dump with 2 more NULL frames
*/
fputc(0, fileref);
fputc(0, fileref);
if (count != 0)
printf("%d zero word translated to 0xFFFF\n", count);
return SCPE_OK;
}
}
return SCPE_ARG;
}
/*
* Symbolic decode
*/
#define FMTASC(x) ((x) < 040) ? "<%03o>" : "%c", (x)
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
{
int32 inst = val[0];
t_bool target = (sw & SWMASK('T')) != 0;
char buf[128];
int consume;
if ((sw & SWMASK('A')) != 0) {
/* ASCII character */
if (inst > 0377)
return SCPE_ARG;
fprintf(of, FMTASC(inst & 0177));
return SCPE_OK;
}
if ((sw & SWMASK('C')) != 0) {
unsigned char c1 = (inst >> 8) & 0xFF, c2 = inst & 0xFF;
fprintf(of, FMTASC(c1 & 0177));
fprintf(of, FMTASC(c2 & 0177));
return SCPE_OK;
}
if ((sw & SWMASK('M')) == 0)
return SCPE_ARG;
consume = disassem(buf, (uint16)addr, FALSE, target, FALSE);
fprintf(of, "%s", buf);
return -(consume - 1);
}
/*
* Autoload top-level command routine
*/
t_stat autoload(int32 flag, CONST char *ptr)
{
char gbuf[CBUFSIZE];
DEVICE *dptr;
if (!ptr || !*ptr)
return SCPE_2FARG;
get_glyph(ptr, gbuf, 0);
dptr = find_dev(gbuf);
if (dptr == NULL)
return SCPE_ARG;
if (dptr == &cd_dev)
return CDautoload();
if (dptr == &dp_dev)
return DPautoload();
return SCPE_NOFNC;
}

View file

@ -32,6 +32,8 @@
#### Intel Systems 8010 and 8020 simulators from Bill Beech
#### CDC 1700 simulator from John Forecast
### New Host Platform support - HP-UX and AIX
### Simulator Front Panel API

View file

@ -0,0 +1,357 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="CDC1700"
ProjectGUID="{2D532F83-02F3-4169-9778-23E52D951FDE}"
RootNamespace="CDC1700"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
KeepComments="false"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wsock32.lib winmm.lib pcrestaticd.lib pcreposixstaticd.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wsock32.lib winmm.lib pcrestatic.lib pcreposixstatic.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
GenerateDebugInformation="false"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\CDC1700\cdc1700_cd.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_cpu.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_dc.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_dev1.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_dis.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_dp.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_io.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_iofw.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_lp.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_mt.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_rtc.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_sym.c"
>
</File>
<File
RelativePath="..\CDC1700\cdc1700_sys.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\sim_video.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\CDC1700\cdc1700_defs.h"
>
</File>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\sim_video.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -228,6 +228,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HP3000", "HP3000.vcproj", "
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDC1700", "CDC1700.vcproj", "{2D532F83-02F3-4169-9778-23E52D951FDE}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -418,6 +423,10 @@ Global
{B3E35063-CB41-4F77-BFCA-49BB316B0EDB}.Debug|Win32.Build.0 = Debug|Win32
{B3E35063-CB41-4F77-BFCA-49BB316B0EDB}.Release|Win32.ActiveCfg = Release|Win32
{B3E35063-CB41-4F77-BFCA-49BB316B0EDB}.Release|Win32.Build.0 = Release|Win32
{2D532F83-02F3-4169-9778-23E52D951FDE}.Debug|Win32.ActiveCfg = Debug|Win32
{2D532F83-02F3-4169-9778-23E52D951FDE}.Debug|Win32.Build.0 = Debug|Win32
{2D532F83-02F3-4169-9778-23E52D951FDE}.Release|Win32.ActiveCfg = Release|Win32
{2D532F83-02F3-4169-9778-23E52D951FDE}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -20,6 +20,7 @@
# ALTAIRZ80 Just Build The MITS Altair Z80.
# BESM6 Just Build The BESM-6.
# B5500 Just Build The B5500.
# CDC1700 Just Build The CDC1700.
# ECLIPSE Just Build The Data General Eclipse.
# GRI Just Build The GRI Corporation GRI-909.
# LGP Just Build The Royal-McBee LGP-30.
@ -675,6 +676,18 @@ B5500_SOURCE = $(B5500_DIR)B5500_CPU.C,$(B5500_DIR)B5500_DK.C,$(B5500_DIR)B5500_
$(B5500_DIR)B5500_SYS.C,$(B5500_DIR)B5500_UREC.C,$(SIMH_DIR)SIM_CARD.C
B5500_OPTIONS = /INCL=($(SIMH_DIR),$(B5500_DIR))/DEF=($(CC_DEFS),"USE_INT64=1","USE_SIM_CARD=1")
#
# CDC1700
#
CDC1700_DIR = SYS$DISK:[.CDC1700]
CDC1700_LIB = $(LIB_DIR)CDC1700-$(ARCH).OLB
CDC1700_SOURCE = $(CDC1700_DIR)CDC1700_CPU.C,$(CDC1700_DIR)CDC1700_DIS.C,$(CDC1700_DIR)CDC1700_IO.C,\
$(CDC1700_DIR)CDC1700_SYS.C,$(CDC1700_DIR)CDC1700_DEV1.C,$(CDC1700_DIR)CDC1700_MT.C,\
$(CDC1700_DIR)CDC1700_DC.C,$(CDC1700_DIR)CDC1700_IOFW.C,$(CDC1700_DIR)CDC1700_LP.C,\
$(CDC1700_DIR)CDC1700_DP.C,$(CDC1700_DIR)CDC1700_CD.C,$(CDC1700_DIR)CDC1700_SYM.C,\
$(CDC1700_DIR)CDC1700_RTC.C
CDC1700_OPTIONS = /INCL=($(SIMH_DIR),$(CDC1700_DIR))/DEF=($(CC_DEFS))
#
# Digital Equipment VAX 3900 Simulator Definitions.
#
@ -934,8 +947,8 @@ I7094_OPTIONS = /INCL=($(SIMH_DIR),$(I7094_DIR))/DEF=($(CC_DEFS))
# If we're not a VAX, Build Everything
#
.IFDEF ALPHA_OR_IA64
ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI LGP H316 HP2100 HP3000 I1401 I1620 IBM1130 ID16 \
ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 \
ALL : ALTAIR ALTAIRZ80 CDC1700 ECLIPSE GRI LGP H316 HP2100 HP3000 I1401 I1620 \
IBM1130 ID16 ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 \
VAX MICROVAX3900 MICROVAX1 RTVAX1000 MICROVAX2 VAX730 VAX750 VAX780 VAX8600 \
SDS I7094 SWTP6800MP-A SWTP6800MP-A2 SSEM BESM6 B5500
$! No further actions necessary
@ -943,7 +956,7 @@ ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI LGP H316 HP2100 HP3000 I1401 I1620 IBM1130 ID
#
# Else We Are On VAX And Build Everything EXCEPT the 64b simulators
#
ALL : ALTAIR ALTAIRZ80 GRI H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \
ALL : ALTAIR ALTAIRZ80 CDC1700 GRI H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \
NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 S3 \
VAX MICROVAX3900 MICROVAX1 RTVAX1000 MICROVAX2 VAX730 VAX750 VAX780 VAX8600 \
SDS SWTP6800MP-A SWTP6800MP-A2 SSEM
@ -1430,6 +1443,17 @@ $(B5500_LIB) :
$! $(MMS$TARGET) Library On VAX.
.ENDIF
$(CDC1700_LIB) : $(CDC1700_SOURCE)
$!
$! Building The $(CDC1700_LIB) Library.
$!
$ $(CC)$(CDC1700_OPTIONS) -
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
LIBRARY/CREATE $(MMS$TARGET)
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
$(VAX_LIB1) : $(VAX_SOURCE1)
$!
$! Building The $(VAX_LIB1) Library.
@ -2059,6 +2083,18 @@ B5500 :
.ENDIF
CDC1700 : $(BIN_DIR)CDC1700-$(ARCH).EXE
$! CDC1700 done
$(BIN_DIR)CDC1700-$(ARCH).EXE : $(SIMH_MAIN) $(SIMH_NONET_LIB) $(CDC1700_LIB)
$!
$! Building The $(BIN_DIR)CDC1700-$(ARCH).EXE Simulator.
$!
$ $(CC)$(CDC1700_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)CDC1700-$(ARCH).EXE -
$(BLD_DIR)SCP.OBJ,$(CDC1700_LIB)/LIBRARY,$(SIMH_NONET_LIB)/LIBRARY
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX : MICROVAX3900
$! MICROVAX3900 aka VAX done

View file

@ -1367,6 +1367,16 @@ B5500_OPT = -I.. -DUSE_INT64 -DB5500 -DUSE_SIM_CARD
### Experimental simulators
###
CDC1700D = CDC1700
CDC1700 = ${CDC1700D}/cdc1700_cpu.c ${CDC1700D}/cdc1700_dis.c \
${CDC1700D}/cdc1700_io.c ${CDC1700D}/cdc1700_sys.c \
${CDC1700D}/cdc1700_dev1.c ${CDC1700D}/cdc1700_mt.c \
${CDC1700D}/cdc1700_dc.c ${CDC1700D}/cdc1700_iofw.c \
${CDC1700D}/cdc1700_lp.c ${CDC1700D}/cdc1700_dp.c \
${CDC1700D}/cdc1700_cd.c ${CDC1700D}/cdc1700_sym.c \
${CDC1700D}/cdc1700_rtc.c
CDC1700_OPT = -I ${CDC1700D}
BESM6D = BESM6
BESM6 = ${BESM6D}/besm6_cpu.c ${BESM6D}/besm6_sys.c ${BESM6D}/besm6_mmu.c \
${BESM6D}/besm6_arith.c ${BESM6D}/besm6_disk.c ${BESM6D}/besm6_drum.c \
@ -1450,7 +1460,7 @@ PDQ3_OPT = -I ${PDQ3D} -DUSE_SIM_IMD
ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
vax microvax3900 microvax1 rtvax1000 microvax2 vax730 vax750 vax780 vax8600 \
nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \
i7094 ibm1130 id16 id32 sds lgp h316 \
i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \
swtp6800mp-a swtp6800mp-a2 tx-0 ssem isys8010 isys8020 \
b5500
@ -1745,6 +1755,12 @@ ${BIN}ssem${EXE} : ${SSEM} ${SIM}
${MKDIRBIN}
${CC} ${SSEM} ${SIM} ${SSEM_OPT} $(CC_OUTSPEC) ${LDFLAGS}
cdc1700 : ${BIN}cdc1700${EXE}
${BIN}cdc1700${EXE} : ${CDC1700} ${SIM}
${MKDIRBIN}
${CC} ${CDC1700} ${SIM} ${CDC1700_OPT} ${CC_OUTSPEC} ${LDFLAGS}
besm6 : ${BIN}besm6${EXE}
${BIN}besm6${EXE} : ${BESM6} ${SIM}