CDC1700: Release 3

- Add 1752 Drum support. Allow shared subroutines across interrupt levels.
- Document and add sample scripts for customizing MSOS5.
This commit is contained in:
John Forecast 2017-12-14 16:44:01 -08:00 committed by Mark Pizzolato
parent ecf7af59d5
commit a5feaf2815
38 changed files with 13577 additions and 470 deletions

1
.gitattributes vendored
View file

@ -7,5 +7,6 @@
*.bin binary *.bin binary
*.imd binary *.imd binary
*.rim binary *.rim binary
*.tap binary
sim_rev.h export-subst sim_rev.h export-subst

View file

@ -0,0 +1,189 @@
Customizing MSOS 5 For the CDC 1700 Simulator
=============================================
1. Overview
Each MSOS 5 customer was provided with at least 2 sets of distribution
materials for MSOS 5 (on punched cards or magnetic tape):
1. A full distribution of all possible system modules for all supported
hardware confugurations (the Fortran library on the other hand is
tailored for a particular installation).
2. A distribution tailored for a specific installation. It only contains
device drivers for a specific configuration and may or may not include
modules from the Fortran run-time library.
Unfortunately none of the full distribution kits have survived so we will
have to make use of a tailored distribution. This means that we will only be
able to remove device drivers and make small modifications to a running system.
System customization consists of making modifications to 1 or 2
source-level components:
1. The system skeleton which describes which is read by the initializer and
defines which components should be loaded into the system image and
specifies which components should be loaded on the library disk. The
skeleton is also able to define global values by the system.
2. SYSDAT. This an assembler source file which describes the peripheral
configuration including interrupts and equipment addresses. Optional
components, such as file manager, may have dedicated sections of SYSDAT.
The system skeleton may be extracted and edited by an application called SKED.
This is a very primitive line editor but, fortunately, most of the changes are
in SYSDAT. SYSDAT is usually provided as the last file present on a tailored
magtape distribution. Unfortunately I have been unable to use MSOS tools to
extract a useable version from a magtape so I wrote Unix tools to manipulate
magtape containers and compress/decompress COSY format files (rawtap & cosy).
Each customization builds on the previous version to change setting and/or
change MSOS drivers. Each customization is driven by a simh script, takes an
existing installation tape (typically MSOS5_SL136.tap) and generates a new
installation tape (MSOS5-Install.trap). When SYSDAT needs to be modified, a
sysdat.asm file is present which needs to be converted to fixed size (80
characters) records and written to a magtape container:
dd if=sysdat.asm of=sysdat.asm.blk cbs=80 conv=block
rawtap -c sysdat.tap -r 80 sysdat.asm.blk
To perform a customization, a running installation generated by
msosInstall.simh is required. If necessary, create sysdat.tap as described
above (customizations 2 - 5) and run the simulator:
cdc1700 msosCustomX.simh <install tape>
where X is 1 to 5 depending on which customization is required. <install tape>
does not need to be specified if it is MSOS5_SL136.tap in the current
directory. The script will run through the customization steps and generate a
new install tape (MSOS5-Install.tap). msosInstall.simh can be used with this
tape to create a customized system.
Each customization directory includes msosCustomX.simh as well as sysdat.asm
and sysdat.tap (customization 1 does not require sysdat changes so it only
contains msosCustom1.simh.
2. Customization 1
This customization changes the creation date of the OS which is
output to the console when the system boots. The changes are in-line in
msosCustom1.simh. SYSMON, SYSDAY and SYSYER modified by SKED. The values are
the month, day and year in ASCII (high byte first).
3. Customization 2
This customization also changes the name of the system from "EXXON
DEVELOPMENT SYSTEM" to "SIMH DEVELOPMENT SYSTEM". Note that the SYSDAT module
name still includes "EXXON DEVELOPMENT SYSTEM" since there is no way to delete
a module and include a new one, only the ability to replace an existing module
is available.
4. Customization 3
The default installation from MSOS5_SL136.tap sets up all four disk
drives as well as the drum for file storage. I have been unable to find a
method for initializing the disk space for anything other than the the
library disk (CDD0/CDD1). This customization changes the file manager
configuration to only use the library disk for storage. This change gets rid
of one of the verification errors.
5. Customization 4
This customization gets rid of the 1743-2 Asynch communications
controller drive. There is no documentation for this device and it appears to
be used for the TIMESHARE option for which there are no good tapes available.
6. Customization 5
This customization adds support for a 10336 real-time clock which
interrupts at ~60Hz. After all of the above modifications, an example run of
the system:
MSOS 5.0--PSR LEVEL 120 04/19/17
SET PROGRAM PROTECT
SIMH DEVELOPMENT SYSTEM
65K MODE
CHECKING FILES - OK
ENTER DATE/TIME MMDDYYHHMM
0508891516
DATE: 08 MAY 89 TIME: 1516:00
MI
*BATCH
J
*JOB
J
*K,L4
J
*LULIST
E10
LOG1A
SYSID
SYSYER
SYSDAY
SYSMON
E *E
MSOS 5.0 LOGICAL UNIT LISTING FOR SIMH DEVELOPMENT SYSTEM 04/19/17
LU. EQUIPMENT DESCRIPTION READ/WRITE CLASS CODE EQ NO
01. SOFTWARE CORE ALLOCATOR READ/WRITE NO CLASS CODE EQ 00
02. SOFTWARE DUMMY ALTERNATE DEVICE READ/WRITE NO CLASS CODE EQ 00
03. SOFTWARE DUMMY ALTERNATE DEVICE READ/WRITE NO CLASS CODE EQ 00
04. 1711 TELETYPEWRITER READ/WRITE TELETYPE EQ 01
05. COSY UNIT READ/WRITE MAGNETIC TAPE EQ 00
06. 1732-3/616-92 MAG TAPE READ/WRITE MAGNETIC TAPE EQ 07
07. PSEUDO TAPE UNIT READ/WRITE MAGNETIC TAPE EQ 00
08. 1733-2/856-4 DISK UNIT (4.5M) READ/WRITE MASS STORAGE EQ 03
09. 1742-120 LINE PRINTER WRITE ONLY LINE PRINTER EQ 04
10. 1732-3/616-92 MAG TAPE READ/WRITE MAGNETIC TAPE EQ 07
11. 1728/430 CARD READER/PUNCH READ/WRITE CARD RDR/PUNCH EQ 10
12. 1742-120 LINE PRINTER WRITE ONLY LINE PRINTER EQ 04
13. 1733-2/856-4 DISK UNIT (4.5M) READ/WRITE MASS STORAGE EQ 03
14. 1733-2/856-4 DISK UNIT (4.5M) READ/WRITE MASS STORAGE EQ 03
15. 1733-2/856-4 DISK UNIT (4.5M) READ/WRITE MASS STORAGE EQ 03
16. 1732-3/616-92 MAG TAPE READ/WRITE MAGNETIC TAPE EQ 07
17. 1732-3/616-92 MAG TAPE READ/WRITE MAGNETIC TAPE EQ 07
18. 1732-3/616-92 MAG TAPE READ/WRITE MAGNETIC TAPE EQ 07
19. PSEUDO TAPE UNIT READ/WRITE MAGNETIC TAPE EQ 00
20. PSEUDO TAPE UNIT READ/WRITE MAGNETIC TAPE EQ 00
21. PSEUDO TAPE UNIT READ/WRITE MAGNETIC TAPE EQ 00
22. PSEUDO DISK DRIVER READ/WRITE MASS STORAGE EQ 00
23. PSEUDO DISK DRIVER READ/WRITE MASS STORAGE EQ 00
24. PSEUDO DISK DRIVER READ/WRITE MASS STORAGE EQ 00
25. PSEUDO DISK DRIVER READ/WRITE MASS STORAGE EQ 00
26. 1752 DRUM UNIT READ/WRITE MASS STORAGE EQ 02
27. COSY UNIT READ/WRITE MAGNETIC TAPE EQ 00
28. 1728/430 CARD READER/PUNCH READ/WRITE CARD RDR/PUNCH EQ 10
29. 1732-3/616-92 MAG TAPE READ/WRITE MAGNETIC TAPE EQ 07
30. 1732-3/616-92 MAG TAPE READ/WRITE MAGNETIC TAPE EQ 07
31. 1732-3/616-92 MAG TAPE READ/WRITE MAGNETIC TAPE EQ 07
32. 1742-120 LINE PRINTER WRITE ONLY LINE PRINTER EQ 04
33. 1728/430 CARD READER/PUNCH READ/WRITE CARD RDR/PUNCH EQ 10
34. 1711 TELETYPEWRITER READ/WRITE TELETYPE EQ 01
J
7. RPG II and Cobol Installation
While installation materials for both RPG II and Cobol are available
on bitsavers.org (141_PRODUCT_SET.tap contains both) they are built to run
in core partition 3 which does not exist in the standard distribution tape
(MSOS5_SL136.tap). There does not appear to be sufficient documentation
available to add another partition.

View file

@ -50,6 +50,8 @@ FE QL2 10196 095C Quick Look 2 (more detailed instruction set test)
4B PET 12166 0C14 1732-2/1732-3 Magnetic Tape Test 4B PET 12166 0C14 1732-2/1732-3 Magnetic Tape Test
Passed in programmed I/O mode Passed in programmed I/O mode
Failed in DMA mode Failed in DMA mode
80 DRM 11086 2702 BG504 Drum Test
Passed
91 RTC 10216 04DA System 17 Real Time Clock Test 91 RTC 10216 04DA System 17 Real Time Clock Test
Passed Passed
@ -269,7 +271,7 @@ FC DPC 09146 0685 Disk Call-up Program
87 SCC 07155 0BCD Synchronous Communication Controller (FJ606-A) Test 87 SCC 07155 0BCD Synchronous Communication Controller (FJ606-A) Test
88 CPC 10216 0E5C 1725-1 Card Punch Test 88 CPC 10216 0E5C 1725-1 Card Punch Test
89 BSC 11196 0CC3 Cyberdata Bisync Controller Test 89 BSC 11196 0CC3 Cyberdata Bisync Controller Test
8A HFP 07046 1CDE 1781-a Hardware Floating Point Unit Test 8A HFP 07046 1CDE 1781-A Hardware Floating Point Unit Test
90 IOM 11096 0B8B IOM Mother Unit Digital Input/Output Test 90 IOM 11096 0B8B IOM Mother Unit Digital Input/Output Test
91 RTC 10216 04DA System 17 Real Time Clock Test 91 RTC 10216 04DA System 17 Real Time Clock Test
92 PT1 10205 0617 1720-1 Paper Tape Punch Test 92 PT1 10205 0617 1720-1 Paper Tape Punch Test

View file

@ -874,7 +874,7 @@ the simtools respository on github:
*Z *Z
This will compile the source code, send a message to the comment device This will compile the source code, send a message to the comment device
(typically the console TTY) and then load an execute the program. If the (typically the console TTY) and then load and execute the program. If the
program reads data from standard input it should follow the *LGO command. program reads data from standard input it should follow the *LGO command.
4. The compiler/assembler expects each line of input to be in a separate 4. The compiler/assembler expects each line of input to be in a separate
@ -892,8 +892,8 @@ program reads data from standard input it should follow the *LGO command.
running. Listings should be sent to the line printer along with any running. Listings should be sent to the line printer along with any
output from the application. output from the application.
If you want to code is Macro Assembler, the operations are the same; change If you want to code in Macro Assembler, the operations are the same; change
*FTN to *ASSEM and change the OPT parameters. Documentation for both the *FTN to *ASSEM and change the OPT parameters. Documentation for both the Macro
Macro Assembler and Fortran compiler are available on bitsavers.org. Assembler and Fortran compiler are available on bitsavers.org.

View file

@ -80,6 +80,11 @@ mostly from the early period of its release:
[Equipment address: 0x3] [Equipment address: 0x3]
DRM 1752 Drum memory controller with 64 - 1024 tracks of
drum memory (each track is 3072 words).
[Equipment address: 0x2]
Notes: Notes:
DP and CDD use the same equipment address so only 1 of them may be DP and CDD use the same equipment address so only 1 of them may be
enabled (default is for CDD to be enabled). enabled (default is for CDD to be enabled).
@ -132,11 +137,12 @@ handling:
3.2 Disk autoload 3.2 Disk autoload
The autoload mechanism loads track 0 from logical drive 0 of a disk The autoload mechanism loads track 0 from logical drive 0 of a disk or
controller to memory location 0, it does not start execution of the loaded drum 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 code (some of the diagnostics code relies on this). DP, CDD and DRM controllers
support the autoload command ("autoload dp" or "autoload cd") which is support the autoload command ("autoload dp", "autoload cdd" or "autoload drm")
normally followed by a "run 0" command to start execution of the loaded code. which is normally followed by a "run 0" command to start execution of the
loaded code.
4. Operating The Simulator 4. Operating The Simulator
@ -195,5 +201,15 @@ The actual key combination may be changed by issuing the command
5. Software 5. Software
There is some software available at bitsavers.org in the There is some software available at bitsavers.org in the
bits/CDC/1700_Cyber18 directory, see CDC1700_Diagnostics.txt and bits/CDC/1700_Cyber18 directory, see CDC1700-Diagnostics.txt and
CDC1700_MSOS.txt for more details. CDC1700-MSOS.txt for more details.
6. Cyber-18
The CDC 1700 later morphed into the Cyber-18 series. This series
included an enhanced instruction set using unused bits from the 1700
instruction encoding. The simulator can detect these instructions and can be
configured to stop if it tries to execute such an instruction
(set cpu debug=enhanced). Due to a lack of detailed documentation it it
unlikely that the enhanced instruction set will ever be completely implemented.

View file

@ -300,7 +300,7 @@ t_bool CDintr(IO_DEVICE *);
IO_DEVICE CDdev = IODEV(NULL, "1733-2", 1733, 3, 0xFF, 0, IO_DEVICE CDdev = IODEV(NULL, "1733-2", 1733, 3, 0xFF, 0,
CDreject, CDin, CDout, NULL, NULL, CDreject, CDin, CDout, NULL, NULL,
CDstate, CDintr, NULL, NULL, CDstate, CDintr, NULL, NULL, NULL, NULL,
0x7F, 8, 0x7F, 8,
MASK_REGISTER0 | MASK_REGISTER1 | MASK_REGISTER2 | \ MASK_REGISTER0 | MASK_REGISTER1 | MASK_REGISTER2 | \
MASK_REGISTER3 | MASK_REGISTER4 | MASK_REGISTER5 | \ MASK_REGISTER3 | MASK_REGISTER4 | MASK_REGISTER5 | \
@ -876,7 +876,7 @@ void CDDiskIO(UNIT *uptr, uint16 iotype)
if ((cd_dev.dctrl & DBG_DERROR) != 0) if ((cd_dev.dctrl & DBG_DERROR) != 0)
fprintf(DBGOUT, fprintf(DBGOUT,
"%sCD - ReadWrite/Compare failed - %s\r\n", "%sCD - Read/Write/Compare failed - %s\r\n",
INTprefix, error); INTprefix, error);
fw_IOalarm(FALSE, &cd_dev, &CDdev, "Alarm"); fw_IOalarm(FALSE, &cd_dev, &CDdev, "Alarm");
@ -1235,6 +1235,8 @@ enum IOstatus CDout(IO_DEVICE *iod, uint8 reg)
/*** TODO: Check protect conditions ***/ /*** TODO: Check protect conditions ***/
} }
CDdev.STATUS &= ~IO_1733_SINGLE;
if ((IOAreg & IO_1733_USEL) != 0) { if ((IOAreg & IO_1733_USEL) != 0) {
CDdev.iod_drive = NULL; CDdev.iod_drive = NULL;
CDdev.STATUS &= ~(IO_1733_ONCYL | IO_ST_BUSY | IO_ST_READY); CDdev.STATUS &= ~(IO_1733_ONCYL | IO_ST_BUSY | IO_ST_READY);
@ -1244,6 +1246,13 @@ enum IOstatus CDout(IO_DEVICE *iod, uint8 reg)
CDdev.iod_drive = iou; CDdev.iod_drive = iou;
CDdev.STATUS |= IO_ST_READY; CDdev.STATUS |= IO_ST_READY;
/*
* We only need to check on of the physical drives to see if it is
* an 856-4 since both drive types are updated together.
*/
if ((iou->ondrive[0]->flags & UNIT_856_4) == 0)
CDdev.STATUS |= IO_1733_SINGLE;
if (iou->active == NULL) { if (iou->active == NULL) {
int first = ((cd_dev.flags & DEV_FIXED) != 0) ? 1 : 0; int first = ((cd_dev.flags & DEV_FIXED) != 0) ? 1 : 0;
@ -1351,14 +1360,14 @@ enum IOstatus CDout(IO_DEVICE *iod, uint8 reg)
*/ */
t_stat CDautoload(void) t_stat CDautoload(void)
{ {
UNIT *uptr = &cd_unit[(cd_dev.flags & DEV_FIXED) ==0 ? 0 : 1]; UNIT *uptr = &cd_unit[(cd_dev.flags & DEV_FIXED) == 0 ? 0 : 1];
if ((uptr->flags & UNIT_ATT) != 0) { if ((uptr->flags & UNIT_ATT) != 0) {
uint32 i; uint32 i;
for (i = 0; i < CD_NUMSC; i++) { for (i = 0; i < CD_NUMSC; i++) {
t_offset offset = i * CD_NUMBY; t_offset offset = i * CD_NUMBY;
void * buf = &M[i * CD_NUMWD]; void *buf = &M[i * CD_NUMWD];
if (sim_fseeko(uptr->fileref, offset, SEEK_SET) || if (sim_fseeko(uptr->fileref, offset, SEEK_SET) ||
(sim_fread(buf, sizeof(uint16), CD_NUMWD, uptr->fileref) != CD_NUMWD)) (sim_fread(buf, sizeof(uint16), CD_NUMWD, uptr->fileref) != CD_NUMWD))

View file

@ -50,28 +50,50 @@
* CPU interrupts are edge-triggered. The interrupt trigger is * CPU interrupts are edge-triggered. The interrupt trigger is
* automatically lowered when the CPU starts processing interrupt 0. * automatically lowered when the CPU starts processing interrupt 0.
* *
* 2. There is no documention on relative timing. For example, the paper tape * 2. Interrupts - undocumented feature
*
* The 1704 and 1784 processor doucmentation has a section describing
* interrupt handling. There is a sub-section titled "Sharing subroutines
* between interrupt levels" which indicates that a subroutine such as:
*
* SUBR ADC 0
* IIN
* <code>
* EIN
* JMP* (SUBR)
*
* may be shared between interrupt levels. It include the text "Interrupts
* occuring after the execution of the RTJ are blocked because the IIN is
* executed. These interrupts are not recognized until after the jump is
* executed, because one instruction must be executed after an EIN before
* the interrupt system is active".
*
* The implication of this is that interrupts must be deferred for one
* instruction following an RTJ. And indeed, deferring interrupts after
* an RTJ fixed a crash I was seeing on a customized version of MSOS 5.0.
*
* 3. There is no documention on relative timing. For example, the paper tape
* punch diagnostic enables Alarm+Data interrupts and assumes that it will * punch diagnostic enables Alarm+Data interrupts and assumes that it will
* be able to execute some number of instructions before the interrupt * be able to execute some number of instructions before the interrupt
* occurs. How many instructions should we delay if interrupts are enabled * occurs. How many instructions should we delay if interrupts are enabled
* and all conditions are met to deliver the interrupt immediately? * and all conditions are met to deliver the interrupt immediately?
* *
* 3. Some peripherals, notably the teletypewriter, do not have a protected * 4. Some peripherals, notably the teletypewriter, do not have a protected
* status bit. Does this mean that any application can directly affect * status bit. Does this mean that any application can directly affect
* them? * them?
* *
* - The teletypewriter may be addressed by either a protected or a * - The teletypewriter may be addressed by either a protected or a
* nonprotected instruction (see SC17 Reference Manual). * nonprotected instruction (see SC17 Reference Manual).
* *
* 4. The 1740/1742 line printer controllers are incorrectly documented as * 5. The 1740/1742 line printer controllers are incorrectly documented as
* having the status register at offset 3, it is at offset 1 like all * having the status register at offset 3, it is at offset 1 like all
* other peripherals. * other peripherals.
* *
* 5. For the 1738 disk pack controller, what is the correct response if an * 6. For the 1738 disk pack controller, what is the correct response if an
* operation is initiated with no drive selected? For now, we'll reject * operation is initiated with no drive selected? For now, we'll reject
* the request. * the request.
* *
* 6. For the 1706-A buffered data channel, what interrupt is used to signal * 7. For the 1706-A buffered data channel, what interrupt is used to signal
* "End of Operation"? A channel-specific interrupt or a pass-through * "End of Operation"? A channel-specific interrupt or a pass-through
* interrupt from the device being controlled or some other? * interrupt from the device being controlled or some other?
* *
@ -123,6 +145,7 @@ uint8 P[MAXMEMSIZE];
t_uint64 Instructions; t_uint64 Instructions;
uint16 Preg, Areg, Qreg, Mreg, CAenable, OrigPreg, Pending, IOAreg, IOQreg; uint16 Preg, Areg, Qreg, Mreg, CAenable, OrigPreg, Pending, IOAreg, IOQreg;
uint16 R1reg, R2reg, R3reg, R4reg;
uint8 Pfault, Protected, lastP, Oflag, INTflag, DEFERflag; uint8 Pfault, Protected, lastP, Oflag, INTflag, DEFERflag;
t_bool ExecutionStarted = FALSE; t_bool ExecutionStarted = FALSE;
@ -177,7 +200,7 @@ t_stat cpu_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE CPUdev = IODEV(NULL, "1714", CPU, 0, 0xFF, 0, IO_DEVICE CPUdev = IODEV(NULL, "1714", CPU, 0, 0xFF, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0, 0, 0, 0, 0, 0, 0, 0, NULL); NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
/* CPU data structures /* CPU data structures
@ -1128,6 +1151,7 @@ t_stat executeAnInstruction(void)
StoreToMem(operand, Preg); StoreToMem(operand, Preg);
Preg = operand; Preg = operand;
INCP; INCP;
DEFERflag = 1;
break; break;
case OPC_STQ: case OPC_STQ:
@ -1185,7 +1209,8 @@ t_stat executeAnInstruction(void)
} }
break; break;
} }
/*** TODO: Enhanced skip instructions ***/ Preg = OrigPreg;
return SCPE_UNIMPL;
break; break;
} }
break; break;
@ -1427,8 +1452,8 @@ t_stat executeAnInstruction(void)
case INSTR_ENHANCED: case INSTR_ENHANCED:
if ((instr & OPC_MODMASK) != 0) { if ((instr & OPC_MODMASK) != 0) {
/*** TODO: Enhanced instructions ***/ Preg = OrigPreg;
goto done; return SCPE_UNIMPL;
} }
break; break;
} }
@ -1635,7 +1660,8 @@ t_stat executeAnInstruction(void)
case INSTR_ENHANCED: case INSTR_ENHANCED:
if ((instr & OPC_MODMASK) != 0) { if ((instr & OPC_MODMASK) != 0) {
/*** TODO: Enhanced miscellaneous instructions ***/ Preg = OrigPreg;
return SCPE_UNIMPL;
} }
break; break;
} }

View file

@ -116,7 +116,7 @@ t_stat dc_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE DCAdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_1_A, IO_DEVICE DCAdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_1_A,
DCreject, DCin, DCout, NULL, NULL, DCreject, DCin, DCout, NULL, NULL,
DCstate, NULL, NULL, NULL, DCstate, NULL, NULL, NULL, NULL, NULL,
0x7F, 4, 0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | \ MASK_REGISTER0 | MASK_REGISTER1 | \
MASK_REGISTER2 | MASK_REGISTER3, MASK_REGISTER2 | MASK_REGISTER3,
@ -124,7 +124,7 @@ IO_DEVICE DCAdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_1_A,
IO_DEVICE DCBdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_2_A, IO_DEVICE DCBdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_2_A,
DCreject, DCin, DCout, NULL, NULL, DCreject, DCin, DCout, NULL, NULL,
DCstate, NULL, NULL, NULL, DCstate, NULL, NULL, NULL, NULL, NULL,
0x7F, 4, 0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | \ MASK_REGISTER0 | MASK_REGISTER1 | \
MASK_REGISTER2 | MASK_REGISTER3, MASK_REGISTER2 | MASK_REGISTER3,
@ -132,7 +132,7 @@ IO_DEVICE DCBdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_2_A,
IO_DEVICE DCCdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_3_A, IO_DEVICE DCCdev = IODEV(NULL, "1706-A", DC, 0, 0xFF, IO_1706_3_A,
DCreject, DCin, DCout, NULL, NULL, DCreject, DCin, DCout, NULL, NULL,
DCstate, NULL, NULL, NULL, DCstate, NULL, NULL, NULL, NULL, NULL,
0x7F, 4, 0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | \ MASK_REGISTER0 | MASK_REGISTER1 | \
MASK_REGISTER2 | MASK_REGISTER3, MASK_REGISTER2 | MASK_REGISTER3,

View file

@ -44,6 +44,7 @@
#define SCPE_INVEXI 3 /* Invalid bit in EXI delta */ #define SCPE_INVEXI 3 /* Invalid bit in EXI delta */
#define SCPE_IBKPT 4 /* Breakpoint */ #define SCPE_IBKPT 4 /* Breakpoint */
#define SCPE_REJECT 5 /* Stop on reject */ #define SCPE_REJECT 5 /* Stop on reject */
#define SCPE_UNIMPL 6 /* Unimplemented instruction */
/* /*
* Private device flags * Private device flags
@ -113,11 +114,13 @@
#define UNIT_V_854 (UNIT_V_UF + 0) /* 854 vs. 853 disk pack drive */ #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_V_856_4 (UNIT_V_UF + 0) /* 856_4 vs. 856_2 drive */
#define UNIT_V_DRMSIZE (UNIT_V_UF + 0) /* 1752 drum memory assignment */
#define UNIT_7TRACK (1 << UNIT_V_7TRACK) #define UNIT_7TRACK (1 << UNIT_V_7TRACK)
#define UNIT_WPROT (1 << UNIT_V_WPROT) #define UNIT_WPROT (1 << UNIT_V_WPROT)
#define UNIT_854 (1 << UNIT_V_854) #define UNIT_854 (1 << UNIT_V_854)
#define UNIT_856_4 (1 << UNIT_V_856_4) #define UNIT_856_4 (1 << UNIT_V_856_4)
#define UNIT_DRMSIZE (1 << UNIT_V_DRMSIZE)
/* /*
* CPU * CPU
@ -386,8 +389,10 @@ enum IOstatus {
*/ */
#define MOD_ENHRE 0x0080 #define MOD_ENHRE 0x0080
#define MOD_ENHIN 0x0040 #define MOD_ENHIN 0x0040
#define MOD_ENHRA 0x0038
#define MOD_ENHRB 0x0007
//#define REG_NONE 0x0 #define REG_NONE 0x0
#define REG_R1 0x1 #define REG_R1 0x1
#define REG_R2 0x2 #define REG_R2 0x2
#define REG_R3 0x3 #define REG_R3 0x3
@ -396,40 +401,48 @@ enum IOstatus {
#define REG_A 0x6 #define REG_A 0x6
#define REG_I 0x7 #define REG_I 0x7
#define OPC_ENHF4 0xF000
#define OPC_ENHF5 0x0F00
#define WORD_REG 0x0 #define WORD_REG 0x0
#define WORD_MEM 0x1 #define WORD_MEM 0x1
#define CHAR_REG 0x2 #define CHAR_REG 0x2
#define CHAR_MEM 0x3 #define CHAR_MEM 0x3
#define OPC_ENHSUBJX 0x5000 #define OPC_STOSJMP 0x5000
#define OPC_ENHADDR 0x8000 #define OPC_STOADD 0x8000
#define OPC_ENHSUBR 0x9000 #define OPC_STOSUB 0x9000
#define OPC_ENHANDR 0xA000 #define OPC_STOAND 0xA000
#define OPC_ENHANDM 0xA100 #define OPC_STOLOADST 0xC000
#define OPC_ENHLOAD 0xC000 #define OPC_STOOR 0xD000
#define OPC_ENHSTORE 0xC100 #define OPC_STOCRE 0xE000
#define OPC_ENHLOADC 0xC200
#define OPC_ENHSTOREC 0xC300
#define OPC_ENHORR 0xD000
#define OPC_ENHORM 0xD100
#define OPC_CMPREQ 0xE000
#define OPC_CMPCEQ 0xE200
#define OPC_FLDF3A 0x07
#define OPC_FLDRSV1 0x0
#define OPC_FLDRSV2 0x1
#define OPC_FLDSFZ 0x2 #define OPC_FLDSFZ 0x2
#define OPC_FLDSFN 0x3 #define OPC_FLDSFN 0x3
#define OPC_FLDLOAD 0x4 #define OPC_FLDLOAD 0x4
#define OPC_FLDSTORE 0x5 #define OPC_FLDSTORE 0x5
#define OPC_FLDCLEAR 0x6 #define OPC_FLDCLEAR 0x6
#define OPC_FLDSET 0x7 #define OPC_FLDSET 0x7
#define OPC_FLDSTR 0xF000
#define OPC_FLDLTH 0x0F00
#define OPC_ENHSKIPZ 0x0 #define OPC_ENHXFRRA 0xE0
#define OPC_ENHSKIPNZ 0x1 #define OPC_ENHXFRF2A 0x18
#define OPC_ENHSKIPPOS 0x2 #define OPC_ENHXFRRB 0x7
#define OPC_ENHSKIPNEG 0x3
#define OPC_ENHSKIPR1 0x4 #define OPC_ENHSKIPTY 0x30
#define OPC_ENHSKIPR2 0x8 #define OPC_ENHSKIPREG 0xC0
#define OPC_ENHSKIPR3 0xC #define OPC_ENHSKIPCNT 0xF
#define OPC_ENHSKIPR4 0x0
#define OPC_DRPMBZ 0x10
#define OPC_DRPRA 0xE0
#define OPC_DRPSK 0xF
#define OPC_MISCRA 0xE0
#define OPC_MISCF3 0xF
#define OPC_ENHLMM 0x1 #define OPC_ENHLMM 0x1
#define OPC_ENHLRG 0x2 #define OPC_ENHLRG 0x2
@ -553,6 +566,8 @@ struct io_device {
t_bool (*iod_intr)(struct io_device *); t_bool (*iod_intr)(struct io_device *);
uint16 (*iod_raised)(DEVICE *); uint16 (*iod_raised)(DEVICE *);
void (*iod_clear)(DEVICE *); void (*iod_clear)(DEVICE *);
uint8 (*iod_decode)(struct io_device *, t_bool, uint8);
t_bool (*iod_chksta)(t_bool, uint8);
uint16 iod_ienable; uint16 iod_ienable;
uint16 iod_oldienable; uint16 iod_oldienable;
uint16 iod_imask; uint16 iod_imask;
@ -561,15 +576,15 @@ struct io_device {
uint16 iod_cmask; uint16 iod_cmask;
uint16 iod_rmask; uint16 iod_rmask;
uint8 iod_regs; uint8 iod_regs;
uint8 iod_validmask; uint16 iod_validmask;
uint8 iod_readmap; uint16 iod_readmap;
uint8 iod_rejmapR; uint16 iod_rejmapR;
uint8 iod_rejmapW; uint16 iod_rejmapW;
uint8 iod_flags; uint8 iod_flags;
uint8 iod_dc; uint8 iod_dc;
uint16 iod_readR[8]; uint16 iod_readR[16];
uint16 iod_writeR[8]; uint16 iod_writeR[16];
uint16 iod_prevR[8]; uint16 iod_prevR[16];
uint16 iod_forced; uint16 iod_forced;
t_uint64 iod_event; t_uint64 iod_event;
uint16 iod_private; uint16 iod_private;
@ -582,6 +597,10 @@ struct io_device {
uint16 iod_private8; uint16 iod_private8;
uint8 iod_private9; uint8 iod_private9;
t_bool iod_private10; t_bool iod_private10;
uint16 iod_private11;
uint16 iod_private12;
uint8 iod_private13;
uint8 iod_private14;
}; };
#define STATUS iod_readR[1] #define STATUS iod_readR[1]
#define DEVSTATUS(iod) ((iod)->iod_readR[1]) #define DEVSTATUS(iod) ((iod)->iod_readR[1])
@ -598,23 +617,31 @@ struct io_device {
#define CLRSTICKY(iod, reg, value) \ #define CLRSTICKY(iod, reg, value) \
((iod)->iod_sticky[reg] &= ~value) ((iod)->iod_sticky[reg] &= ~value)
#define MASK_REGISTER0 0x01 #define MASK_REGISTER0 0x0001
#define MASK_REGISTER1 0x02 #define MASK_REGISTER1 0x0002
#define MASK_REGISTER2 0x04 #define MASK_REGISTER2 0x0004
#define MASK_REGISTER3 0x08 #define MASK_REGISTER3 0x0008
#define MASK_REGISTER4 0x10 #define MASK_REGISTER4 0x0010
#define MASK_REGISTER5 0x20 #define MASK_REGISTER5 0x0020
#define MASK_REGISTER6 0x40 #define MASK_REGISTER6 0x0040
#define MASK_REGISTER7 0x80 #define MASK_REGISTER7 0x0080
#define MASK_REGISTER8 0x0100
#define MASK_REGISTER9 0x0200
#define MASK_REGISTER10 0x0400
#define MASK_REGISTER11 0x0800
#define MASK_REGISTER12 0x1000
#define MASK_REGISTER13 0x2000
#define MASK_REGISTER14 0x4000
#define MASK_REGISTER15 0x8000
#define STATUS_ZERO 0x01 #define STATUS_ZERO 0x01
#define DEVICE_DC 0x02 #define DEVICE_DC 0x02
#define AQ_ONLY 0x04 #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) \ #define IODEV(name, model, id, equ, sta, base, busy, ior, iow, bdcr, bdcw, dump, intr, raised, clear, decode, chksta, mask, regs, valid, map, rejR, rejW, flags, dc, devspec) \
{ name, model, IOtype_default, equ, sta, 0, base, \ { name, model, IOtype_default, equ, sta, 0, base, \
NULL, NULL, NULL, \ NULL, NULL, NULL, \
busy, ior, iow, bdcr, bdcw, dump, intr, raised, clear, \ busy, ior, iow, bdcr, bdcw, dump, intr, raised, clear, decode, chksta, \
0, 0, IO_##id##_INTR, IO_##id##_DIRMSK, IO_##id##_STMSK, \ 0, 0, IO_##id##_INTR, IO_##id##_DIRMSK, IO_##id##_STMSK, \
IO_##id##_STCINT | IO_ST_INT, \ IO_##id##_STCINT | IO_ST_INT, \
mask, regs, valid, map, rejR, rejW, flags, dc, \ mask, regs, valid, map, rejR, rejW, flags, dc, \
@ -722,7 +749,7 @@ typedef uint16 devINTR(DEVICE *);
#define IO_1711_SWRITE 0x0100 /* Select write mode */ #define IO_1711_SWRITE 0x0100 /* Select write mode */
#define IO_1711_DIRMSK (IO_1711_SREAD | IO_1711_SWRITE | IO_DIR_ALARM | \ #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) 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_INTR (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA)
#define IO_1711_MANUAL 0x0800 /* Manual interrupt */ #define IO_1711_MANUAL 0x0800 /* Manual interrupt */
#define IO_1711_MON 0x0400 /* Motor on */ #define IO_1711_MON 0x0400 /* Motor on */
@ -797,6 +824,47 @@ typedef uint16 devINTR(DEVICE *);
IO_ST_INT | IO_ST_BUSY | IO_ST_READY) IO_ST_INT | IO_ST_BUSY | IO_ST_READY)
#define IO_1726_STCINT (IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA) #define IO_1726_STCINT (IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA)
/*
* 1728-A/B Card Reader/Punch
*/
#define IO_1728_MASK 0x0060 /* Station mask */
#define IO_1728_CR 0x0020 /* Card reader select */
#define IO_1728_CP 0x0040 /* Card puch select */
#define IO_1728_OFFSET 0x0100 /* Offset request */
#define IO_1728_FEED 0x0080 /* Initiate feed cycle */
#define IO_1728_DIRMSK (IO_1728_OFFSET | IO_1728_FEED | IO_DIR_ALARM | \
IO_DIR_EOP | IO_DIR_DATA | IO_DIR_CINT | \
IO_DIR_CCONT)
#define IO_1728_INTR (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA)
#define IO_1728_CBFULL 0x0800 /* Chip box full */
#define IO_1728_EOF 0x0400 /* End of file */
#define IO_1728_FEEDAL 0x0200 /* Feed alert */
#define IO_1728_ERROR 0x0100 /* Pre-read or punch error */
#define IO_1728_STMSK (IO_1728_CBFULL | IO_1728_EOF | IO_1728_FEEDAL | \
IO_1728_ERROR | IO_ST_PROT | IO_ST_LOST | \
IO_ST_EOP | IO_ST_DATA | IO_ST_INT | IO_ST_BUSY | \
IO_ST_READY)
#define IO_1728_STCINT (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_DATA)
#define IO_ST2_INTLOCK 0x0400 /* Door interlock */
#define IO_ST2_PUNINH 0x0200 /* Punch inhibit set */
#define IO_ST2_MANUAL 0x0100 /* Manual mode */
#define IO_ST2_PUNERR 0x0080 /* Punch error */
#define IO_ST2_PREERR 0x0040 /* Pre-read error */
#define IO_ST2_STKJAM 0x0020 /* Stacker area jam */
#define IO_ST2_PUNJAM 0x0010 /* Punch area jam */
#define IO_ST2_READJAM 0x0008 /* Read area jam */
#define IO_ST2_FFEED 0x0004 /* Fail to feed */
#define IO_ST2_FULL 0x0002 /* Stacker full */
#define IO_ST2_EMPTY 0x0001 /* Hopper empty */
#define IO_1728_ST2MSK (IO_ST2_INTLOCK | IO_ST2_PUNINH | IO_ST2_MANUAL | \
IO_ST2_PUNERR | IO_ST2_PREERR | IO_ST2_STKJAM | \
IO_ST2_PUNJAM | IO_ST2_READJAM | IO_ST2_FFEED | \
IO_ST2_FULL | IO_ST2_EMPTY)
/* /*
* 1729-A/B Card Reader * 1729-A/B Card Reader
*/ */
@ -997,6 +1065,29 @@ typedef uint16 devINTR(DEVICE *);
#define IO_1742_STCINT (IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA) #define IO_1742_STCINT (IO_ST_ALARM | IO_ST_EOP | IO_ST_DATA)
/*
* 1752-1/2/3/4 Drum
*/
#define IO_1752_DIRMSK (IO_DIR_ALARM | IO_DIR_EOP | IO_DIR_CINT | \
IO_DIR_CCONT)
#define IO_1752_INTR (IO_DIR_ALARM | IO_DIR_EOP)
#define IO_1752_OVERR 0x8000 /* Sector overrange error */
#define IO_1752_GUARDED 0x4000 /* Guarded address error */
#define IO_1752_SECCMP 0x2000 /* Sector compare */
#define IO_1752_POWERF 0x1000 /* Power failure */
#define IO_1752_TIMERR 0x0800 /* Timing track error */
#define IO_1752_GUARDE 0x0400 /* Guarded address enabled */
#define IO_1752_PROTF 0x0200 /* Protect fault */
#define IO_1752_CHECKW 0x0100 /* Checkword error */
#define IO_1752_STMSK (IO_1752_OVERR | IO_1752_GUARDED | IO_1752_SECCMP | \
IO_1752_POWERF | IO_1752_TIMERR | IO_1752_GUARDE | \
IO_1752_PROTF | IO_1752_CHECKW | 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_1752_STCINT (IO_ST_ALARM | IO_ST_EOP)
/* /*
* 10336-1 Real-Time Clock * 10336-1 Real-Time Clock
*/ */
@ -1013,6 +1104,15 @@ typedef uint16 devINTR(DEVICE *);
#define IO_10336_STMSK 0 #define IO_10336_STMSK 0
#define IO_10336_STCINT 0 #define IO_10336_STCINT 0
/*
* M05 addressing scheme used by Cyber-18 enhanced instruction set for
* magtape access.
*/
#define M05_SAMPLE 0x0000 /* Sample (peripheral input) */
#define M05_SET 0x0008 /* Set (peripheral output) */
#define M05_DEVICE 0x0070 /* Device selection */
#define M05_CONTR 0x0380 /* Controller selection */
/* /*
* Timing parameters * Timing parameters
*/ */
@ -1047,8 +1147,14 @@ typedef uint16 devINTR(DEVICE *);
#define CD_IO_WAIT 800 /* Sector I/O wait time */ #define CD_IO_WAIT 800 /* Sector I/O wait time */
#define CD_RTZS_WAIT 200 /* Return to zero seek wait */ #define CD_RTZS_WAIT 200 /* Return to zero seek wait */
#define DRM_ACCESS_WAIT 5800 /* Average access latency */
#define DRM_SECTOR_WAIT 350 /* Sector I/O time */
#define DC_START_WAIT 4 /* Startup delay */ #define DC_START_WAIT 4 /* Startup delay */
#define DC_IO_WAIT 4 /* I/O transfer delay */ #define DC_IO_WAIT 4 /* I/O transfer delay */
#define DC_EOP_WAIT 5 /* EOP delay */ #define DC_EOP_WAIT 5 /* EOP delay */
#define RDR_IN_WAIT 200 /* Card reader feed wait */
#define PUN_OUT_WAIT 200 /* Card punch feed wait */
#endif #endif

View file

@ -26,7 +26,7 @@
*/ */
/* cdc1700_dev1.c: equipment number 1 I/O device support /* cdc1700_dev1.c: equipment number 1 I/O device support
* Simh devices: tti, tto, ptr, ptp, cdr * Simh devices: tti, tto, ptr, ptp
*/ */
#include "cdc1700_defs.h" #include "cdc1700_defs.h"
@ -140,21 +140,21 @@ t_stat tt_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE TTIdev = IODEV("TTI", "1711-A", 1711, 1, 1, 0, IO_DEVICE TTIdev = IODEV("TTI", "1711-A", 1711, 1, 1, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
TTIstate, NULL, NULL, NULL, TTIstate, NULL, NULL, NULL, NULL, NULL,
0xF, 2, 0xF, 2,
MASK_REGISTER0 | MASK_REGISTER1, MASK_REGISTER0 | MASK_REGISTER1,
MASK_REGISTER1, 0, 0, 0, 0, NULL); MASK_REGISTER1, 0, 0, 0, 0, NULL);
IO_DEVICE TTOdev = IODEV("TTO", "1711-A", 1711, 1, 1, 0, IO_DEVICE TTOdev = IODEV("TTO", "1711-A", 1711, 1, 1, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
TTOstate, NULL, NULL, NULL, TTOstate, NULL, NULL, NULL, NULL, NULL,
0xF, 2, 0xF, 2,
MASK_REGISTER0 | MASK_REGISTER1, MASK_REGISTER0 | MASK_REGISTER1,
MASK_REGISTER1, 0, 0, 0, 0, NULL); MASK_REGISTER1, 0, 0, 0, 0, NULL);
IO_DEVICE TTdev = IODEV("TT", "1711-A", 1711, 1, 1, 0, IO_DEVICE TTdev = IODEV("TT", "1711-A", 1711, 1, 1, 0,
TTreject, TTin, TTout, NULL, NULL, TTreject, TTin, TTout, NULL, NULL,
TTstate, NULL, NULL, NULL, TTstate, NULL, NULL, NULL, NULL, NULL,
0xF, 2, 0xF, 2,
MASK_REGISTER0 | MASK_REGISTER1, MASK_REGISTER0 | MASK_REGISTER1,
0, 0, 0, 0, 0, NULL); 0, 0, 0, 0, 0, NULL);
@ -841,7 +841,7 @@ t_stat ptr_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE PTRdev = IODEV(NULL, "1721-A", 1721, 1, 2, 0, IO_DEVICE PTRdev = IODEV(NULL, "1721-A", 1721, 1, 2, 0,
fw_reject, PTRin, PTRout, NULL, NULL, fw_reject, PTRin, PTRout, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0xF, 2, 0xF, 2,
MASK_REGISTER0 | MASK_REGISTER1, MASK_REGISTER0 | MASK_REGISTER1,
MASK_REGISTER1, 0, 0, 0, 0, NULL); MASK_REGISTER1, 0, 0, 0, 0, NULL);
@ -1147,7 +1147,7 @@ t_stat ptp_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE PTPdev = IODEV(NULL, "1723-A", 1723, 1, 4, 0, IO_DEVICE PTPdev = IODEV(NULL, "1723-A", 1723, 1, 4, 0,
fw_reject, PTPin, PTPout, NULL, NULL, fw_reject, PTPin, PTPout, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0xF, 2, 0xF, 2,
MASK_REGISTER0 | MASK_REGISTER1, MASK_REGISTER0 | MASK_REGISTER1,
MASK_REGISTER1, 0, 0, 0, 0, NULL); MASK_REGISTER1, 0, 0, 0, 0, NULL);
@ -1397,164 +1397,6 @@ t_stat ptp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr
return scp_help(st, dptr, uptr, flag, helpString, cptr); return scp_help(st, dptr, uptr, flag, helpString, cptr);
} }
t_stat cdr_svc(UNIT *);
t_stat cdr_reset(DEVICE *);
enum IOstatus CDRin(IO_DEVICE *, uint8);
enum IOstatus CDRout(IO_DEVICE *, uint8);
/*
1729-A/B Card Reader
Addresses
Computer Instruction
Q Register Output From A Input to A
00E0 Read
00E1 Director Function Director Status
Operations:
Director Function
15 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X | X | X | X | X | X | X | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | |
| | | | | | Clr Controller
| | | | | Clr Interrupts
| | | | Data Interrupt Req.
| | | Interrupt on End of Record
| | Interrupt on Alarm
| Start Motion
Stop Motion
Status Response:
Director Status
15 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X | X | X | X | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | |
| | | | | | | | | Ready
| | | | | | | | Busy
| | | | | | | Interrupt
| | | | | | Data
| | | | | End Of Record
| | | | Alarm
| | | Lost Data
| | Protected
| Existence Code
Read Station Empty
*/
IO_DEVICE CDRdev = IODEV(NULL, "1729", 1729, 1, 6, 0,
fw_reject, CDRin, CDRout, NULL, NULL,
NULL, NULL, NULL, NULL,
0xF, 2,
MASK_REGISTER0 | MASK_REGISTER1,
MASK_REGISTER1, 0, 0, 0, 0, NULL);
/* CDR data structures
cdr_dev CDR device descriptor
cdr_unit CDR unit descriptor
cdr_reg CDR register list
cdr_mod CDR modifiers list
*/
UNIT cdr_unit = {
UDATA(&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), SERIAL_IN_WAIT
};
REG cdr_reg[] = {
{ HRDATAD(FUNCTION, CDRdev.FUNCTION, 16, "Last director function issued") },
{ HRDATAD(STATUS, CDRdev.STATUS, 16, "Director status register") },
{ HRDATAD(IENABLE, CDRdev.IENABLE, 16, "Interrupts enabled") },
{ NULL }
};
MTAB cdr_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, "1729 Card Reader" },
{ MTAB_XTD|MTAB_VDV, 0, "EQUIPMENT", NULL,
NULL, &show_addr, NULL, "Display equipment address" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "PROTECT",
&set_protected, NULL, NULL, "Device is protected (unimplemented)" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOPROTECT",
&clear_protected, NULL, NULL, "Device is unprotected (unimplemented)" },
{ 0 }
};
DEBTAB cdr_deb[] = {
{ "TRACE", DBG_DTRACE, "Trace device I/O requests" },
{ "STATE", DBG_DSTATE, "Display device state changes" },
{ "LOCATION", DBG_DLOC, "Display address for I/O instructions" },
{ "FIRSTREJ", DBG_DFIRSTREJ, "Suppress display of 2nd ... I/O rejects" },
{ "ALL", DBG_DTRACE | DBG_DSTATE | DBG_DLOC },
{ NULL }
};
DEVICE cdr_dev = {
"CDR", &cdr_unit, cdr_reg, cdr_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &cdr_reset,
NULL, NULL, NULL,
&CDRdev,
DEV_DEBUG | DEV_NOEQUIP | DEV_INDEV | DEV_PROTECT, 0, cdr_deb,
NULL, NULL, NULL, NULL, NULL, NULL
};
/* Unit service */
t_stat cdr_svc(UNIT *uptr)
{
/*** TODO: Implement Card Reader support ***/
return SCPE_OK;
}
/* Reset routine */
t_stat cdr_reset(DEVICE *dptr)
{
DEVRESET(&CDRdev);
ptr_unit.buf = 0;
if (!sim_is_running)
sim_activate(&cdr_unit, cdr_unit.wait);
return SCPE_OK;
}
/* Perform I/O */
enum IOstatus CDRin(IO_DEVICE *iod, uint8 reg)
{
/*
* The framework only passes IN operations for the data register (0x90)
*/
Areg = cdr_unit.buf;
CDRdev.STATUS &= IO_ST_BUSY | IO_ST_DATA;
return IO_REPLY;
}
enum IOstatus CDRout(IO_DEVICE *iod, uint8 reg)
{
switch (reg) {
case 0x00:
return IO_REJECT;
case 0x01:
doDirectorFunc(&cdr_dev, FALSE);
/*** TODO: Process local director functions ***/
break;
}
return IO_REPLY;
}
/* /*
* Return device 1 interrupt status. If any of the sub-devices have their * Return device 1 interrupt status. If any of the sub-devices have their
* interrupt status active, return the device 1 interrupt mask bit. * interrupt status active, return the device 1 interrupt mask bit.
@ -1563,7 +1405,7 @@ uint16 dev1INTR(DEVICE *dptr)
{ {
uint16 status; uint16 status;
status = TTIdev.STATUS | TTOdev.STATUS | PTRdev.STATUS | PTPdev.STATUS | CDRdev.STATUS; status = TTIdev.STATUS | TTOdev.STATUS | PTRdev.STATUS | PTPdev.STATUS;
return (status & IO_ST_INT) != 0 ? 1 << 1 : 0; return (status & IO_ST_INT) != 0 ? 1 << 1 : 0;
} }
@ -1584,6 +1426,4 @@ void dev1Interrupts(char *buf)
strcat(buf, " PTR"); strcat(buf, " PTR");
if ((PTPdev.STATUS & IO_ST_INT) != 0) if ((PTPdev.STATUS & IO_ST_INT) != 0)
strcat(buf, " PTP"); strcat(buf, " PTP");
if ((CDRdev.STATUS & IO_ST_INT) != 0)
strcat(buf, " CDR");
} }

View file

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2015-2016, John Forecast Copyright (c) 2015-2017, John Forecast
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -71,22 +71,61 @@ const char *destName[] = {
"", "M", "Q", "Q,M", "A", "A,M", "A,Q", "A,Q,M" "", "M", "Q", "Q,M", "A", "A,M", "A,Q", "A,Q,M"
}; };
const char *shiftName[] = { const char *shiftName[] = {
NULL, "QRS", "ARS", "LRS", NULL, "QLS", "ALS", "LLS" NULL, "QRS", "ARS", "LRS", NULL, "QLS", "ALS", "LLS"
}; };
/*
* Enhanced instruction set mnemonics
*/
char enhRegChar[] = {
' ', '1', '2', '3', '4', 'Q', 'A', 'I'
};
const char *enhIdxName[] = {
"", ",1", ",2", ",3", ",4", ",Q", ",A", ",I"
};
char enhSkipType[] = {
'Z', 'N', 'P', 'M'
};
char enhSkipReg[] = {
'4', '1', '2', '3'
};
const char *enhMiscName0[] = {
"???", "LMM", "LRG", "SRG", "SIO", "SPS", "DMI", "CBP",
"GPE", "GPO", "ASC", "APM", "PM0", "PM1"
};
#define ENH_MAXMISC0 0xD
const char *enhMiscName1[] = {
"LUB", "LLB", "EMS", "WPR", "RPR", "ECC"
};
#define ENH_MAXMISC1 0x5
const char *enhFldName[] = {
"???", "???", "SFZ", "SFN", "LFA", "SFA", "CLF", "SEF"
};
/* /*
* Generate a single line of text for an instruction. Format is: * Generate a single line of text for an instruction. Format is:
* *
* c xxxx yyyy zzzz <instr> <targ> * c xxxx yyyy zzzz <instr> <targ>
* *
* or if enhanced instruction set is enabled
*
* c xxxx yyyy zzzz aaaa <instr> <targ>
*
* where: * where:
* *
* |P Normal/Protected location * |P Normal/Protected location
* xxxx Memory address of instruction in hex * xxxx Memory address of instruction in hex
* yyyy First word of instruction in hex * yyyy First word of instruction in hex
* zzzz Second word of inctruction in hex, replaced by spaces if * zzzz Second word of instruction in hex, replaced by spaces if
* not present
* aaaa Third word of instruction in hex, replaced by spaces if
* not present * not present
* <instr> Disassmbled instruction * <instr> Disassmbled instruction
* <targ> Optional target address and contents * <targ> Optional target address and contents
@ -99,14 +138,17 @@ int disassem(char *buf, uint16 addr, t_bool dbg, t_bool targ, t_bool exec)
{ {
int consumed = 1; int consumed = 1;
char prot = ISPROTECTED(addr) ? 'P' : ' '; char prot = ISPROTECTED(addr) ? 'P' : ' ';
char optional[8], temp[8], decoded[64]; char optional[8], optional2[8], temp[8], decoded[64], enhInstr[8];
const char *mode, *spc, *shift, *inter, *dest; const char *mode, *spc, *shift, *inter, *dest;
uint16 instr = LoadFromMem(addr); uint16 instr = LoadFromMem(addr);
uint16 instr2, enhMode;
uint16 delta = instr & OPC_ADDRMASK; uint16 delta = instr & OPC_ADDRMASK;
uint8 more = 0, isconst = 0; uint8 more = 0, isconst = 0, enhRB;
uint16 t; uint16 t;
t_bool enhValid = FALSE, enhChar = FALSE;
strcpy(optional, " "); strcpy(optional, " ");
strcpy(optional2, " ");
strcpy(decoded, "UNDEF"); strcpy(decoded, "UNDEF");
if ((instr & OPC_MASK) != 0) { if ((instr & OPC_MASK) != 0) {
@ -181,7 +223,228 @@ int disassem(char *buf, uint16 addr, t_bool dbg, t_bool targ, t_bool exec)
break; break;
case INSTR_ENHANCED: case INSTR_ENHANCED:
sprintf(decoded, "%s", delta != 0 ? "Enhanced" : spc); if (delta != 0) {
switch (instr & OPC_SPECIALMASK) {
case OPC_IIN:
if (((instr & OPC_FLDF3A) != OPC_FLDRSV1) &&
((instr & OPC_FLDF3A) != OPC_FLDRSV2)) {
instr2 = LoadFromMem(addr + 1);
delta = instr2 & OPC_ADDRMASK;
if (((instr2 & OPC_FLDSTR) - (instr2 & OPC_FLDLTH)) >= 0) {
consumed++;
if ((instr & MOD_ENHRE) == 0)
mode = delta == 0 ? "+ " : "- ";
else mode = "* ";
sprintf(optional, "%04X", instr2);
if (delta == 0) {
consumed++;
sprintf(optional2, "%04X", LoadFromMem(addr + 2));
sprintf(temp, "$%04X", LoadFromMem(addr + 2));
} else sprintf(temp, "$%02X", delta);
sprintf(decoded, "%s%s%s%s%s,%d,%d%s",
enhFldName[instr & OPC_FLDF3A],
mode,
(instr & MOD_ENHIN) != 0 ? "(" : "",
temp,
(instr & MOD_ENHIN) != 0 ? ")" : "",
(instr2 & OPC_FLDSTR) >> 12,
((instr2 & OPC_FLDLTH) >> 8) + 1,
enhIdxName[(instr & MOD_ENHRA) >> 3]);
break;
}
}
strcpy(decoded, "UNDEF");
targ = FALSE;
break;
case OPC_EIN:
instr2 = LoadFromMem(addr + 1);
enhMode = (instr2 & OPC_ENHF5) >> 8;
enhRB = instr & MOD_ENHRB;
switch (instr2 & OPC_ENHF4) {
case OPC_STOSJMP:
if (enhMode == 0) {
enhValid = TRUE;
if (enhRB == REG_NONE)
strcpy(enhInstr, "SJE");
else sprintf(enhInstr, "SJ%c", enhRegChar[enhRB]);
}
break;
case OPC_STOADD:
if ((enhMode == 0) && (enhRB != REG_NONE)) {
enhValid = TRUE;
sprintf(enhInstr, "AR%c", enhRegChar[enhRB]);
}
break;
case OPC_STOSUB:
if ((enhMode == 0) && (enhRB != REG_NONE)) {
enhValid = TRUE;
sprintf(enhInstr, "SB%c", enhRegChar[enhRB]);
}
break;
case OPC_STOAND:
if (enhRB != REG_NONE)
switch (enhMode) {
case WORD_REG:
enhValid = TRUE;
sprintf(enhInstr, "AN%c", enhRegChar[enhRB]);
break;
case WORD_MEM:
enhValid = TRUE;
sprintf(enhInstr, "AM%c", enhRegChar[enhRB]);
break;
}
break;
case OPC_STOLOADST:
switch (enhMode) {
case WORD_REG:
if (enhRB != REG_NONE) {
enhValid = TRUE;
sprintf(enhInstr, "LR%c", enhRegChar[enhRB]);
}
break;
case WORD_MEM:
if (enhRB != REG_NONE) {
enhValid = TRUE;
sprintf(enhInstr, "SR%c", enhRegChar[enhRB]);
}
break;
case CHAR_REG:
if (enhRB != REG_NONE) {
enhValid = TRUE;
enhChar = TRUE;
strcpy(enhInstr, "LCA");
}
break;
case CHAR_MEM:
if (enhRB != REG_NONE) {
enhValid = TRUE;
enhChar = TRUE;
strcpy(enhInstr, "SCA");
}
break;
}
break;
case OPC_STOOR:
if (enhRB != REG_NONE)
switch (enhMode) {
case WORD_REG:
enhValid = TRUE;
sprintf(enhInstr, "OR%c", enhRegChar[enhRB]);
break;
case WORD_MEM:
enhValid = TRUE;
sprintf(enhInstr, "OM%c", enhRegChar[enhRB]);
break;
}
break;
case OPC_STOCRE:
switch (enhMode) {
case WORD_REG:
if (enhRB != REG_NONE) {
enhValid = TRUE;
sprintf(enhInstr, "C%cE", enhRegChar[enhRB]);
}
break;
case CHAR_REG:
if (enhRB != REG_NONE) {
enhValid = TRUE;
enhChar = TRUE;
strcpy(enhInstr, "CCE");
}
break;
}
break;
}
if (enhValid) {
delta = instr2 & OPC_ADDRMASK;
consumed++;
if ((instr & MOD_ENHRE) == 0)
mode = delta == 0 ? "+ " : "- ";
else mode = "* ";
sprintf(optional, "%04X", instr2);
if (delta == 0) {
consumed++;
sprintf(optional2, "%04X", LoadFromMem(addr + 2));
sprintf(temp, "$%04X", LoadFromMem(addr + 2));
} else sprintf(temp, "$%02X", delta);
if (!enhChar) {
if ((delta == 0) &&
(instr & (MOD_ENHRE | MOD_ENHIN)) == 0)
isconst = 1;
sprintf(decoded, "%s%s%s%s%s%s%s",
enhInstr,
mode,
isconst ? "=" : "",
(instr & MOD_ENHIN) != 0 ? "(" : "",
temp,
(instr & MOD_ENHIN) != 0 ? ")" : "",
enhIdxName[(instr & MOD_ENHRA) >> 3]);
} else {
sprintf(decoded, "%s%s%s%s%s%s%s",
enhInstr,
mode,
(instr & MOD_ENHIN) != 0 ? "(" : "",
temp,
(instr & MOD_ENHIN) != 0 ? ")" : "",
enhIdxName[enhRB],
enhIdxName[(instr & MOD_ENHRA) >> 3]);
}
} else {
strcpy(decoded, "UNDEF");
targ = FALSE;
}
break;
case OPC_SPB:
if ((instr & OPC_DRPMBZ) == 0) {
char reg = enhRegChar[(instr & OPC_DRPRA) >> 5];
uint8 sk = instr & OPC_DRPSK;
sprintf(decoded, "D%cP $%1X", reg, sk);
break;
}
break;
case OPC_CPB:
if ((instr & OPC_ENHXFRF2A) == 0) {
if ((instr & (OPC_ENHXFRRA | OPC_ENHXFRRB)) != 0) {
char ra = enhRegChar[(instr & OPC_ENHXFRRA) >> 5];
char rb = enhRegChar[instr & OPC_ENHXFRRB];
sprintf(decoded, "XF%c %c", ra, rb);
break;
}
}
strcpy(decoded, "UNDEF");
targ = FALSE;
break;
}
} else {
sprintf(decoded, "%s", spc);
targ = FALSE;
}
break; break;
} }
break; break;
@ -199,7 +462,23 @@ int disassem(char *buf, uint16 addr, t_bool dbg, t_bool targ, t_bool exec)
break; break;
case INSTR_ENHANCED: case INSTR_ENHANCED:
sprintf(decoded, "%s", delta != 0 ? "Enhanced" : spc); if (delta != 0) {
uint8 miscFN = instr & OPC_MISCF3;
char reg = enhRegChar[(instr & OPC_MISCRA) >> 5];
targ = FALSE;
if ((instr & OPC_MISCRA) == 0) {
if (miscFN <= ENH_MAXMISC0)
spc = enhMiscName0[miscFN];
else spc = "UNDEF";
sprintf(decoded, "%s", spc);
} else {
if (miscFN <= ENH_MAXMISC1) {
spc = enhMiscName1[miscFN];
sprintf(decoded, "%s %c", spc, reg);
} else strcpy(decoded, "UNDEF");
}
} else sprintf(decoded, "%s", spc);
break; break;
} }
break; break;
@ -225,7 +504,13 @@ int disassem(char *buf, uint16 addr, t_bool dbg, t_bool targ, t_bool exec)
break; break;
case INSTR_ENHANCED: case INSTR_ENHANCED:
sprintf(decoded, "%s", "Enhanced"); {
char reg = enhSkipReg[(instr & OPC_ENHSKIPREG) >> 6];
char type = enhSkipType[(instr & OPC_ENHSKIPTY) >> 4];
uint8 sk = instr & OPC_ENHSKIPCNT;
sprintf(decoded, "S%c%c $%1X", reg, type, sk);
}
break; break;
} }
break; break;
@ -257,9 +542,17 @@ int disassem(char *buf, uint16 addr, t_bool dbg, t_bool targ, t_bool exec)
} }
if (dbg) { if (dbg) {
if (INSTR_SET == INSTR_ENHANCED)
sprintf(buf, "%c %04X %04X %s %s %s",
prot, addr, instr, optional, optional2, decoded);
else
sprintf(buf, "%c %04X %04X %s %s", sprintf(buf, "%c %04X %04X %s %s",
prot, addr, instr, optional, decoded); prot, addr, instr, optional, decoded);
} else { } else {
if (INSTR_SET == INSTR_ENHANCED)
sprintf(buf, "%c %04X %s %s %s",
prot, instr, optional, optional2, decoded);
else
sprintf(buf, "%c %04X %s %s", sprintf(buf, "%c %04X %s %s",
prot, instr, optional, decoded); prot, instr, optional, decoded);
} }
@ -350,6 +643,13 @@ int disassem(char *buf, uint16 addr, t_bool dbg, t_bool targ, t_bool exec)
case OPC_INP: case OPC_INP:
case OPC_OUT: case OPC_OUT:
taddr = doADDinternal(addr, EXTEND8(instr & OPC_MODMASK));
taddr2 = taddr;
if ((sim_switches & SWMASK('R')) != 0)
taddr2 -= RelBase;
more = 1;
break;
case OPC_EIN: case OPC_EIN:
case OPC_IIN: case OPC_IIN:
case OPC_INTER: case OPC_INTER:

View file

@ -231,7 +231,7 @@ t_stat dp_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE DPdev = IODEV(NULL, "1738-B", 1738, 3, 0xFF, 0, IO_DEVICE DPdev = IODEV(NULL, "1738-B", 1738, 3, 0xFF, 0,
DPreject, DPin, DPout, NULL, NULL, DPreject, DPin, DPout, NULL, NULL,
DPstate, DPintr, NULL, NULL, DPstate, DPintr, NULL, NULL, NULL, NULL,
0x7F, 8, 0x7F, 8,
MASK_REGISTER1 | MASK_REGISTER2 | MASK_REGISTER3 | \ MASK_REGISTER1 | MASK_REGISTER2 | MASK_REGISTER3 | \
MASK_REGISTER4 | MASK_REGISTER5 | MASK_REGISTER6 | \ MASK_REGISTER4 | MASK_REGISTER5 | MASK_REGISTER6 | \

967
CDC1700/cdc1700_drm.c Normal file
View file

@ -0,0 +1,967 @@
/*
Copyright (c) 2015-2017, 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_drm.c: drum memory controller
* Simh device: drm
*/
/*
* Notes:
*
* 1. The 1752 Drum Memory Subsystem consists of a 3600 RPM drum with 32
* sectors (96 words each) per track. There can be 64 - 1024 tracks
* depending on the model ordered.
*
* There is 1 readable register which needs to be handled specially - the
* Sector Address Status. This register consists of 3 fields:
*
* - Current sector address as read from the drum (0 - 31)
* - Current track address from last I/O request (zero on startup)
* - Core address compare - set if transfer is to last address of buffer
*
* The SMM17 diagnostic for the 1752 uses this register to verify that
* the hardware is operational before allowing the diagnostic to run. The
* register fields will be implemented as follows:
*
* 1. Current sector address
*
* Rather than use a repeating service routine, we will timestamp
* (using the instruction count) when the Sector Address Status register
* was last referenced or used as part of an I/O operation. When the
* register is next referenced, we will compute the number of sectors
* which have passed under the head (521 uSec/sector so 350 instructions
* assuming 1.5 microsecond/instruction) and update the sector address
* field appropriately. If an I/O is active, the sector address will
* reflect that used by the current I/O. This may result in a sudden
* change in value.
*
* 2. Current track address
*
* This will be the last track address referenced by an I/O request.
*
* 3. Core address compare
*
* This bit is set when the current/next DMA request is to the last
* address of the buffer. Rather than simulate DMA word at a time,
* we simulate sector transfer at a time. We will set this bit if the
* last address of the buffer is somewhere within the current sector
* and also set the Core Address Status to be the last address of
* the buffer.
*
* 2. This is the first, and only, device driver which requires dynamic
* processing of the Director Status Register. The Sector Compare is only
* set when the requested sector is under the read head. The I/O framework
* did not require any changes to allow this to work.
*/
#include "cdc1700_defs.h"
#define SASTATUS iod_readR[2]
#define CASTATUS iod_readR[3]
#define DATASTATUS iod_readR[4]
extern char INTprefix[];
extern void RaiseExternalInterrupt(DEVICE *);
extern t_bool doDirectorFunc(DEVICE *, t_bool);
extern t_bool fw_reject(IO_DEVICE *, t_bool, uint8);
extern void fw_IOunderwayEOP2(IO_DEVICE *, uint16);
extern void fw_IOcompleteEOP2(t_bool, DEVICE *, IO_DEVICE *, uint16, const char *);
extern void fw_IOalarm(t_bool, DEVICE *, IO_DEVICE *, const char *);
extern void fw_IOintr(t_bool, DEVICE *, IO_DEVICE *, uint16, uint16, uint16, const char *);
extern void rebuildPending(void);
extern t_stat show_addr(FILE *, UNIT *, int32, CONST 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 t_stat set_stoponrej(UNIT *, int32, CONST char *, void *);
extern t_stat clr_stoponrej(UNIT *, int32, CONST char *, void *);
extern uint16 LoadFromMem(uint16);
extern t_bool IOStoreToMem(uint16, uint16, t_bool);
extern uint16 M[], Areg, IOAreg;
extern t_uint64 Instructions;
extern t_bool IOFWinitialized;
extern UNIT cpu_unit;
t_stat drm_help(FILE *, DEVICE *, UNIT *, int32, const char *);
/* Constants */
#define DRM_NUMWD (96) /* words/sector */
#define DRM_NUMBY (DRM_NUMWD * sizeof(uint16))
#define DRM_NUMSC (32) /* sectors/track */
#define DRM_SIZE (512 * DRM_NUMSC * DRM_NUMBY)
#define DRM_MINTRACKS (64) /* Min # of tracks supported */
#define DRM_MAXTRACKS (1024) /* Max # of tracks supported */
#define DRM_AUTOLOAD (16) /* Sectors to autoload */
/*
* Drum address fields
*/
#define DRM_TRK_MASK 0x7FE0 /* Track address */
#define DRM_TRK_SHIFT 5 /* and shift */
#define DRM_SEC_MASK 0x001F /* Sector mask */
#define DRM_COMPARE 0x8000 /* Core address compare */
enum drmio_status {
DRMIO_MORE, /* More I/O pending */
DRMIO_DONE, /* I/O processing complete */
DRMIO_PROTECT, /* Protect fault */
DRMIO_ADDRERR /* Addressing error */
};
t_stat drm_svc(UNIT *);
t_stat drm_reset(DEVICE *);
t_stat drm_attach(UNIT *, CONST char *);
t_stat drm_detach(UNIT *);
t_stat drm_set_size(UNIT *, int32, CONST char *, void *);
void DRMstate(const char *, DEVICE *, IO_DEVICE *);
t_bool DRMreject(IO_DEVICE *, t_bool, uint8);
enum IOstatus DRMin(IO_DEVICE *, uint8);
enum IOstatus DRMout(IO_DEVICE *, uint8);
void DRMclear(DEVICE *);
uint8 DRMdecode(IO_DEVICE *, t_bool, uint8);
/*
1752-A/B/C/D Drum memory controller
Addresses
Computer Instruction
Q Register Output From A Input to A
(Bits 03-00)
0000 Initiate Write Op Illegal
0001 Director Function Director Status
0010 Illegal Sector Address Status
0011 Director Function Core Address Status
0100 Initiate Read Op Data Status
0101 Director Function Illegal
0110 Illegal Illegal
0111 Director Function Illegal
1000 Load ISA Illegal
1001 Director Function Illegal
1010 Illegal Illegal
1011 Director Function Illegal
1100 Load Initial Addr Illegal
1101 Director Function Illegal
1110 Load Final Addr Illegal
1111 Director Function Illegal
Operations:
Initiate Drum Write Operation
15 14 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Director Function
15 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X | X | X | X | X | X | X | X | X | | | X | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | |
| | | Clr Controller
| | Clr Interrupts
| EOP Interrupt Req.
Interrupt on Alarm
Initiate Drum Read Operation
15 14 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Load Initial Sector Address
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | |
+-----------------------------------+ +---------------+
Desired Initial Track Address Desired Initial
Sector Addr - 1
Load Initial Core Address, Load Final Core Address
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| |
+-----------------------------------------------------------+
Core Address
Status Response:
Director Status
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | Ready
| | | | | | | | | | | | | | Busy
| | | | | | | | | | | | | Interrupt
| | | | | | | | | | | | Data
| | | | | | | | | | | End of Operation
| | | | | | | | | | Alarm
| | | | | | | | | Lost Data
| | | | | | | | Protected
| | | | | | | Checkword Error
| | | | | | Protect Fault
| | | | | Guarded Address Enabled
| | | | Timing Track Error
| | | Power Failure
| | Sector Compare
| Guarded Address Error
Sector Overrange Error
Sector Address Status
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | |
| +-----------------------------------+ +---------------+
| Track Address Register Contents Sector Address
| Register Contents
Core Address Compare
Core Address Status
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| |
+-----------------------------------------------------------+
Core Address Register Contents
Data Status
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| |
+-----------------------------------------------------------+
Data Register Zero Contents
*/
IO_DEVICE DRMdev = IODEV(NULL, "1752", 1752, 2, 0xFF, 0,
DRMreject, DRMin, DRMout, NULL, NULL,
DRMstate, NULL, NULL, DRMclear, DRMdecode, NULL,
0x7F, 16,
MASK_REGISTER0 | MASK_REGISTER1 | MASK_REGISTER2 | \
MASK_REGISTER3 | MASK_REGISTER4 | MASK_REGISTER5 | \
MASK_REGISTER6 | MASK_REGISTER7 | MASK_REGISTER8 | \
MASK_REGISTER9 | MASK_REGISTER10 | MASK_REGISTER11 | \
MASK_REGISTER12 | MASK_REGISTER13 | \
MASK_REGISTER14 | MASK_REGISTER15,
MASK_REGISTER3 | MASK_REGISTER4,
MASK_REGISTER0 | MASK_REGISTER5 | MASK_REGISTER6 | \
MASK_REGISTER7 | MASK_REGISTER8 | MASK_REGISTER9 | \
MASK_REGISTER10 | MASK_REGISTER11 | \
MASK_REGISTER12 | MASK_REGISTER13 | \
MASK_REGISTER14 | MASK_REGISTER15,
MASK_REGISTER2 | MASK_REGISTER6 | MASK_REGISTER10,
0, 0, NULL);
/*
* Define usage for "private" IO_DEVICE data areas.
*/
#define iod_tracks iod_private /* # of tracks on device */
#define iod_compare iod_private4 /* TRUE if DMA of last buffer word */
#define iod_isa iod_private6 /* Initial sector address */
#define iod_ica iod_private7 /* Initial core address */
#define iod_fca iod_private8 /* Final core address */
#define iod_state iod_private9 /* Current controller state */
#define iod_ca iod_private11 /* Current DMA address */
#define iod_trk iod_private12 /* Current track # */
#define iod_sec iod_private13 /* Current sector # */
#define DRM_IDLE 0x00 /* Idle */
#define DRM_WRITE 0x01 /* Write data */
#define DRM_READ 0x02 /* Read data */
/* DRM data structures
drm_dev DRM device descriptor
drm_unit DRM unit descriptor
drm_reg DRM register list
drm_mod DRM modifier list
*/
UNIT drm_unit = {
UDATA(&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DRM_SIZE)
};
REG drm_reg[] = {
{ HRDATAD(FUNCTION, DRMdev.FUNCTION, 16, "Last director function issued") },
{ HRDATAD(STATUS, DRMdev.STATUS, 16, "Director status register") },
{ HRDATAD(IENABLE, DRMdev.IENABLE, 16, "Interrupts enabled") },
/*** more ***/
{ NULL }
};
MTAB drm_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, "1752 Drum Memory Controller" },
{ MTAB_XTD|MTAB_VDV, 0, "EQUIPMENT", "EQUIPMENT=hexAddress",
&set_equipment, &show_addr, NULL, "Set/Display equipment address" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "STOPONREJECT",
&set_stoponrej, NULL, NULL, "Stop simulation if I/O is rejected" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOSTOPONREJECT",
&clr_stoponrej, NULL, NULL, "Don't stop simulation if I/O is rejected" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "PROTECT",
&set_protected, NULL, NULL, "Device is protected (unimplemented)" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOPROTECT",
&clear_protected, NULL, NULL, "Device is unprotected (unimplemented)" },
{ UNIT_DRMSIZE, 64, NULL, "64",
&drm_set_size, NULL, NULL, "Set drum storage to 64 tracks" },
{ UNIT_DRMSIZE, 128, NULL, "128",
&drm_set_size, NULL, NULL, "Set drum storage to 128 tracks" },
{ UNIT_DRMSIZE, 192, NULL, "192",
&drm_set_size, NULL, NULL, "Set drum storage to 192 tracks" },
{ UNIT_DRMSIZE, 256, NULL, "256",
&drm_set_size, NULL, NULL, "Set drum storage to 256 tracks" },
{ UNIT_DRMSIZE, 320, NULL, "320",
&drm_set_size, NULL, NULL, "Set drum storage to 320 tracks" },
{ UNIT_DRMSIZE, 384, NULL, "384",
&drm_set_size, NULL, NULL, "Set drum storage to 384 tracks" },
{ UNIT_DRMSIZE, 448, NULL, "448",
&drm_set_size, NULL, NULL, "Set drum storage to 448 tracks" },
{ UNIT_DRMSIZE, 512, NULL, "512",
&drm_set_size, NULL, NULL, "Set drum storage to 512 tracks" },
{ UNIT_DRMSIZE, 576, NULL, "576",
&drm_set_size, NULL, NULL, "Set drum storage to 576 tracks" },
{ UNIT_DRMSIZE, 640, NULL, "640",
&drm_set_size, NULL, NULL, "Set drum storage to 640 tracks" },
{ UNIT_DRMSIZE, 704, NULL, "704",
&drm_set_size, NULL, NULL, "Set drum storage to 704 tracks" },
{ UNIT_DRMSIZE, 768, NULL, "768",
&drm_set_size, NULL, NULL, "Set drum storage to 768 tracks" },
{ UNIT_DRMSIZE, 832, NULL, "832",
&drm_set_size, NULL, NULL, "Set drum storage to 832 tracks" },
{ UNIT_DRMSIZE, 896, NULL, "896",
&drm_set_size, NULL, NULL, "Set drum storage to 896 tracks" },
{ UNIT_DRMSIZE, 960, NULL, "960",
&drm_set_size, NULL, NULL, "Set drum storage to 960 tracks" },
{ UNIT_DRMSIZE, 1024, NULL, "1024",
&drm_set_size, NULL, NULL, "Set drum storage to 1024 tracks" },
{ 0 }
};
DEBTAB drm_deb[] = {
{ "TRACE", DBG_DTRACE, "Trace device I/O requests" },
{ "STATE", DBG_DSTATE, "Display device state changes" },
{ "INTR", DBG_DINTR, "Display device interrupt requests" },
{ "ERROR", DBG_DERROR, "Display device errors" },
{ "LOCATION", DBG_DLOC, "Display address for I/O instructions" },
{ "FIRSTREJ", DBG_DFIRSTREJ, "Suppress display of 2nd ... I/O rejects" },
{ "ALL", DBG_DTRACE | DBG_DSTATE | DBG_DINTR | DBG_DERROR | DBG_DLOC },
{ NULL }
};
DEVICE drm_dev = {
"DRM", &drm_unit, drm_reg, drm_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &drm_reset,
NULL, &drm_attach, &drm_detach,
&DRMdev,
DEV_DEBUG | DEV_DISK | DEV_DISABLE | DEV_INDEV | DEV_OUTDEV | DEV_PROTECT,
0, drm_deb,
NULL, NULL, &drm_help, NULL, NULL, NULL
};
/*
* Dump the current internal state of the DRM device.
*/
const char *DRMStateStr[] = {
"Idle", "Write", "Read"
};
void DRMstate(const char *where, DEVICE *dev, IO_DEVICE *iod)
{
fprintf(DBGOUT,
"%s[%s %s: %s, Func: %04X, Sta: %04X, Ena: %04X]\r\n",
INTprefix, dev->name, where, DRMStateStr[iod->iod_state],
iod->FUNCTION, iod->STATUS, iod->IENABLE);
fprintf(DBGOUT,
"%s[%s: ISA: %04X, ICA: %04X, FCA: %04X, SAS: %04X, CAS: %04X]\r\n",
INTprefix, dev->name,
iod->iod_isa, iod->iod_ica, iod->iod_fca,
iod->SASTATUS, iod->CASTATUS);
fprintf(DBGOUT,
"%s[%s: Trk: %03X, Sec: %02X, Cur: %04X, Comp: %c]\r\n",
INTprefix, dev->name, iod->iod_trk, iod->iod_sec, iod->iod_ca,
iod->iod_compare ? 'T' : 'F');
}
/*
* Load and validate drum address in the Initial Sector Address Register
*/
static t_bool LoadDrumAddress(void)
{
uint16 track = (DRMdev.iod_isa & DRM_TRK_MASK) >> DRM_TRK_SHIFT;
if (track >= DRMdev.iod_tracks)
return FALSE;
/*
* The sector field initially holds (sector # - 1) and needs to be
* incremented without touching the track #.
*/
DRMdev.iod_trk = track;
DRMdev.iod_sec = (DRMdev.iod_isa + 1) & DRM_SEC_MASK;
return TRUE;
}
/*
* Set up a drum I/O operation using the currently set parameters
*/
static void StartDrumIO(t_bool wr)
{
if (LoadDrumAddress()) {
DRMdev.iod_compare =(DRMdev.iod_fca >= DRMdev.CASTATUS) &&
(DRMdev.iod_fca < (DRMdev.CASTATUS + DRM_NUMWD));
DRMdev.iod_ca = DRMdev.iod_ica;
DRMdev.CASTATUS = DRMdev.iod_compare ? DRMdev.iod_ica : DRMdev.iod_fca;
fw_IOunderwayEOP2(&DRMdev, IO_ST_DATA);
if ((drm_dev.dctrl & DBG_DTRACE) != 0) {
fprintf(DBGOUT,
"%sDRM - Start %s I/O, Trk: %03X, Sec: %02X, Start: %04X, End: %04X\r\n",
INTprefix, wr ? "Write" : "Read",
DRMdev.iod_trk, DRMdev.iod_sec, DRMdev.iod_ica, DRMdev.iod_fca);
}
DRMdev.iod_state = wr ? DRM_WRITE : DRM_READ;
sim_activate(&drm_unit, DRM_ACCESS_WAIT);
return;
}
/*
* Generate a sector overrange error and possible interrupt.
*/
DRMdev.STATUS &= ~IO_ST_DATA;
DRMdev.STATUS |= IO_1752_OVERR;
fw_IOalarm(FALSE, &drm_dev, &DRMdev, "Invalid track #");
}
/*
* Increment the drum sector address.
*/
static void DrumIOIncSector(void)
{
DRMdev.iod_sec = (DRMdev.iod_sec + 1) & DRM_SEC_MASK;
if (DRMdev.iod_sec == 0)
DRMdev.iod_trk++;
}
/*
* Initiate a read operation on the drum.
*/
static enum drmio_status DrumIORead(UNIT *uptr)
{
uint16 buf[DRM_NUMWD];
uint32 lba = (DRMdev.iod_trk << DRM_TRK_SHIFT) | DRMdev.iod_sec;
int i;
if (DRMdev.iod_trk >= DRMdev.iod_tracks)
return DRMIO_ADDRERR;
/*
* Report any error in the underlying container infrastructure as an
* address error.
*/
if (sim_fseeko(uptr->fileref, lba * DRM_NUMBY, SEEK_SET) ||
(sim_fread(buf, sizeof(uint16), DRM_NUMWD, uptr->fileref) != DRM_NUMWD))
return DRMIO_ADDRERR;
for (i = 0; i < DRM_NUMWD; i++) {
/*** TODO: fix protect check ***/
if (!IOStoreToMem(DRMdev.iod_ca, buf[i], TRUE))
return DRMIO_PROTECT;
DRMdev.DATASTATUS = buf[i];
if (DRMdev.iod_ca++ == DRMdev.iod_fca) {
DRMdev.CASTATUS = DRMdev.iod_ca;
DrumIOIncSector();
return DRMIO_DONE;
}
}
DrumIOIncSector();
if ((drm_dev.dctrl & DBG_DTRACE) != 0)
fprintf(DBGOUT,
"%sDRM - Continue Read I/O, Trk: %03X, Sec: %02X, Cur: %04X, End: %04X\r\n",
INTprefix, DRMdev.iod_trk, DRMdev.iod_sec,
DRMdev.iod_ca, DRMdev.iod_fca);
return DRMIO_MORE;
}
/*
* Initiate a write operation on the drum.
*/
static enum drmio_status DrumIOWrite(UNIT *uptr)
{
uint16 buf[DRM_NUMWD];
uint32 lba = (DRMdev.iod_trk << DRM_TRK_SHIFT) | DRMdev.iod_sec;
t_bool done = FALSE;
int i;
if (DRMdev.iod_trk >= DRMdev.iod_tracks)
return DRMIO_ADDRERR;
memset(buf, 0, sizeof(buf));
for (i = 0; i < DRM_NUMWD; i++) {
DRMdev.DATASTATUS = buf[i] = LoadFromMem(DRMdev.iod_ca);
if (DRMdev.iod_ca++ == DRMdev.iod_fca) {
DRMdev.CASTATUS = DRMdev.iod_ca;
done = TRUE;
break;
}
}
/*
* Report any error in the underlying container infrastructure as an
* address error.
*/
if (sim_fseeko(uptr->fileref, lba * DRM_NUMBY, SEEK_SET) ||
(sim_fwrite(buf, sizeof(uint16), DRM_NUMWD, uptr->fileref) != DRM_NUMWD))
return DRMIO_ADDRERR;
DrumIOIncSector();
if (((drm_dev.dctrl & DBG_DTRACE) != 0) && !done)
fprintf(DBGOUT,
"%sDRM - Continue Write I/O, Trk: %03X, Sec: %02X, Cur: %04X, End: %04X\r\n",
INTprefix, DRMdev.iod_trk, DRMdev.iod_sec,
DRMdev.iod_ca, DRMdev.iod_fca);
return done ? DRMIO_DONE : DRMIO_MORE;
}
/*
* Perform read/write sector operations from within the unit service routine.
*/
void DrumIO(UNIT *uptr, uint8 iotype)
{
const char *error = "Unknown";
enum drmio_status status = DRMIO_ADDRERR;
switch (iotype) {
case DRM_WRITE:
status = DrumIOWrite(uptr);
break;
case DRM_READ:
status = DrumIORead(uptr);
break;
}
/*
* Update the sector address status register if the I/O was successful.
* Note that since we perform sector at a time I/O, we assert the "Core
* Address Compare" bit for the entire period.
*/
if ((status == DRMIO_MORE) || (status == DRMIO_DONE)) {
DRMdev.iod_compare =(DRMdev.iod_fca >= DRMdev.iod_ca) &&
(DRMdev.iod_fca < (DRMdev.iod_ca + DRM_NUMWD));
}
switch (status) {
case DRMIO_MORE:
sim_activate(uptr, DRM_SECTOR_WAIT);
break;
case DRMIO_PROTECT:
DRMdev.STATUS |= IO_1752_PROTF;
error = "Protection Fault";
goto err;
case DRMIO_ADDRERR:
DRMdev.STATUS |= IO_1752_OVERR;
error = "Address Error";
err:
DRMdev.iod_compare = FALSE;
DRMdev.iod_state = DRM_IDLE;
if ((drm_dev.dctrl & DBG_DERROR) != 0)
fprintf(DBGOUT,
"%sDRM - Read/Write failed - %s\r\n",
INTprefix, error);
fw_IOalarm(FALSE, &drm_dev, &DRMdev, "Alarm");
break;
case DRMIO_DONE:
DRMdev.iod_compare = FALSE;
DRMdev.iod_event = Instructions;
DRMdev.iod_state = DRM_IDLE;
if ((drm_dev.dctrl & DBG_DTRACE) != 0)
fprintf(DBGOUT,
"%sDRM - Read/Write transfer complete\r\n", INTprefix);
DRMdev.STATUS |= IO_ST_DATA;
fw_IOcompleteEOP2(FALSE, &drm_dev, &DRMdev, 0xFFFF, "Transfer complete");
break;
}
}
/* Unit service */
t_stat drm_svc(UNIT *uptr)
{
if ((drm_dev.dctrl & DBG_DTRACE) != 0) {
fprintf(DBGOUT, "%s[DRM: drm_svc() entry]\r\n", INTprefix);
if ((drm_dev.dctrl & DBG_DSTATE) != 0)
DRMstate("svc_entry", &drm_dev, &DRMdev);
}
switch (DRMdev.iod_state) {
case DRM_IDLE:
/*
* Unit is idle, nothing to do.
*/
break;
case DRM_WRITE:
case DRM_READ:
DrumIO(uptr, DRMdev.iod_state);
break;
}
if ((drm_dev.dctrl & DBG_DTRACE) != 0) {
fprintf(DBGOUT, "%s[DRM: drm_svc() exit]\r\n", INTprefix);
if ((drm_dev.dctrl & DBG_DSTATE) != 0)
DRMstate("svc_exit", &drm_dev, &DRMdev);
}
return SCPE_OK;
}
/* Reset routine */
t_stat drm_reset(DEVICE *dptr)
{
DRMdev.STATUS = 0;
if ((drm_unit.flags & UNIT_ATT) != 0)
DRMdev.STATUS |= IO_ST_READY | IO_ST_DATA;
DRMdev.SASTATUS =
DRMdev.CASTATUS =
DRMdev.DATASTATUS = 0;
DRMdev.iod_trk =
DRMdev.iod_sec = 0;
DRMdev.iod_event = Instructions;
return SCPE_OK;
}
/* Attach routine */
t_stat drm_attach (UNIT *uptr, CONST char *cptr)
{
t_addr capac = uptr->capac;
t_stat r;
uint16 tracks;
r = attach_unit(uptr, cptr);
if (r != SCPE_OK)
return r;
/*
* If this ia a newly created file, set the drum size appropriately.
*/
if (sim_fsize_ex(uptr->fileref) == 0)
sim_set_fsize(uptr->fileref, capac);
/*
* If we are attaching to an existing file, make sure that its size:
*
* - is a multiple of 3072 words
* - is between 64 and 1024 tracks (each of 3072 words)
* - is a multiple of 64 tracks
*/
tracks = sim_fsize_ex(uptr->fileref) / (DRM_NUMSC * DRM_NUMBY);
if (((sim_fsize_ex(uptr->fileref) % (DRM_NUMSC * DRM_NUMBY)) != 0) ||
(tracks < DRM_MINTRACKS) ||
(tracks > DRM_MAXTRACKS) ||
((tracks & (DRM_MINTRACKS - 1)) != 0)) {
detach_unit(uptr);
uptr->capac = capac;
return sim_messagef(SCPE_OPENERR, "Invalid file size");
}
DRMdev.STATUS = IO_ST_READY | IO_ST_DATA;
DRMdev.iod_tracks = tracks;
DRMdev.iod_event = Instructions;
return SCPE_OK;
}
/* Detach routine */
t_stat drm_detach(UNIT *uptr)
{
sim_cancel(uptr);
DRMdev.STATUS &= ~(IO_ST_READY | IO_ST_DATA);
return detach_unit(uptr);
}
/*
* Change drum capacity
*/
t_stat drm_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if ((uptr->flags & UNIT_ATT) != 0)
return SCPE_ALATT;
drm_unit.capac = val * DRM_NUMSC * DRM_NUMBY;
DRMdev.iod_tracks = val;
return SCPE_OK;
}
/* Check if I/O should be rejected */
t_bool DRMreject(IO_DEVICE *iod, t_bool output, uint8 reg)
{
if (output) {
if (reg != 0x1)
return (DRMdev.STATUS & IO_ST_BUSY) != 0;
}
return FALSE;
}
/* Perform I/O */
enum IOstatus DRMin(IO_DEVICE *iod, uint8 reg)
{
/*
* The I/O framework passes input requests for the Director Status register
* and the Sector Address Status register so that we can return values
* which are dependent on the rotational position of the drum.
*/
/*
* Update the current sector value.
*/
if (DRMdev.iod_state == DRM_IDLE) {
t_uint64 sectors = (Instructions - DRMdev.iod_event) / DRM_SECTOR_WAIT;
if (sectors != 0) {
DRMdev.iod_sec = (DRMdev.iod_sec + sectors) & DRM_SEC_MASK;
DRMdev.iod_event += sectors * DRM_SECTOR_WAIT;
}
}
switch (reg) {
case 0x01:
/*
* Director Status
*/
if (DRMdev.iod_sec == (DRMdev.iod_isa & DRM_SEC_MASK))
DRMdev.STATUS |= IO_1752_SECCMP;
else DRMdev.STATUS &= ~IO_1752_SECCMP;
Areg = DRMdev.STATUS;
return IO_REPLY;
case 0x02:
/*
* Sector Address Status
*/
DRMdev.SASTATUS = (DRMdev.iod_trk << DRM_TRK_SHIFT) | DRMdev.iod_sec;
if (DRMdev.iod_compare)
DRMdev.SASTATUS |= DRM_COMPARE;
Areg = DRMdev.SASTATUS;
return IO_REPLY;
}
return IO_REJECT;
}
enum IOstatus DRMout(IO_DEVICE *iod, uint8 reg)
{
switch (reg) {
case 0x00:
/*
* Initiate Drum Write Operation
*/
StartDrumIO(TRUE);
break;
case 0x01:
/*
* Director function.
*/
doDirectorFunc(&drm_dev, FALSE);
break;
case 0x04:
/*
* Initiate Drum Read Operation
*/
StartDrumIO(FALSE);
break;
case 0x08:
/*
* Load Initial Sector Address Register.
*/
DRMdev.iod_isa = IOAreg;
DRMdev.iod_trk = (IOAreg & DRM_TRK_MASK) >> DRM_TRK_SHIFT;
break;
case 0x0C:
/*
* Load Initial Core Address Register
*/
DRMdev.iod_ica = DRMdev.CASTATUS = IOAreg;
DRMdev.iod_compare = DRMdev.iod_ica == DRMdev.iod_fca;
break;
case 0x0E:
/*
* Load Final Core Address Register
*/
DRMdev.iod_fca = IOAreg;
DRMdev.iod_compare = DRMdev.iod_ica == DRMdev.iod_fca;
break;
}
/*
* Any non-rejected output clears EOP interrupt.
*/
if ((DRMdev.STATUS & IO_ST_EOP) != 0)
DRMdev.STATUS &= ~(IO_ST_INT | IO_ST_EOP);
rebuildPending();
return IO_REPLY;
}
/*
* Device clear routine. Clear controller operation from a director
* function - same as device reset but don't clear CASTATUS and DATASTATUS
*/
void DRMclear(DEVICE *dptr)
{
DRMdev.STATUS = 0;
if ((drm_unit.flags & UNIT_ATT) != 0)
DRMdev.STATUS |= IO_ST_READY | IO_ST_DATA;
DRMdev.SASTATUS = 0;
DRMdev.iod_trk =
DRMdev.iod_sec = 0;
DRMdev.iod_event = Instructions;
}
/*
* Address decode routine. If bit 0 of an output register address is set,
* clear bits 1 - 7 since they are ignored.
*/
uint8 DRMdecode(IO_DEVICE *iod, t_bool output, uint8 reg)
{
if (output && ((reg & 0x01) != 0))
reg &= 0x01;
return reg;
}
/*
* Autoload support
*/
t_stat DRMautoload(void)
{
UNIT *uptr = &drm_unit;
if ((uptr->flags & UNIT_ATT) != 0) {
uint32 i;
for (i = 0; i < DRM_AUTOLOAD; i++) {
t_offset offset = i * DRM_NUMBY;
void *buf = &M[i * DRM_NUMBY];
if (sim_fseeko(uptr->fileref, offset, SEEK_SET) ||
(sim_fread(buf, sizeof(uint16), DRM_NUMWD, uptr->fileref) != DRM_NUMWD))
return SCPE_IOERR;
}
return SCPE_OK;
}
return SCPE_UNATT;
}
t_stat drm_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
const char helpString[] =
/****************************************************************************/
" The %D device is a 1752 drum memory controller.\n"
"1 Hardware Description\n"
" The 1752-1/2/3/4 consists of a controller and field expandable drum\n"
" storage from 196608 to 1572864 words. A custom order may provide\n"
" additional storage up to 3145728 words.\n"
"2 Equipment Address\n"
" Drum controllers are typically set to equipment address 2. This address\n"
" may be changed by:\n\n"
"+sim> SET %D EQUIPMENT=hexValue\n\n"
"2 $Registers\n"
"\n"
" These registers contain the emulated state of the device. These values\n"
" don't necessarily relate to any detail of the original device being\n"
" emulated but are merely internal details of the emulation. STATUS always\n"
" contains the current status of the device as it would be read by an\n"
" application program.\n"
"1 Configuration\n"
" A %D device is configured with various simh SET and ATTACH commands\n"
"2 $Set commands\n";
return scp_help(st, dptr, uptr, flag, helpString, cptr);
}

