/* cy.c Tahoe version Mar 1983. */
* Cypher tape driver. Stand alone version.
#include "../machine/pte.h"
#include "../machine/mtpr.h"
#include "../tahoevba/vbaparam.h"
long cystd
[] = { 0xf4000, 0 };
#define CYADDR(i) (cystd[i] + (int)VBIOBASE)
struct scp
/* SYSTEM CONFIGURATION POINTER */
char sysbus
; /* width of system buss 0=8;1=16 */
char pt_scb
[4] ; /* pointer to ->SYSTEM CONFIGURATION BLOCK */
struct scp
* SCP
; /* absolute address - jumpered on the controller */
/* set to 0xC06 for Tahoe */
struct scb
/* SYSTEM CONFIGUREATION BLOCK */
char sysblk
[1] ; /* 0x03 fixed value code */
char pt_ccb
[4] ; /* pointer to ->CHANNEL CONTROL BLOCK */
struct ccb
/* CHANNEL CONTROL BLOCK */
char ccw
[1] ; /* 0x11 normal; 0x09 clear non_vect interrupt */
char gate
[1] ; /* This is "the" GATE */
char pt_tpb
[4] ; /* pointer to ->TAPE OPERATION BLOCK or MOVE BLOCK */
struct tpb
/* TAPE OPERATIONS PARAMETER BLOCK */
long cmd
; /* COMMAND (input) */
char control
[2] ; /* CONTROL (input) */
short count
; /* RETURN COUNT (output) */
short size
; /* BUFFER SIZE (input/output) */
short rec_over
; /* RECORDS/OVERRUN (input/output) */
char pt_data
[4] ; /* pointer to ->SOURCE/DEST (input) */
char status
[2] ; /* STATUS (output) */
char pt_link
[4] ; /* pointer to ->INTERRUPT/PARAMETER BLOCK (input) */
struct tpb cycool
/* tape parameter block to clear interrupts */
int cyblksiz
= 1024; /* foreign tape size as found in open routine */
long cyblock
; /* next block number for i/o */
SCP
= (struct scp
*)0xc06; /* absolute - for setup */
TM_RESET(ctlradr
,0xff); /* reset the controller */
* Initialize the system configuration pointer
SCP
->sysbus
= 1; /* system width = 16 bits. */
/* initialize the pointer to the system configuration block */
set_pointer((long)&scb
.sysblk
[0],(char *)SCP
->pt_scb
);
* Initialize the system configuration block.
scb
.sysblk
[0] = 0x3; /* fixed value */
/* initialize the pointer to the channel control block */
set_pointer((long)&ccb
.ccw
[0],(char *)scb
.pt_ccb
);
* Initialize the channel control block.
ccb
.ccw
[0] = 0x11; /* normal interrupts */
/* initialize the pointer to the tape parameter block */
set_pointer((long)&tpb
,(char *)ccb
.pt_tpb
);
* set the command to be NO_OP.
tpb
.control
[0] = CW_BL
; /* TPB not used on first attention */
tpb
.control
[1] = CW_16bits
;
ccb
.gate
[0] = GATE_CLOSED
;
TM_ATTENTION(ctlradr
, 0xff); /* execute! */
* set the command to be CONFIGURE.
tpb
.control
[0] = CW_BL
; /* NO interrupt on completion */
tpb
.control
[1] = CW_16bits
;
tpb
.status
[0] = tpb
.status
[1] = 0;
ccb
.gate
[0] = GATE_CLOSED
;
TM_ATTENTION(ctlradr
, 0xff); /* execute! */
uncache (&tpb
.status
[1]) ;
if (tpb
.status
[1] & CS_ERm
) {
printf("Cypher initialization error!\n");
cy_decode_error(tpb
.status
[1]&CS_ERm
);
if(cycmd(io
,REWD_TA
) == -1)
_stop("Rewind failed!\n");
if(cycmd(io
,SPAC_FM
) == -1)
_stop("cy: seek failure!\n");
if (io
->i_flgs
& F_READ
) {
if((cyblksiz
= cycmd(io
,READ_FO
)) == -1)
_stop("Read foriegn tape failed!\n");
if(cycmd(io
,REWD_TA
) == -1)
_stop("Rewind after read failed\n");
/* if tape was open for writing write a file mark */
if (io
->i_flgs
& F_WRITE
) cycmd(io
,WRITE_FMARK
);
if ((func
!= SPACE
) && (func
!= REWD_TA
) && (io
->i_bn
!= cyblock
)) {
if(func
==READ
|| func
==WRITE
) {
register struct iob
*lio
= &liob
;
if((count
= cycmd(lio
, func
)) == 0)
if (func
== READ
) func
= READ_TA
;
else if (func
== WRITE
) func
= WRIT_TA
;
else if (func
== WRITE_FMARK
) func
= WRIT_FM
;
while(ccb
.gate
[0] == GATE_CLOSED
)
ccb
.gate
[0] = GATE_CLOSED
;
tpb
.control
[1] = CW_16bits
;
tpb
.status
[0] = tpb
.status
[1] = 0;
set_pointer((long)&tpb
,(char *)ccb
.pt_tpb
);
tpb
.size
= TM_SHORT(cyblksiz
);
else tpb
.size
= TM_SHORT(io
->i_cc
);
set_pointer((long)io
->i_ma
,(char *)tpb
.pt_data
);
tpb
.size
= TM_SHORT(io
->i_cc
);
set_pointer((long)io
->i_ma
,(char *)tpb
.pt_data
);
if ((j
= io
->i_bn
- cyblock
) < 0) {
tpb
.rec_over
= TM_SHORT(j
);
TM_ATTENTION(ctlradr
, 0xff); /* execute! */
if (func
== REWD_TA
|| func
== SPACE
) {
* First we clear the interrupt and close the gate.
ccb
.gate
[0] = GATE_CLOSED
;
set_pointer((int)&cycool
,(char *)ccb
.pt_tpb
);
cycool
.cmd
= NO_OP
; /* no operation */
cycool
.control
[0] = CW_BL
; /* No INTERRUPTS */
TM_ATTENTION(ctlradr
,0xff); /* cool it ! */
uncache (&tpb
.status
[1] ) ;
if (tpb
.status
[1] & CS_ERm
) {
cy_decode_error(tpb
.status
[1]&CS_ERm
);
return((long)TM_SHORT(tpb
.count
));
printf("cy0: %s.\n", message
);
cyprint_error("Drive timed out during transfer");
cyprint_error("Non-existant system memory reference");
cyprint_error("Controller micro diagnostics failed");
cyprint_error("Unrecoverble media error");
cyprint_error("Unsatisfactory media");
cyprint_error("Data transfer over run");
cyprint_error("Drive is not ready");
cyprint_error("Tape is write protected");
cyprint_error("Checksum error in controller proms");
cyprint_error("Unrecoverable tape parity error");
cyprint_error("Blank tape found where data was expected");
cyprint_error("Unrecoverble hardware error");
while (ccb
.gate
[0] != GATE_OPEN
) {
cyprint_error("Transfer timeout");
* Set a TAPEMASTER pointer (first parameter), into the
* 4 bytes array pointed by the second parameter.
set_pointer(pointer
,dest
)
*dest
++ = pointer
& 0xff; /* low byte - offset */
*dest
++ = (pointer
>> 8) & 0xff; /* high byte - offset */
*dest
= (pointer
& 0xf0000) >> 12; /* base */