CDC1700: Initial import of new simulator from John Forecast
This commit is contained in:
parent
93a8754bfe
commit
1897dfeb94
22 changed files with 13713 additions and 4 deletions
280
CDC1700/CDC1700-Diagnostics.txt
Normal file
280
CDC1700/CDC1700-Diagnostics.txt
Normal 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
588
CDC1700/CDC1700-MSOS.txt
Normal 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
198
CDC1700/CDC1700.txt
Normal 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
1327
CDC1700/cdc1700_cd.c
Normal file
File diff suppressed because it is too large
Load diff
1548
CDC1700/cdc1700_cpu.c
Normal file
1548
CDC1700/cdc1700_cpu.c
Normal file
File diff suppressed because it is too large
Load diff
795
CDC1700/cdc1700_dc.c
Normal file
795
CDC1700/cdc1700_dc.c
Normal 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
919
CDC1700/cdc1700_defs.h
Normal 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
1497
CDC1700/cdc1700_dev1.c
Normal file
File diff suppressed because it is too large
Load diff
325
CDC1700/cdc1700_dis.c
Normal file
325
CDC1700/cdc1700_dis.c
Normal 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
1102
CDC1700/cdc1700_dp.c
Normal file
File diff suppressed because it is too large
Load diff
584
CDC1700/cdc1700_io.c
Normal file
584
CDC1700/cdc1700_io.c
Normal 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
477
CDC1700/cdc1700_iofw.c
Normal 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
654
CDC1700/cdc1700_lp.c
Normal 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
1973
CDC1700/cdc1700_mt.c
Normal file
File diff suppressed because it is too large
Load diff
341
CDC1700/cdc1700_rtc.c
Normal file
341
CDC1700/cdc1700_rtc.c
Normal 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
339
CDC1700/cdc1700_sym.c
Normal 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
342
CDC1700/cdc1700_sys.c
Normal 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;
|
||||
}
|
|
@ -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
|
||||
|
|
357
Visual Studio Projects/CDC1700.vcproj
Normal file
357
Visual Studio Projects/CDC1700.vcproj
Normal 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 & 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 & 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>
|
|
@ -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
|
||||
|
|
42
descrip.mms
42
descrip.mms
|
@ -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
|
||||
|
||||
|
|
18
makefile
18
makefile
|
@ -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}
|
||||
|
|
Loading…
Add table
Reference in a new issue