View file

@ -49,7 +49,7 @@ extern t_bool FirstRejSeen;
extern uint32 CountRejects; extern uint32 CountRejects;
extern DEVICE cpu_dev, dca_dev, dcb_dev, dcc_dev, tti_dev, tto_dev, extern DEVICE cpu_dev, dca_dev, dcb_dev, dcc_dev, tti_dev, tto_dev,
ptr_dev, ptp_dev, cdr_dev; ptr_dev, ptp_dev;
static const char *status[] = { static const char *status[] = {
"REPLY", "REJECT", "INTERNALREJECT" "REPLY", "REJECT", "INTERNALREJECT"
@ -326,7 +326,7 @@ enum IOstatus doIO(t_bool output, DEVICE **device)
* 001 - 1711/1712/1713 teletypewriter * 001 - 1711/1712/1713 teletypewriter
* 010 - 1721/1722 paper tape reader * 010 - 1721/1722 paper tape reader
* 100 - 1723/1724 paper tape punch * 100 - 1723/1724 paper tape punch
* 110 - 1729 card reader * 110 - 1729 card reader (not implemented on device address 1)
*/ */
switch ((IOQreg >> 4) & 0x7) { switch ((IOQreg >> 4) & 0x7) {
case 0x01: case 0x01:
@ -341,10 +341,6 @@ enum IOstatus doIO(t_bool output, DEVICE **device)
dev = &ptp_dev; dev = &ptp_dev;
break; break;
case 0x06:
dev = &cdr_dev;
break;
default: default:
return IO_INTERNALREJECT; return IO_INTERNALREJECT;
} }

View file

@ -46,7 +46,7 @@ t_bool IOFWinitialized = FALSE;
/* /*
* This I/O framework provides an implementation of a generic device. The * 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 * framework provides for up to 16 read and 16 write device registers. The
* read device registers may be stored and read directly from the framework * 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 * 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 * driver. The framework may be setup to dynamically reject I/O requests
@ -110,6 +110,10 @@ t_bool IOFWinitialized = FALSE;
* interrupt handling * interrupt handling
* void (*iod_clear)(DEVICE *); * void (*iod_clear)(DEVICE *);
* - Perform clear controller operation * - Perform clear controller operation
* uint8 (*iod_decode)(DEVICE *, t_bool, uint8);
* - Non-std device register decode
* t_bool (*iod_chksta)(t_bool, uint8);
* - Check for valid station address(es)
* uint16 iod_ienable; - Device interrupt enables * uint16 iod_ienable; - Device interrupt enables
* uint16 iod_oldienable; - Previous iod_ienable * uint16 iod_oldienable; - Previous iod_ienable
* uint16 iod_imask; - Valid device interrupts * uint16 iod_imask; - Valid device interrupts
@ -119,10 +123,10 @@ t_bool IOFWinitialized = FALSE;
* "clear interrupts" * "clear interrupts"
* uint16 iod_rmask; - Register mask (vs. station addr) * uint16 iod_rmask; - Register mask (vs. station addr)
* uint8 iod_regs; - # of device registers * uint8 iod_regs; - # of device registers
* uint8 iod_validmask; - Bitmap of valid registers * uint16 iod_validmask; - Bitmap of valid registers
* uint8 iod_readmap; - Bitmap of read registers * uint16 iod_readmap; - Bitmap of read registers
* uint8 iod_rejmapR; - Bitmaps of register R/W * uint16 iod_rejmapR; - Bitmaps of register R/W
* uint8 iod_rejmapW; access to be rejected * uint16 iod_rejmapW; access to be rejected
* uint8 iod_flags; - Device flags * uint8 iod_flags; - Device flags
* #define STATUS_ZERO 0x01 - Status register read returns 0 * #define STATUS_ZERO 0x01 - Status register read returns 0
* #define DEVICE_DC 0x02 - Device is buffered data channel * #define DEVICE_DC 0x02 - Device is buffered data channel
@ -143,6 +147,10 @@ t_bool IOFWinitialized = FALSE;
* uint16 iod_private8; - Device-specific use * uint16 iod_private8; - Device-specific use
* uint8 iod_private9; - Device-specific use * uint8 iod_private9; - Device-specific use
* t_bool iod_private10; - Device-specific use * t_bool iod_private10; - Device-specific use
* uint16 iod_private11; - Device-specific use
* uint16 iod_private12; - Device-specific use
* uint8 iod_private13; - Device-specific use
* uint8 iod_private14; - Device-specific use
* *
* The macro CHANGED(iod, n) will return what bits have been changed in write * The macro CHANGED(iod, n) will return what bits have been changed in write
* register 'n' just after it has been written. * register 'n' just after it has been written.
@ -193,13 +201,28 @@ void fw_init(void)
enum IOstatus fw_doIO(DEVICE *dptr, t_bool output) enum IOstatus fw_doIO(DEVICE *dptr, t_bool output)
{ {
IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt; IO_DEVICE *iod = (IO_DEVICE *)dptr->ctxt;
uint8 rej = (output ? iod->iod_rejmapW : iod->iod_rejmapR) & ~MASK_REGISTER1; uint16 rej = (output ? iod->iod_rejmapW : iod->iod_rejmapR) & ~MASK_REGISTER1;
uint8 reg; uint8 reg;
if ((iod->iod_flags & DEVICE_DC) != 0) if ((iod->iod_flags & DEVICE_DC) != 0)
reg = ((IOQreg & IO_W) - iod->iod_dcbase) >> 11; reg = ((IOQreg & IO_W) - iod->iod_dcbase) >> 11;
else reg = IOQreg & iod->iod_rmask; else reg = IOQreg & iod->iod_rmask;
/*
* Check for special station address handling for this device.
*/
if (iod->iod_chksta != NULL)
if (!(*iod->iod_chksta)(output, reg))
return IO_INTERNALREJECT;
/*
* Handle non-standard register decoding. E.g. For the 1752 drum controller,
* if bit 0 of the equipment address is set, bits 1 - 3 are ignored so all
* odd addresses map to "Director Function".
*/
if (iod->iod_decode != NULL)
reg = (*iod->iod_decode)(iod, output, reg);
/* /*
* Check for valid device address * Check for valid device address
*/ */
@ -298,7 +321,7 @@ enum IOstatus fw_doBDCIO(IO_DEVICE *iod, uint16 *data, t_bool output, uint8 reg)
* must make sure that the active interrupt flag is set whenever one or more * 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. * interrupt source is active and the interrupt(s) have been enabled.
* Interrupts are typically generated when a status flag is raised but we also * 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. * need to handle removing an interrupt source when a flag is dropped.
* *
* In addition, some devices have non-standard interrupts and we need to * In addition, some devices have non-standard interrupts and we need to
* provide a callback to a device-specific routine to check for such * provide a callback to a device-specific routine to check for such

View file

@ -182,7 +182,7 @@ t_stat lp_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE LPdev = IODEV(NULL, "Line Printer", 1740, 4, 0xFF, 0, IO_DEVICE LPdev = IODEV(NULL, "Line Printer", 1740, 4, 0xFF, 0,
fw_reject, LPin, LPout, NULL, NULL, fw_reject, LPin, LPout, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0x7F, 4, 0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | MASK_REGISTER3, MASK_REGISTER0 | MASK_REGISTER1 | MASK_REGISTER3,
MASK_REGISTER1, MASK_REGISTER1,
@ -215,7 +215,7 @@ IO_DEVICE LPdev = IODEV(NULL, "Line Printer", 1740, 4, 0xFF, 0,
*/ */
UNIT lp_unit = { UNIT lp_unit = {
UDATA(&lp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), LP_OUT_WAIT UDATA(&lp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), LP_OUT_WAIT
}; };
REG lp_reg_1740[] = { REG lp_reg_1740[] = {
@ -326,10 +326,12 @@ const char *LPprivateState[4] = {
void LPstate(const char *where, DEVICE *dev, IO_DEVICE *iod) void LPstate(const char *where, DEVICE *dev, IO_DEVICE *iod)
{ {
fprintf(DBGOUT, fprintf(DBGOUT,
"%s[%s %s: Func: %04X, Func2: %04X, Sta: %04X, Ena: %04x, Count: %d, \ "%s[%s %s: Func: %04X, Func2: %04X, Sta: %04X, Ena: %04x]\r\n",
Private: %s%s\r\n", INTprefix, dev->name, where,
iod->FUNCTION, iod->FUNCTION2, iod->STATUS, iod->IENABLE);
fprintf(DBGOUT,
"%s[%s %s: Count: %d, Private: %s%s\r\n",
INTprefix, dev->name, where, INTprefix, dev->name, where,
iod->FUNCTION, iod->FUNCTION2, iod->STATUS, iod->IENABLE,
iod->iod_LPcolumn, iod->iod_LPcolumn,
LPprivateState[iod->iod_LPstate], LPprivateState[iod->iod_LPstate],
iod->iod_LPoverwrite ? ",Overwrite" : ""); iod->iod_LPoverwrite ? ",Overwrite" : "");
@ -391,12 +393,36 @@ t_stat lp_svc(UNIT *uptr)
return SCPE_OK; return SCPE_OK;
} }
/* I/O routines */
static void lp_puts(char *s)
{
if (fputs(s, lp_unit.fileref) == EOF) {
perror("LP I/O error (puts)");
clearerr(lp_unit.fileref);
return;
}
lp_unit.pos += strlen(s);
}
static void lp_putc(uint8 ch)
{
if (putc(ch, lp_unit.fileref) == EOF) {
perror("LP I/O error (putc)");
clearerr(lp_unit.fileref);
return;
}
lp_unit.pos++;
}
/* Reset routine */ /* Reset routine */
t_stat lp_reset(DEVICE *dptr) t_stat lp_reset(DEVICE *dptr)
{ {
t_stat r; t_stat r;
if ((lp_dev.dctrl & DBG_TRACE) != 0)
fprintf(DBGOUT, "%s[LP: lp_reset() entry]\r\n", INTprefix);
if (LPdev.iod_type == IOtype_default) { if (LPdev.iod_type == IOtype_default) {
/* /*
* Setup the default device type. * Setup the default device type.
@ -408,8 +434,11 @@ t_stat lp_reset(DEVICE *dptr)
if (IOFWinitialized) if (IOFWinitialized)
if ((dptr->flags & DEV_DIS) == 0) if ((dptr->flags & DEV_DIS) == 0)
if ((r = checkReset(dptr, LPdev.iod_equip)) != SCPE_OK) if ((r = checkReset(dptr, LPdev.iod_equip)) != SCPE_OK) {
if ((lp_dev.dctrl & DBG_TRACE) != 0)
fprintf(DBGOUT, "%s[LP: lp_reset() disabled]\r\n", INTprefix);
return r; return r;
}
DEVRESET(&LPdev); DEVRESET(&LPdev);
@ -421,6 +450,9 @@ t_stat lp_reset(DEVICE *dptr)
LPdev.STATUS |= IO_ST_DATA | IO_ST_EOP; LPdev.STATUS |= IO_ST_DATA | IO_ST_EOP;
if ((lp_dev.dctrl & DBG_TRACE) != 0)
fprintf(DBGOUT, "%s[LP: lp_reset() exit]\r\n", INTprefix);
return SCPE_OK; return SCPE_OK;
} }
@ -511,12 +543,9 @@ enum IOstatus LPout(IO_DEVICE *iod, uint8 reg)
/*** TODO: implement format tape decoding ***/ /*** TODO: implement format tape decoding ***/
} }
if ((lp_unit.flags & UNIT_ATT) != 0) { if ((lp_unit.flags & UNIT_ATT) != 0)
if (fputs(ccontrol, lp_unit.fileref) == EOF) { lp_puts((char *)ccontrol);
perror("LP I/O error");
clearerr(lp_unit.fileref);
}
}
fw_IOunderwayData(&LPdev, 0); fw_IOunderwayData(&LPdev, 0);
LPdev.iod_LPstate = IODP_LPCCWAIT; LPdev.iod_LPstate = IODP_LPCCWAIT;
@ -567,12 +596,8 @@ enum IOstatus LPout(IO_DEVICE *iod, uint8 reg)
if ((lp_unit.flags & UNIT_ATT) != 0) { if ((lp_unit.flags & UNIT_ATT) != 0) {
int i; int i;
for (i = 0; i < iod->iod_LPcolumn; i++) { for (i = 0; i < iod->iod_LPcolumn; i++)
if (putc(buffer[i], lp_unit.fileref) == EOF) { lp_putc(buffer[i]);
perror("LP I/O error");
clearerr(lp_unit.fileref);
}
}
} }
} }
fw_IOunderwayEOP(&LPdev, IO_ST_INT); fw_IOunderwayEOP(&LPdev, IO_ST_INT);
@ -597,19 +622,12 @@ enum IOstatus LPout(IO_DEVICE *iod, uint8 reg)
if ((lp_unit.flags & UNIT_ATT) != 0) { if ((lp_unit.flags & UNIT_ATT) != 0) {
int i; int i;
if (iod->iod_LPoverwrite) { if (iod->iod_LPoverwrite)
if (putc('\r', lp_unit.fileref) == EOF) { lp_putc('\r');
perror("LP I/O error");
clearerr(lp_unit.fileref); for (i = 0; i < iod->iod_LPcolumn; i++)
} lp_putc(buffer[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);
}
}
iod->iod_LPoverwrite = TRUE; iod->iod_LPoverwrite = TRUE;
} }
} }
@ -620,16 +638,10 @@ enum IOstatus LPout(IO_DEVICE *iod, uint8 reg)
/*** TODO: Implement format tape operations. /*** TODO: Implement format tape operations.
For now, all operations generate a single space motion ***/ For now, all operations generate a single space motion ***/
if ((lp_unit.flags & UNIT_ATT) != 0) { if ((lp_unit.flags & UNIT_ATT) != 0) {
if (putc('\n', lp_unit.fileref) == EOF) { lp_putc('\n');
perror("LP I/O error");
clearerr(lp_unit.fileref); if ((Areg & IO_1740_DSP) != 0)
} lp_putc('\n');
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; iod->iod_LPoverwrite = FALSE;
printwait = TRUE; printwait = TRUE;

View file

@ -127,6 +127,8 @@ extern t_bool IOFWinitialized;
extern UNIT cpu_unit; extern UNIT cpu_unit;
t_stat mt_show_transport(FILE *, UNIT *, int32, CONST void *); t_stat mt_show_transport(FILE *, UNIT *, int32, CONST void *);
t_stat mt_set_9track(UNIT *, int32, CONST char *, void *);
t_stat mt_set_7track(UNIT *, int32, CONST char *, void *);
t_stat mt_show_type(FILE *, UNIT *, int32, CONST void *); t_stat mt_show_type(FILE *, UNIT *, int32, CONST void *);
t_stat mt_set_type(UNIT *, int32, CONST char *, void *); t_stat mt_set_type(UNIT *, int32, CONST char *, void *);
@ -352,7 +354,7 @@ t_stat mt_help(FILE *, DEVICE *, UNIT *, int32, const char *);
| | | (1732-A only, additional unit select bit) | | | (1732-A only, additional unit select bit)
| | Select Tape Unit | | Select Tape Unit
| Deselect Tape Unit | Deselect Tape Unit
Select Low Read Threshold (1733-3 only) Select Low Read Threshold (1732-3 only)
Status Response: Status Response:
@ -377,8 +379,8 @@ t_stat mt_help(FILE *, DEVICE *, UNIT *, int32, const char *);
| | | | File Mark | | | | File Mark
| | | Controller Active | | | Controller Active
| | Fill | | Fill
| Storage Parity Error (1733-3 only) | Storage Parity Error (1732-3 only)
Protect Fault (1733-3 only) Protect Fault (1732-3 only)
Director Status 2 Director Status 2
@ -389,7 +391,7 @@ t_stat mt_help(FILE *, DEVICE *, UNIT *, int32, const char *);
| | | | | | | | | | | | | | | | | | | |
| | | | | | | | | 556 BPI | | | | | | | | | 556 BPI
| | | | | | | | 800 BPI | | | | | | | | 800 BPI
| | | | | | | 1600 BPI (1733-3 only) | | | | | | | 1600 BPI (1732-3 only)
| | | | | | Seven Track | | | | | | Seven Track
| | | | | Write Enable | | | | | Write Enable
| | | | PE - Warning | | | | PE - Warning
@ -402,7 +404,7 @@ t_stat mt_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE MTdev = IODEV(NULL, "Magtape", 1732, 7, 0xFF, 0, IO_DEVICE MTdev = IODEV(NULL, "Magtape", 1732, 7, 0xFF, 0,
MTreject, MTin, MTout, MTBDCin, MTBDCout, MTreject, MTin, MTout, MTBDCin, MTBDCout,
MTstate, NULL, NULL, MTclear, MTstate, NULL, NULL, MTclear, NULL, NULL,
0x7F, 4, 0x7F, 4,
MASK_REGISTER0 | MASK_REGISTER1 | MASK_REGISTER2 | \ MASK_REGISTER0 | MASK_REGISTER1 | MASK_REGISTER2 | \
MASK_REGISTER3, MASK_REGISTER3,
@ -419,6 +421,7 @@ IO_DEVICE MTdev = IODEV(NULL, "Magtape", 1732, 7, 0xFF, 0,
#define iod_CWA iod_readR[3] /* current DSA address */ #define iod_CWA iod_readR[3] /* current DSA address */
#define iod_LWA iod_private6 /* last word address */ #define iod_LWA iod_private6 /* last word address */
#define iod_DSApending iod_private10 /* DSA request pending */ #define iod_DSApending iod_private10 /* DSA request pending */
#define iod_FWA iod_private11 /* first word address */
/* /*
* Define delay functions other than the standard motion commands. The low * Define delay functions other than the standard motion commands. The low
@ -486,6 +489,10 @@ MTAB mt_mod[] = {
&sim_tape_set_capac, &sim_tape_show_capac, NULL, "Specify tape capacity" }, &sim_tape_set_capac, &sim_tape_show_capac, NULL, "Specify tape capacity" },
{ MTAB_XTD|MTAB_VUN, 0, "TRANSPORT", NULL, { MTAB_XTD|MTAB_VUN, 0, "TRANSPORT", NULL,
NULL, &mt_show_transport, NULL, "Display type of tape transport" }, NULL, &mt_show_transport, NULL, "Display type of tape transport" },
{ MTAB_XTD|MTAB_VUN, 0, NULL, "9TRACK",
&mt_set_9track, NULL, NULL, "Set drive as 9-track transport" },
{ MTAB_XTD|MTAB_VUN, 0, NULL, "7TRACK",
&mt_set_7track, NULL, NULL, "Set drive as 7-track transport" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "STOPONREJECT", { MTAB_XTD|MTAB_VDV, 0, NULL, "STOPONREJECT",
&set_stoponrej, NULL, NULL, "Stop simulation if I/O is rejected" }, &set_stoponrej, NULL, NULL, "Stop simulation if I/O is rejected" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOSTOPONREJECT", { MTAB_XTD|MTAB_VDV, 0, NULL, "NOSTOPONREJECT",
@ -507,6 +514,8 @@ MTAB mt_mod[] = {
#define DBG_V_MTIO (DBG_SPECIFIC+4)/* Trace library routine calls */ #define DBG_V_MTIO (DBG_SPECIFIC+4)/* Trace library routine calls */
#define DBG_V_DENS (DBG_SPECIFIC+5)/* Trace density select changes */ #define DBG_V_DENS (DBG_SPECIFIC+5)/* Trace density select changes */
#define DBG_V_SELECT (DBG_SPECIFIC+6)/* Trace drive select/de-select */ #define DBG_V_SELECT (DBG_SPECIFIC+6)/* Trace drive select/de-select */
#define DBG_V_RDSA (DBG_SPECIFIC+7)/* Read data after DSA transfer */
#define DBG_V_WDSA (DBG_SPECIFIC+8)/* Write data before DSA transfer */
#define DBG_OPS (1 << DBG_V_OPS) #define DBG_OPS (1 << DBG_V_OPS)
#define DBG_READ (1 << DBG_V_READ) #define DBG_READ (1 << DBG_V_READ)
@ -515,6 +524,8 @@ MTAB mt_mod[] = {
#define DBG_MTIO (1 << DBG_V_MTIO) #define DBG_MTIO (1 << DBG_V_MTIO)
#define DBG_DENS (1 << DBG_V_DENS) #define DBG_DENS (1 << DBG_V_DENS)
#define DBG_SELECT (1 << DBG_V_SELECT) #define DBG_SELECT (1 << DBG_V_SELECT)
#define DBG_RDSA (1 << DBG_V_RDSA)
#define DBG_WDSA (1 << DBG_V_WDSA)
DEBTAB mt_deb[] = { DEBTAB mt_deb[] = {
{ "TRACE", DBG_DTRACE, "Trace device I/O requests" }, { "TRACE", DBG_DTRACE, "Trace device I/O requests" },
@ -529,6 +540,8 @@ DEBTAB mt_deb[] = {
{ "MTIO", DBG_MTIO, "Trace tape library routine calls" }, { "MTIO", DBG_MTIO, "Trace tape library routine calls" },
{ "DENS", DBG_DENS, "Trace denisty select changes" }, { "DENS", DBG_DENS, "Trace denisty select changes" },
{ "SELECT", DBG_SELECT, "Trace transport select/de-select" }, { "SELECT", DBG_SELECT, "Trace transport select/de-select" },
{ "RDSA", DBG_RDSA, "Dump buffer after DSA read" },
{ "WDSA", DBG_WDSA, "Dump buffer before DSA write" },
{ NULL } { NULL }
}; };
@ -745,6 +758,42 @@ void mt_dump(void)
} }
} }
void mt_DSAdump(uint16 lwa, t_bool rw)
{
uint16 cwa = MTdev.iod_FWA;
int idx;
char msg[80], text[16], temp[8];
fprintf(DBGOUT, "Dump of DSA %s buffer (FWA: %04X, LWA: %04X):\r\n",
rw ? "write" : "read", cwa, lwa);
msg[0] = '\0';
idx = 0;
while (cwa != lwa) {
text[idx++] = chars[(M[cwa] >> 8) & 0x7F];
text[idx++] = chars[M[cwa] & 0x7F];
sprintf(temp, "0x%04X", M[cwa]);
if (msg[0] != '\0')
strcat(msg, " ");
strcat(msg, temp);
if (idx == 10) {
text[idx++] = '\0';
fprintf(DBGOUT, "%-55s%s\r\n", msg, text);
msg[0] = '\0';
idx = 0;
}
cwa++;
}
if (idx != 0) {
text[idx++] = '\0';
fprintf(DBGOUT, "%-55s%s\r\n", msg, text);
}
}
/* /*
* Dump the current internal state of the MT device. * Dump the current internal state of the MT device.
*/ */
@ -788,7 +837,7 @@ t_stat mt_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
break; break;
case DEVTYPE_1732_3: case DEVTYPE_1732_3:
fprintf(st, "1733-3 Magnetic Tape Controller"); fprintf(st, "1732-3 Magnetic Tape Controller");
break; break;
default: default:
@ -842,6 +891,36 @@ t_stat mt_show_transport(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
return SCPE_OK; return SCPE_OK;
} }
/*
* Set drive to 9-track transport.
*/
t_stat mt_set_9track(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr == NULL)
return SCPE_IERR;
if ((uptr->flags & UNIT_ATT) != 0)
return SCPE_ALATT;
uptr->flags &= ~UNIT_7TRACK;
return SCPE_OK;
}
/*
* Set drive to 7-track transport.
*/
t_stat mt_set_7track(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr == NULL)
return SCPE_IERR;
if ((uptr->flags & UNIT_ATT) != 0)
return SCPE_ALATT;
uptr->flags |= UNIT_7TRACK;
return SCPE_OK;
}
/* /*
* Compute the delay time between new data being available from tape. This * Compute the delay time between new data being available from tape. This
* will be dependent on the density of the tape and the speed of the drive * will be dependent on the density of the tape and the speed of the drive
@ -988,6 +1067,8 @@ t_stat mt_svc(UNIT *uptr)
if ((mt_dev.dctrl & DBG_OPS) != 0) if ((mt_dev.dctrl & DBG_OPS) != 0)
mt_trace(uptr, "DSA read complete", (t_stat)-1, FALSE); mt_trace(uptr, "DSA read complete", (t_stat)-1, FALSE);
if ((mt_dev.dctrl & DBG_RDSA) != 0)
mt_DSAdump(MTdev.iod_LWA, FALSE);
break; break;
} }
@ -1005,6 +1086,8 @@ t_stat mt_svc(UNIT *uptr)
if ((mt_dev.dctrl & DBG_OPS) != 0) if ((mt_dev.dctrl & DBG_OPS) != 0)
mt_trace(uptr, "DSA read complete - no data", (t_stat)-1, FALSE); mt_trace(uptr, "DSA read complete - no data", (t_stat)-1, FALSE);
if ((mt_dev.dctrl & DBG_RDSA) != 0)
mt_DSAdump(MTdev.iod_CWA, FALSE);
break; break;
} }
@ -1170,6 +1253,10 @@ t_stat mt_svc(UNIT *uptr)
if (MTdev.iod_DSApending) { if (MTdev.iod_DSApending) {
MTdev.iod_DSApending = FALSE; MTdev.iod_DSApending = FALSE;
MTdev.iod_delay = IO_DSA_WRITE; MTdev.iod_delay = IO_DSA_WRITE;
if ((mt_dev.dctrl & DBG_WDSA) != 0)
mt_DSAdump(MTdev.iod_LWA, TRUE);
sim_activate(uptr, mt_densityTimeout(FALSE)); sim_activate(uptr, mt_densityTimeout(FALSE));
if ((mt_dev.dctrl & DBG_OPS) != 0) { if ((mt_dev.dctrl & DBG_OPS) != 0) {
int32 u = uptr - mt_dev.units; int32 u = uptr - mt_dev.units;
@ -1240,11 +1327,12 @@ t_stat mt_svc(UNIT *uptr)
if ((mt_dev.dctrl & DBG_MTIO) != 0) if ((mt_dev.dctrl & DBG_MTIO) != 0)
mtio_trace(uptr, "sprecf", status, FALSE, 0); mtio_trace(uptr, "sprecf", status, FALSE, 0);
if (status == MTSE_TMK) { if (status == MTSE_TMK)
MTdev.STATUS |= IO_1732_FMARK; MTdev.STATUS |= IO_1732_FMARK;
if (status != MTSE_OK)
break; break;
} }
}
if (sim_tape_bot(uptr)) if (sim_tape_bot(uptr))
MTdev.STATUS |= IO_1732_BOT; MTdev.STATUS |= IO_1732_BOT;
if (sim_tape_eot(uptr)) if (sim_tape_eot(uptr))
@ -1260,11 +1348,12 @@ t_stat mt_svc(UNIT *uptr)
if ((mt_dev.dctrl & DBG_MTIO) != 0) if ((mt_dev.dctrl & DBG_MTIO) != 0)
mtio_trace(uptr, "sprecr", status, FALSE, 0); mtio_trace(uptr, "sprecr", status, FALSE, 0);
if (status == MTSE_TMK) { if (status == MTSE_TMK)
MTdev.STATUS |= IO_1732_FMARK; MTdev.STATUS |= IO_1732_FMARK;
if (status != MTSE_OK)
break; break;
} }
}
if (sim_tape_bot(uptr)) if (sim_tape_bot(uptr))
MTdev.STATUS |= IO_1732_BOT; MTdev.STATUS |= IO_1732_BOT;
if (sim_tape_eot(uptr)) if (sim_tape_eot(uptr))
@ -1915,7 +2004,7 @@ enum IOstatus MTout(IO_DEVICE *iod, uint8 reg)
if ((uptr == NULL) || (MTdev.iod_type == DEVTYPE_1732_A)) if ((uptr == NULL) || (MTdev.iod_type == DEVTYPE_1732_A))
return IO_REJECT; return IO_REJECT;
MTdev.iod_LWA = LoadFromMem(IOAreg); MTdev.iod_LWA = LoadFromMem(IOAreg);
MTdev.iod_CWA = ++IOAreg; MTdev.iod_CWA = MTdev.iod_FWA = ++IOAreg;
MTdev.iod_DSApending = TRUE; MTdev.iod_DSApending = TRUE;
if ((mt_dev.dctrl & DBG_OPS) != 0) if ((mt_dev.dctrl & DBG_OPS) != 0)
mt_DSAtrace(uptr, "setup"); mt_DSAtrace(uptr, "setup");
@ -1991,8 +2080,10 @@ t_stat mt_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
"+sim> SET %D 1732-A\n" "+sim> SET %D 1732-A\n"
"+sim> SET %D 1732-3\n\n" "+sim> SET %D 1732-3\n\n"
" The first 3 transports (MT0, MT1, MT2) are 9-track drives and MT3 is a\n" " The first 3 transports (MT0, MT1, MT2) are 9-track drives and MT3 is a\n"
" 7-track drive. Each drive may be individually write-locked or\n" " 7-track drive. The type of a transport may be changed with:\n\n"
" write-enabled with:\n\n" "+sim> SET %U 9TRACK\n"
"+sim> SET %U 7TRACK\n\n"
" Each drive may be individually write-locked or write-enabled with:\n\n"
"+sim> SET %U LOCKED\n" "+sim> SET %U LOCKED\n"
"+sim> SET %U WRITEENABLED\n\n" "+sim> SET %U WRITEENABLED\n\n"
" The 1732-A controller can only perform I/O 1 or 2 bytes at a time. In\n" " The 1732-A controller can only perform I/O 1 or 2 bytes at a time. In\n"

View file

@ -93,7 +93,7 @@ t_stat rtc_help(FILE *, DEVICE *, UNIT *, int32, const char *);
IO_DEVICE RTCdev = IODEV(NULL, "10336-1", 10336, 13, 0xFF, 0, IO_DEVICE RTCdev = IODEV(NULL, "10336-1", 10336, 13, 0xFF, 0,
NULL, RTCin, RTCout, NULL, NULL, NULL, RTCin, RTCout, NULL, NULL,
NULL, NULL, RTCraised, NULL, NULL, NULL, RTCraised, NULL, NULL, NULL,
0x7F, 2, 0x7F, 2,
MASK_REGISTER0 | MASK_REGISTER1, MASK_REGISTER0 | MASK_REGISTER1,
MASK_REGISTER1, MASK_REGISTER1,
@ -158,7 +158,7 @@ struct RTCtimebase {
*/ */
UNIT rtc_unit = { UNIT rtc_unit = {
UDATA(&rtc_svc, 0, 0), RTC_10MSEC UDATA(&rtc_svc, 0, 0), RTC_10USEC
}; };
REG rtc_reg[] = { REG rtc_reg[] = {
@ -346,7 +346,8 @@ t_stat rtc_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr
"1 Hardware Description\n" "1 Hardware Description\n"
" The 10336-1 is a Real Time Clock which can generate periodic interrupts\n" " The 10336-1 is a Real Time Clock which can generate periodic interrupts\n"
" or measure elapsed time. The timer resolution is set via jumpers on the\n" " or measure elapsed time. The timer resolution is set via jumpers on the\n"
" physical hardware. For the simulator, the resolution can be changed by:\n\n" " physical hardware. For the simulator, the default resolution is\n"
" 10 uSec and can be changed by:\n\n"
"+sim> SET %D RATE=1usec\n" "+sim> SET %D RATE=1usec\n"
"+sim> SET %D RATE=10usec\n" "+sim> SET %D RATE=10usec\n"
"+sim> SET %D RATE=100usec\n" "+sim> SET %D RATE=100usec\n"

View file

@ -39,13 +39,14 @@ extern int disassem(char *, uint16, t_bool, t_bool, t_bool);
extern uint16 M[]; extern uint16 M[];
extern REG cpu_reg[]; extern REG cpu_reg[];
extern DEVICE cpu_dev, dca_dev, dcb_dev, dcc_dev, 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, tti_dev, tto_dev, ptr_dev, ptp_dev, mt_dev, lp_dev, dp_dev,
cd_dev, rtc_dev; cd_dev, drm_dev, rtc_dev;
extern UNIT cpu_unit; extern UNIT cpu_unit;
t_stat autoload(int32, CONST char *); t_stat autoload(int32, CONST char *);
t_stat CDautoload(void); t_stat CDautoload(void);
t_stat DPautoload(void); t_stat DPautoload(void);
t_stat DRMautoload(void);
t_bool RelValid = FALSE; t_bool RelValid = FALSE;
uint16 RelBase; uint16 RelBase;
@ -76,13 +77,11 @@ DEVICE *sim_devices[] = {
&tto_dev, &tto_dev,
&ptr_dev, &ptr_dev,
&ptp_dev, &ptp_dev,
#if 0
&cdr_dev,
#endif
&mt_dev, &mt_dev,
&lp_dev, &lp_dev,
&dp_dev, &dp_dev,
&cd_dev, &cd_dev,
&drm_dev,
NULL NULL
}; };
@ -92,7 +91,8 @@ const char *sim_stop_messages[] = {
"Selective Stop", "Selective Stop",
"Invalid bits set in EXI instruction", "Invalid bits set in EXI instruction",
"Breakpoint", "Breakpoint",
"Stop on reject" "Stop on reject",
"Unimpl. instruction"
}; };
/* /*
@ -113,7 +113,7 @@ static void postUpdate(t_bool from_scp)
{ {
/* /*
* Rebuild the I/O device and buffered data channel tables in case the * Rebuild the I/O device and buffered data channel tables in case the
* command the configuration. * command changed the configuration.
*/ */
buildIOtable(); buildIOtable();
buildDCtables(); buildDCtables();
@ -346,6 +346,8 @@ t_stat autoload(int32 flag, CONST char *ptr)
return CDautoload(); return CDautoload();
if (dptr == &dp_dev) if (dptr == &dp_dev)
return DPautoload(); return DPautoload();
if (dptr == &drm_dev)
return DRMautoload();
return SCPE_NOFNC; return SCPE_NOFNC;
} }

View file

@ -0,0 +1,126 @@
# Script to generate a customized MSOS 5.0 installation tape.
#
# Customizations:
# 1. Set system creation date to 4/19/17
#
# Requires:
# MSOS5-A.dsk and MSOS5-B.dsk Installation boot disks
# Installation tape Default is MSOS5_SL136.tap which can
# be copied from bitsavers.org. This can
# be overridden by specifying the
# installation tape on the command line:
#
# cdc1700 msosCustom1.simh install.tap
#
# Creates:
# MSOS5-Install.tap New installation tape. If it already
# exists, it will be overwritten
# Scratch1.tap and Scratch2.tap Tapes for temporary use. If they
# already exist, they will be overwritten
# %DATETIME%.lpt Unique LPT output file for this run
#
set env CDD0=MSOS5-A.dsk
set env CDD1=MSOS5-B.dsk
set env MT0=%1
if "%MT0%"=="" set env MT0=MSOS5_SL136.tap
set env MT1=MSOS5-Install.tap
set env MT2=Scratch1.tap
set env MT3=Scratch2.tap
set cpu instr=basic
set cpu mode65k,64k
#set throttle 30%
set mt type=1732-3
set mt3 9track
set lp type=1742
att lp %DATETIME%.lpt
att cdd0 %CDD0%
att cdd1 %CDD1%
att -r mt0 %MT0%
att mt1 %MT1%
att mt2 %MT2%
att mt3 %MT3%
set env TODAY=%DATE_MM%%DATE_DD%%DATE_19XX_YY%
#
# The following command will patch out unimplemented devices (1728 card
# reader/punch)
#
expect "SET PROGRAM PROTECT" set cpu protect; d 056D 0649; d 057E 0649; d 0589 0649; c
expect "DATE/TIME MMDDYYHHMM \n\r\n" send "%TODAY%%TIME_HH%%TIME_MM%\r"; c
expect ":00 " send after=1000000,"\007"; c
expect "MI\r\n" send "*BATCH,4\r"; c
expect "J \r\n" send "*JOB\r"; c
# Use SKED to extract and edit the skeleton file
expect "J \r\n" send delay=10000,"*SKED\r"; c
expect "NEXT\r\n" send "ADF,6,1\r"; c
expect "NEXT\r\n" send "BUILD,6\r"; c
expect "ENTER LU\r\n\007" send "\r"; goto insert1
autoload cdd
run 0
goto end
:insert1
expect "NEXT\r\n" send "INSERT,1,4\r"; c
expect "\007" send delay=20000,"*S,SYSMON,$3034\r"; c
expect "\007" send "*S,SYSDAY,$3139\r"; c
expect "\007" send "*S,SYSYER,$3137\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n" send delay=10000,"DELETE,2,4\r"; c
expect "NEXT\r\n" send "DUMP,17\r"; c
expect "NEXT\r\n" send "EXIT\r"; c
expect "J \r\n" send "*REW,6,17\r"; c
expect "J \r\n" send "*ADF,6,1\r"; goto libild
continue
:libild
expect "J \r\n" send delay=5000,"*LIBILD\r"; c
expect "CONTROL LU = \007" send "\r"; c
expect "DEFS LU = \007" send "\r"; c
expect "INSTALL LU = \007" send "18\r"; c
expect "NEWLIB LU = \007" send "\r"; c
expect "LIB 01 LU = \007" send "6\r"; c
expect "LIB 02 LU = \007" send "\r"; c
expect "SKELETON LU = \007" send "17\r"; c
expect "CR WHEN READY \r\n\007" send "\r"; c
expect "OUTPUT LIBRARY LU'S \007" send "*Z\r"; c
expect "J \r\n" send "*REW,6\r"; goto mtup
continue
:mtup
expect "J \r\n" send "*mtup\r"; c
expect "NEXT: \007" send "OPEN,O18,NL,U,A,SF0\r"; c
expect "NEXT: \007" send "CLOSE,O18,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF1,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I18,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I18,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*Z\r"; c
continue
:end

View file

@ -0,0 +1,149 @@
# Script to generate a customized MSOS 5.0 installation tape.
#
# Customizations:
# 1. Set system creation date to 4/19/17
# 2. Change the system name to "SIMH DEVELOPMENT SYSTEM"
#
# Requires:
# MSOS5-A.dsk and MSOS5-B.dsk Installation boot disks
# sysdat.tap Modified sysdat.asm as only file on
# the tape (80 char records)
# Installation tape Default is MSOS5_SL136.tap which can
# be copied from bitsavers.org. This can
# be overridden by specifying the
# installation tape on the command line:
#
# cdc1700 msosCustom1.simh install.tap
#
# Creates:
# MSOS5-Install.tap New installation tape. If it already
# exists, it will be overwritten
# Scratch?.tap Tapes for temporary use. If they
# already exist, they will be overwritten
# %DATETIME%.lpt Unique LPT output file for this run
#
set env CDD0=MSOS5-A.dsk
set env CDD1=MSOS5-B.dsk
set env MT0=%1
if "%MT0%"=="" set env MT0=MSOS5_SL136.tap
set env MT1A=Scratch3.tap
set env MT1B=MSOS5-Install.tap
set env MT2A=sysdat.tap
set env MT2B=Scratch1.tap
set env MT3=Scratch2.tap
set cpu instr=basic
set cpu mode65k,64k
#set throttle 30%
set mt type=1732-3
set mt3 9track
set lp type=1742
att lp %DATETIME%.lpt
att cdd0 %CDD0%
att cdd1 %CDD1%
att -r mt0 %MT0%
att mt1 %MT1A%
att -r mt2 %MT2A%
att mt3 %MT3%
set env TODAY=%DATE_MM%%DATE_DD%%DATE_19XX_YY%
#
# The following command will patch out unimplemented devices (1728 card
# reader/punch)
#
expect "SET PROGRAM PROTECT" set cpu protect; d 056D 0649; d 057E 0649; d 0589 0649; c
expect "DATE/TIME MMDDYYHHMM \n\r\n" send "%TODAY%%TIME_HH%%TIME_MM%\r"; c
expect ":00 " send after=1000000,"\007"; c
expect "MI\r\n" send "*BATCH,4\r"; c
expect "J \r\n" send "*JOB\r"; c
expect "J \r\n" send "*K,I17,P16\r"; c
expect "J \r\n" send "*ASSEM\r"; c
expect "J \r\n" send "*mtup\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*REW,17\r"; c
# Use SKED to extract and edit the skeleton file
expect "J \r\n" send "*SKED\r"; c
expect "NEXT\r\n\007" send "ADF,6,1\r"; c
expect "NEXT\r\n\007" send "BUILD,6\r"; c
expect "ENTER LU\r\n\007" send "\r"; goto insert1
send delay=10000
autoload cdd
run 0
goto end
:insert1
det mt2
att -q mt2 %MT2B%
expect "NEXT\r\n\007" send "INSERT,1,4\r"; c
expect "\007" send "*S,SYSMON,$3034\r"; c
expect "\007" send "*S,SYSDAY,$3139\r"; c
expect "\007" send "*S,SYSYER,$3137\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n\007" send "DELETE,2,4\r"; c
expect "NEXT\r\n\007" send "INSERT,8,4\r"; c
expect "\007" send "*V SIMH DEVELOPMENT SYSTEM\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n\007" send "DELETE,9\r"; c
expect "NEXT\r\n\007" send "DUMP,17\r"; c
expect "NEXT\r\n\007" send "EXIT\r"; c
expect "J \r\n" send "*REW,6\r"; c
expect "J \r\n" send "*ADF,6,1\r"; goto libild
continue
:libild
expect "J \r\n" send delay=5000,"*LIBILD\r"; c
expect "CONTROL LU = \007" send "\r"; c
expect "DEFS LU = \007" send "\r"; c
expect "INSTALL LU = \007" send "18\r"; c
expect "NEWLIB LU = \007" send "\r"; c
expect "LIB 01 LU = \007" send "16\r"; c
expect "LIB 02 LU = \007" send "6\r"; c
expect "LIB 03 LU = \007" send "\r"; c
expect "SKELETON LU = \007" send "17\r"; c
expect "CR WHEN READY. \r\n\007" send "\r"; c
expect "CR WHEN READY \r\n\007" send "\r"; c
expect "OUTPUT LIBRARY LU'S \007" send "*Z\r"; c
expect "J \r\n" send "*REW,6,16\r"; goto mtup
continue
:mtup
det mt1
att mt1 %MT1B%
expect "J \r\n" send "*mtup\r"; c
expect "NEXT: \007" send "OPEN,O18,NL,U,A,SF0\r"; c
expect "NEXT: \007" send "CLOSE,O18,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF1,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I18,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I18,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*Z\r"; c
continue
:end

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,150 @@
# Script to generate a customized MSOS 5.0 installation tape.
#
# Customizations:
# 1. Set system creation date to 4/19/17
# 2. Change the system name to "SIMH DEVELOPMENT SYSTEM"
# 3. Reduce file manager devices to CDD0/CDD1
#
# Requires:
# MSOS5-A.dsk and MSOS5-B.dsk Installation boot disks
# sysdat.tap Modified sysdat.asm as only file on
# the tape (80 char records)
# Installation tape Default is MSOS5_SL136.tap which can
# be copied from bitsavers.org. This can
# be overridden by specifying the
# installation tape on the command line:
#
# cdc1700 msosCustom1.simh install.tap
#
# Creates:
# MSOS5-Install.tap New installation tape. If it already
# exists, it will be overwritten
# Scratch?.tap Tapes for temporary use. If they
# already exist, they will be overwritten
# %DATETIME%.lpt Unique LPT output file for this run
#
set env CDD0=MSOS5-A.dsk
set env CDD1=MSOS5-B.dsk
set env MT0=%1
if "%MT0%"=="" set env MT0=MSOS5_SL136.tap
set env MT1A=Scratch3.tap
set env MT1B=MSOS5-Install.tap
set env MT2A=sysdat.tap
set env MT2B=Scratch1.tap
set env MT3=Scratch2.tap
set cpu instr=basic
set cpu mode65k,64k
#set throttle 30%
set mt type=1732-3
set mt3 9track
set lp type=1742
att lp %DATETIME%.lpt
att cdd0 %CDD0%
att cdd1 %CDD1%
att -r mt0 %MT0%
att mt1 %MT1A%
att -r mt2 %MT2A%
att mt3 %MT3%
set env TODAY=%DATE_MM%%DATE_DD%%DATE_19XX_YY%
#
# The following command will patch out unimplemented devices (1728 card
# reader/punch)
#
expect "SET PROGRAM PROTECT" set cpu protect; d 056D 0649; d 057E 0649; d 0589 0649; c
expect "DATE/TIME MMDDYYHHMM \n\r\n" send "%TODAY%%TIME_HH%%TIME_MM%\r"; c
expect ":00 " send after=1000000,"\007"; c
expect "MI\r\n" send "*BATCH,4\r"; c
expect "J \r\n" send "*JOB\r"; c
expect "J \r\n" send "*K,I17,P16\r"; c
expect "J \r\n" send "*ASSEM\r"; c
expect "J \r\n" send "*MTUP\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0,BR1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*REW,17\r"; c
# Use SKED to extract and edit the skeleton file
expect "J \r\n" send "*SKED\r"; c
expect "NEXT\r\n\007" send "ADF,6,1\r"; c
expect "NEXT\r\n\007" send "BUILD,6\r"; c
expect "ENTER LU\r\n\007" send "\r"; goto insert1
send delay=10000
autoload cdd
run 0
goto end
:insert1
det mt2
att -q mt2 %MT2B%
expect "NEXT\r\n\007" send "INSERT,1,4\r"; c
expect "\007" send "*S,SYSMON,$3034\r"; c
expect "\007" send "*S,SYSDAY,$3139\r"; c
expect "\007" send "*S,SYSYER,$3137\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n\007" send "DELETE,2,4\r"; c
expect "NEXT\r\n\007" send "INSERT,8,4\r"; c
expect "\007" send "*V SIMH DEVELOPMENT SYSTEM\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n\007" send "DELETE,9\r"; c
expect "NEXT\r\n\007" send "DUMP,17\r"; c
expect "NEXT\r\n\007" send "EXIT\r"; c
expect "J \r\n" send "*REW,6,17\r"; c
expect "J \r\n" send "*ADF,6,1\r"; goto libild
continue
:libild
expect "J \r\n" send delay=5000,"*LIBILD\r"; c
expect "CONTROL LU = \007" send "\r"; c
expect "DEFS LU = \007" send "\r"; c
expect "INSTALL LU = \007" send "18\r"; c
expect "NEWLIB LU = \007" send "\r"; c
expect "LIB 01 LU = \007" send "16\r"; c
expect "LIB 02 LU = \007" send "6\r"; c
expect "LIB 03 LU = \007" send "\r"; c
expect "SKELETON LU = \007" send "17\r"; c
expect "CR WHEN READY. \r\n\007" send "\r"; c
expect "CR WHEN READY \r\n\007" send "\r"; c
expect "OUTPUT LIBRARY LU'S \007" send "*Z\r"; c
expect "J \r\n" send "*REW,6,16\r"; goto mtup
continue
:mtup
det mt1
att -q mt1 %MT1B%
expect "J \r\n" send "*mtup\r"; c
expect "NEXT: \007" send "OPEN,O18,NL,U,A,SF0\r"; c
expect "NEXT: \007" send "CLOSE,O18,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF1,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I18,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I18,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*Z\r"; c
continue
:end

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,151 @@
# Script to generate a customized MSOS 5.0 installation tape.
#
# Customizations:
# 1. Set system creation date to 4/19/17
# 2. Change the system name to "SIMH DEVELOPMENT SYSTEM"
# 3. Reduce file manager devices to CDD0/CDD1
# 4. Remove the 1743-2 Asynch communication controller support
#
# Requires:
# MSOS5-A.dsk and MSOS5-B.dsk Installation boot disks
# sysdat.tap Modified sysdat.asm as only file on
# the tape (80 char records)
# Installation tape Default is MSOS5_SL136.tap which can
# be copied from bitsavers.org. This can
# be overridden by specifying the
# installation tape on the command line:
#
# cdc1700 msosCustom1.simh install.tap
#
# Creates:
# MSOS5-Install.tap New installation tape. If it already
# exists, it will be overwritten
# Scratch?.tap Tapes for temporary use. If they
# already exist, they will be overwritten
# %DATETIME%.lpt Unique LPT output file for this run
#
set env CDD0=MSOS5-A.dsk
set env CDD1=MSOS5-B.dsk
set env MT0=%1
if "%MT0%"=="" set env MT0=MSOS5_SL136.tap
set env MT1A=Scratch3.tap
set env MT1B=MSOS5-Install.tap
set env MT2A=sysdat.tap
set env MT2B=Scratch1.tap
set env MT3=Scratch2.tap
set cpu instr=basic
set cpu mode65k,64k
#set throttle 30%
set mt type=1732-3
set mt3 9track
set lp type=1742
att lp %DATETIME%.lpt
att cdd0 %CDD0%
att cdd1 %CDD1%
att -r mt0 %MT0%
att mt1 %MT1A%
att -r mt2 %MT2A%
att mt3 %MT3%
set env TODAY=%DATE_MM%%DATE_DD%%DATE_19XX_YY%
#
# The following command will patch out unimplemented devices (1728 card
# reader/punch)
#
expect "SET PROGRAM PROTECT" set cpu protect; d 056D 0649; d 057E 0649; d 0589 0649; c
expect "DATE/TIME MMDDYYHHMM \n\r\n" send "%TODAY%%TIME_HH%%TIME_MM%\r"; c
expect ":00 " send after=1000000,"\007"; c
expect "MI\r\n" send "*BATCH,4\r"; c
expect "J \r\n" send "*JOB\r"; c
expect "J \r\n" send "*K,I17,P16\r"; c
expect "J \r\n" send "*ASSEM\r"; c
expect "J \r\n" send "*MTUP\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0,BR1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*REW,17\r"; c
# Use SKED to extract and edit the skeleton file
expect "J \r\n" send "*SKED\r"; c
expect "NEXT\r\n\007" send "ADF,6,1\r"; c
expect "NEXT\r\n\007" send "BUILD,6\r"; c
expect "ENTER LU\r\n\007" send "\r"; goto insert1
send delay=10000
autoload cdd
run 0
goto end
:insert1
det mt2
att -q mt2 %MT2B%
expect "NEXT\r\n\007" send "INSERT,1,4\r"; c
expect "\007" send "*S,SYSMON,$3034\r"; c
expect "\007" send "*S,SYSDAY,$3139\r"; c
expect "\007" send "*S,SYSYER,$3137\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n\007" send "DELETE,2,4\r"; c
expect "NEXT\r\n\007" send "INSERT,8,4\r"; c
expect "\007" send "*V SIMH DEVELOPMENT SYSTEM\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n\007" send "DELETE,9\r"; c
expect "NEXT\r\n\007" send "DUMP,17\r"; c
expect "NEXT\r\n\007" send "EXIT\r"; c
expect "J \r\n" send "*REW,6,17\r"; c
expect "J \r\n" send "*ADF,6,1\r"; goto libild
continue
:libild
expect "J \r\n" send delay=5000,"*LIBILD\r"; c
expect "CONTROL LU = \007" send "\r"; c
expect "DEFS LU = \007" send "\r"; c
expect "INSTALL LU = \007" send "18\r"; c
expect "NEWLIB LU = \007" send "\r"; c
expect "LIB 01 LU = \007" send "16\r"; c
expect "LIB 02 LU = \007" send "6\r"; c
expect "LIB 03 LU = \007" send "\r"; c
expect "SKELETON LU = \007" send "17\r"; c
expect "CR WHEN READY. \r\n\007" send "\r"; c
expect "CR WHEN READY \r\n\007" send "\r"; c
expect "OUTPUT LIBRARY LU'S \007" send "*Z\r"; c
expect "J \r\n" send "*REW,6,16\r"; goto mtup
continue
:mtup
det mt1
att -q mt1 %MT1B%
expect "J \r\n" send "*mtup\r"; c
expect "NEXT: \007" send "OPEN,O18,NL,U,A,SF0\r"; c
expect "NEXT: \007" send "CLOSE,O18,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF1,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I18,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I18,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*Z\r"; c
continue
:end

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,152 @@
# Script to generate a customized MSOS 5.0 installation tape.
#
# Customizations:
# 1. Set system creation date to 4/19/17
# 2. Change the system name to "SIMH DEVELOPMENT SYSTEM"
# 3. Reduce file manager devices to CDD0/CDD1
# 4. Remove the 1743-2 Asynch communication controller support
# 5. Add 10336 real-time clock
#
# Requires:
# MSOS5-A.dsk and MSOS5-B.dsk Installation boot disks
# sysdat.tap Modified sysdat.asm as only file on
# the tape (80 char records)
# Installation tape Default is MSOS5_SL136.tap which can
# be copied from bitsavers.org. This can
# be overridden by specifying the
# installation tape on the command line:
#
# cdc1700 msosCustom1.simh install.tap
#
# Creates:
# MSOS5-Install.tap New installation tape. If it already
# exists, it will be overwritten
# Scratch?.tap Tapes for temporary use. If they
# already exist, they will be overwritten
# %DATETIME%.lpt Unique LPT output file for this run
#
set env CDD0=MSOS5-A.dsk
set env CDD1=MSOS5-B.dsk
set env MT0=%1
if "%MT0%"=="" set env MT0=MSOS5_SL136.tap
set env MT1A=Scratch3.tap
set env MT1B=MSOS5-Install.tap
set env MT2A=sysdat.tap
set env MT2B=Scratch1.tap
set env MT3=Scratch2.tap
set cpu instr=basic
set cpu mode65k,64k
#set throttle 30%
set mt type=1732-3
set mt3 9track
set lp type=1742
att lp %DATETIME%.lpt
att cdd0 %CDD0%
att cdd1 %CDD1%
att -r mt0 %MT0%
att mt1 %MT1A%
att -r mt2 %MT2A%
att mt3 %MT3%
set env TODAY=%DATE_MM%%DATE_DD%%DATE_19XX_YY%
#
# The following command will patch out unimplemented devices (1728 card
# reader/punch)
#
expect "SET PROGRAM PROTECT" set cpu protect; d 056D 0649; d 057E 0649; d 0589 0649; c
expect "DATE/TIME MMDDYYHHMM \n\r\n" send "%TODAY%%TIME_HH%%TIME_MM%\r"; c
expect ":00 " send after=1000000,"\007"; c
expect "MI\r\n" send "*BATCH,4\r"; c
expect "J \r\n" send "*JOB\r"; c
expect "J \r\n" send "*K,I17,P16\r"; c
expect "J \r\n" send "*ASSEM\r"; c
expect "J \r\n" send "*MTUP\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0,BR1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*REW,17\r"; c
# Use SKED to extract and edit the skeleton file
expect "J \r\n" send "*SKED\r"; c
expect "NEXT\r\n\007" send "ADF,6,1\r"; c
expect "NEXT\r\n\007" send "BUILD,6\r"; c
expect "ENTER LU\r\n\007" send "\r"; goto insert1
send delay=10000
autoload cdd
run 0
goto end
:insert1
det mt2
att -q mt2 %MT2B%
expect "NEXT\r\n\007" send "INSERT,1,4\r"; c
expect "\007" send "*S,SYSMON,$3034\r"; c
expect "\007" send "*S,SYSDAY,$3139\r"; c
expect "\007" send "*S,SYSYER,$3137\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n\007" send "DELETE,2,4\r"; c
expect "NEXT\r\n\007" send "INSERT,8,4\r"; c
expect "\007" send "*V SIMH DEVELOPMENT SYSTEM\r"; c
expect "\007" send "\r"; c
expect "NEXT\r\n\007" send "DELETE,9\r"; c
expect "NEXT\r\n\007" send "DUMP,17\r"; c
expect "NEXT\r\n\007" send "EXIT\r"; c
expect "J \r\n" send "*REW,6,17\r"; c
expect "J \r\n" send "*ADF,6,1\r"; goto libild
continue
:libild
expect "J \r\n" send delay=5000,"*LIBILD\r"; c
expect "CONTROL LU = \007" send "\r"; c
expect "DEFS LU = \007" send "\r"; c
expect "INSTALL LU = \007" send "18\r"; c
expect "NEWLIB LU = \007" send "\r"; c
expect "LIB 01 LU = \007" send "16\r"; c
expect "LIB 02 LU = \007" send "6\r"; c
expect "LIB 03 LU = \007" send "\r"; c
expect "SKELETON LU = \007" send "17\r"; c
expect "CR WHEN READY. \r\n\007" send "\r"; c
expect "CR WHEN READY \r\n\007" send "\r"; c
expect "OUTPUT LIBRARY LU'S \007" send "*Z\r"; c
expect "J \r\n" send "*REW,6,16\r"; goto mtup
continue
:mtup
det mt1
att -q mt1 %MT1B%
expect "J \r\n" send "*mtup\r"; c
expect "NEXT: \007" send "OPEN,O18,NL,U,A,SF0\r"; c
expect "NEXT: \007" send "CLOSE,O18,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF1,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,I18,NL,U,A,SF0,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I18,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF2,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF3,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF4,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "OPEN,I6,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "OPEN,O16,NL,U,A,SF5,,LB13000\r"; c
expect "NEXT: \007" send "COPY,FC1\r"; c
expect "NEXT: \007" send "CLOSE,O16,RW\r"; c
expect "NEXT: \007" send "CLOSE,I6,RW\r"; c
expect "NEXT: \007" send "EXIT\r"; c
expect "J \r\n" send "*Z\r"; c
continue
:end

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -1,6 +1,6 @@
# Script to install MSOS5 onto cartridge disks # Script to install MSOS5 onto cartridge disks
# Requires: # Requires:
# Installtion tape Default is MSOS5_SL136.tap which can # Installation tape Default is MSOS5_SL136.tap which can
# be copied from bitsavers.org. This # be copied from bitsavers.org. This
# can be overridden by specifying the # can be overridden by specifying the
# installation tape on the command line: # installation tape on the command line:
@ -13,7 +13,7 @@
# #
set env CDD0=MSOS5-A.dsk set env CDD0=MSOS5-A.dsk
set env CDD1=MSOS5-B.dsk set env CDD1=MSOS5-B.dsk
set env MT0=%2 set env MT0=%1
if "%MT0%"=="" set env MT0=MSOS5_SL136.tap if "%MT0%"=="" set env MT0=MSOS5_SL136.tap
set env LPT=MSOSinstall.lpt set env LPT=MSOSinstall.lpt
set cpu instr=basic set cpu instr=basic
@ -46,14 +46,20 @@ echo 1. Partition setup error
echo 2. File Manager sequential file error echo 2. File Manager sequential file error
echo 3. Fortran Formatted I/O error echo 3. Fortran Formatted I/O error
echo echo
send delay=10000
expect "DATE MM/DD/YY \r\r\r\r\n" send "%DATE1%\r"; c expect "DATE MM/DD/YY \r\r\r\r\n" send "%DATE1%\r"; c
expect -p "DATE/TIME MMDDYYHHMM \n\r\n" send "%DATE2%%TIME_HH%%TIME_MM%\r"; c expect -p "DATE/TIME MMDDYYHHMM \n\r\n" send "%DATE2%%TIME_HH%%TIME_MM%\r"; c
expect "Q\r\r\r\r\n" send "*i,3\r"; c expect "Q\r\r\r\r\n" send "*i,3\r"; c
expect "Q\r\r\r\r\n" send "*V\r"; c expect "Q\r\r\r\r\n" send "*V\r"; c
expect -p "YOU MAY AUTOLOAD" step 100000; autoload cdd; go 0 expect -p "YOU MAY AUTOLOAD" step 100000; autoload cdd; go 0
expect "SET PROGRAM PROTECT \r\n" set cpu protect; c expect "SET PROGRAM PROTECT \r\n" set cpu protect; c
expect -p ":00 " send after=100000,"\007"; c expect -p ":00 " send after=1000000,"\007"; c
expect "MI\r\n" send "*BATCH\r"; c expect "MI\r\n" send "*BATCH\r"; c
expect "MI\r\n" send "DB\r"; c
expect "IN\n\r\007" send "REW,6\r"; c
expect "NEXT \n\r\007" send "ADF,6,2\r"; c
expect "NEXT \n\r\007" send "OFF\r"; c
expect "OUT \n\r" send "\007"; c
expect "MI\r\n" send "VERIFY\r"; c expect "MI\r\n" send "VERIFY\r"; c
expect "TESTS COMPLETE." step 100000 expect "TESTS COMPLETE." step 100000
boot mt0 boot mt0

View file

@ -18,11 +18,8 @@ att lp %DATETIME%.lpt
att cdd0 %CDD0% att cdd0 %CDD0%
att cdd1 %CDD1% att cdd1 %CDD1%
set env DATEANDTIME=%DATE_MM%%DATE_DD%%DATE_19XX_YY%%TIME_HH%%TIME_MM% set env DATEANDTIME=%DATE_MM%%DATE_DD%%DATE_19XX_YY%%TIME_HH%%TIME_MM%
# send delay=10000
# The following command will patch out unimplemented devices (1728 card expect "SET PROGRAM PROTECT" set cpu protect; c
# reader/punch and 1752 drum)
#
expect "SET PROGRAM PROTECT" set cpu protect; d 056D 0649; d 057E 0649; d 0589 0649; d 057C 0649; c
expect "DATE/TIME MMDDYYHHMM \n\r\n" send "%DATEANDTIME%\r"; c expect "DATE/TIME MMDDYYHHMM \n\r\n" send "%DATEANDTIME%\r"; c
autoload cdd autoload cdd
run 0 run 0

51
CDC1700/msosVerify.simh Normal file
View file

@ -0,0 +1,51 @@
# Script to run the MSOS5 installation verification procedure
# Requires:
# Installation tape Default is MSOS5_SL136.tap which can
# be copied from bitsavers.org. This
# can be overridden by specifying the
# installation tape on the command line:
#
# cdc1700 msosInstall.simh install.tap
#
# Creates:
# MSOS5-A.dsk and MSOS5-B.dsk installation disks
# %DATETIME%.lpt unique LPT output file for this run
#
set env CDD0=MSOS5-A.dsk
set env CDD1=MSOS5-B.dsk
set env MT0=%1
if "%MT0%"=="" set env MT0=MSOS5_SL136.tap
set cpu instr=basic
set cpu mode65k,64k
set throttle 50%
set mt type=1732-3
set lp type=1742
att lp %DATETIME%.lpt
att cdd0 %CDD0%
att cdd1 %CDD1%
att -r mt0 %MT0%
set env DATEANDTIME=%DATE_MM%%DATE_DD%%DATE_19XX_YY%%TIME_HH%%TIME_MM%
set env DATE1=%DATE_MM%/%DATE_DD%/%DATE_19XX_YY%
set env DATE2=%DATE_MM%%DATE_DD%%DATE_19XX_YY%
echo This script will execute the installation verification procedure. It will
echo detect 3 errors:
echo
echo 1. Partition setup error
echo 2. File Manager sequential file error
echo 3. Fortran Formatted I/O error
echo
send delay=10000
expect "SET PROGRAM PROTECT \r\n" set cpu protect; c
expect "DATE/TIME MMDDYYHHMM \n\r\n" send "%DATE2%%TIME_HH%%TIME_MM%\r"; c
expect ":00 " send after=1000000,"\007"; c
expect "MI\r\n" send "DB\r"; c
expect "IN\n\r\007" send "REW,6\r"; c
expect "NEXT \n\r\007" send "ADF,6,2\r"; c
expect "NEXT \n\r\007" send "OFF\r"; c
expect "OUT \n\r" send "\007"; c
expect "MI\r\n" send "VERIFY\r"; c
expect "TESTS COMPLETE." step 100000
autoload cdd
run 0

View file

@ -212,6 +212,10 @@
RelativePath="..\CDC1700\cdc1700_dp.c" RelativePath="..\CDC1700\cdc1700_dp.c"
> >
</File> </File>
<File
RelativePath="..\CDC1700\cdc1700_drm.c"
>
</File>
<File <File
RelativePath="..\CDC1700\cdc1700_io.c" RelativePath="..\CDC1700\cdc1700_io.c"
> >

View file

@ -698,7 +698,7 @@ CDC1700_SOURCE = $(CDC1700_DIR)CDC1700_CPU.C,$(CDC1700_DIR)CDC1700_DIS.C,$(CDC17
$(CDC1700_DIR)CDC1700_SYS.C,$(CDC1700_DIR)CDC1700_DEV1.C,$(CDC1700_DIR)CDC1700_MT.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_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_DP.C,$(CDC1700_DIR)CDC1700_CD.C,$(CDC1700_DIR)CDC1700_SYM.C,\
$(CDC1700_DIR)CDC1700_RTC.C $(CDC1700_DIR)CDC1700_MSOS5.C $(CDC1700_DIR)CDC1700_RTC.C $(CDC1700_DIR)CDC1700_MSOS5.C $(CDC1700_DIR)CDC1700_DRM.C
CDC1700_OPTIONS = /INCL=($(SIMH_DIR),$(CDC1700_DIR))/DEF=($(CC_DEFS)) CDC1700_OPTIONS = /INCL=($(SIMH_DIR),$(CDC1700_DIR))/DEF=($(CC_DEFS))
# #

View file

@ -1570,7 +1570,8 @@ CDC1700 = ${CDC1700D}/cdc1700_cpu.c ${CDC1700D}/cdc1700_dis.c \
${CDC1700D}/cdc1700_dc.c ${CDC1700D}/cdc1700_iofw.c \ ${CDC1700D}/cdc1700_dc.c ${CDC1700D}/cdc1700_iofw.c \
${CDC1700D}/cdc1700_lp.c ${CDC1700D}/cdc1700_dp.c \ ${CDC1700D}/cdc1700_lp.c ${CDC1700D}/cdc1700_dp.c \
${CDC1700D}/cdc1700_cd.c ${CDC1700D}/cdc1700_sym.c \ ${CDC1700D}/cdc1700_cd.c ${CDC1700D}/cdc1700_sym.c \
${CDC1700D}/cdc1700_rtc.c ${CDC1700D}/cdc1700_msos5.c ${CDC1700D}/cdc1700_rtc.c ${CDC1700D}/cdc1700_drm.c \
${CDC1700D}/cdc1700_msos5.c
CDC1700_OPT = -I ${CDC1700D} CDC1700_OPT = -I ${CDC1700D}
### ###