/* FILE : linkio.c PROJECT : dView Author : Phil Atkin / Jeff Sullivan (C) Division Ltd 1991 / 1992. Transputer link support functions currently supported are - simple polled PC / DOS interface, a la IMS B004 simple polled Mac interface for C012 (not high-speed Nubus access) UNIX device driver interface */ #include #include #include #include #include int32 __connected=1; void linkio_error ( char *str ) { printf ( str ); __connected=1; } #define time_out_seconds 5 /* plenty of time */ #ifdef MS_DOS /*{{{ MS-DOS link io functions*/ #include int32 C012; static int32 inputData, outputData, inputStatus, outputStatus, resetRoot, analyseRoot, ok_to_fifo; #define failed (int32) 40000 #define read_C012(reg) inp(reg) #define write_C012(reg,byte) outp(reg,byte) #define INPUT_READY (1 & read_C012(inputStatus)) #define OUTPUT_READY (1 & read_C012(outputStatus)) #define OUTBYTE(b) write_C012(outputData, b) #define INBYTE() read_C012(inputData) /*{{{ void setLA ( int32 addr )*/ void setLA ( int32 C012_addr ) { C012 = C012_addr; inputData = C012; outputData = inputData + 1; inputStatus = outputData + 1; outputStatus = inputStatus + 1; resetRoot = C012 + 16; analyseRoot = resetRoot+1; ok_to_fifo = C012 + 16; } /*}}} */ /*{{{ void initLA ( )*/ void initLA () { return; } /*}}} */ /*{{{ int32 outputOrFail ( unsigned char b)*/ int32 outputOrFail ( unsigned char b) { int32 i; link_io_ABORTCHECK; write_C012(outputData, b); for (i=0; i=failed) { i=0; now=clock(); if ((now - then) > (time_t) (CLOCKS_PER_SEC * time_out_seconds)) { linkio_error ("timeout in outRecord\n"); goto abort; } } } } return(1); link_io_EXITZERO; } /*}}} */ /*{{{ int32 inRecord(register char *packet, int32 bytes )*/ int32 inRecord(register char *packet, int32 bytes ) { int32 j; int32 i; time_t now, then=clock(); link_io_ABORTCHECK; for (j=0; j=failed) { i=0; now=clock(); if ((now - then) > (time_t) (CLOCKS_PER_SEC * time_out_seconds)) { linkio_error ("timeout in inRecord\n"); goto abort; } } } } return(1); link_io_EXITZERO; } /*}}} */ /*{{{ int32 inputReady(void)*/ int32 inputReady(void) { int32 t=INPUT_READY; return t; } /*}}} */ /*{{{ int32 altRecord()*/ int32 altRecord(void) { return (inputReady()); } /*}}} */ /*{{{ int32 fifo_ok_status(void)*/ int32 fifo_ok_status(void) { return (1 & read_C012(ok_to_fifo)); } /*}}} */ /*}}} */ #endif #ifdef UNIX /*{{{ UNIX support*/ #include #include #include static int32 linkfd = -1; static char device_name[256]; void setLA ( int32 addr ) { if (addr == 0x150) { strcpy ( device_name, "/dev/bviii0" ); } else if (addr == 0x200) { strcpy ( device_name, "/dev/bviii1" ); } } int32 inputReady(void); void initLA (void) { if((linkfd = open(device_name, O_RDWR)) == -1) { link_io_error("can't open link adaptor \"%s\".\n", device_name ); } inputReady(); } static char inByte() { char b; read( linkfd, &b, 1 ); return b; } long outputOrFail ( unsigned char b) { /* should set up to do ndelay style stuff,and check status*/ write(linkfd, &b, 1); return 1; } long inputOrFail ( unsigned char *b) { if(read(linkfd, b, 1) != 1) { link_io_error("Failed to write 1 byte to link adaptor.\n"); } return 1; } void reset() { union B008_IO dat; dat.set.op = RESET; dat.set.val = 0; ioctl(linkfd,SETFLAGS, &dat); } long outRecord(char *packet, int32 bytes ) { int32 byteswritten; if ((byteswritten = write(linkfd,packet, bytes)) != bytes) { link_io_error("Tried to write %ld bytes, got %ld.\n",bytes, byteswritten); } return 1; } long inRecord(char *packet, int32 bytes ) { return read (linkfd,packet, bytes); } int32 inputReady (void) { union B008_IO dat; if (ioctl(linkfd,READFLAGS, &dat) == (-1)) { printf ("IOCTL failed\n" ); return -1; } return dat.status.read_f; } int32 outputReady ( void ) { union B008_IO dat; if (ioctl(linkfd,READFLAGS, &dat) == (-1)) { printf ("IOCTL failed\n" ); return -1; } return dat.status.write_f; } int32 altRecord(void) { return inputReady(); } /*}}} */ #endif #ifdef TRANNY /*{{{ transputer direct link support code*/ #include #include Channel *out_link = (Channel *) (0x80000000 | 0x0c); Channel *in_link = (Channel *) (0x80000000 | 0x1c); /*{{{ void initLA (void)*/ void initLA (void) { } /*}}} */ /*{{{ void setLA ( int32 slot )*/ void setLA ( int32 slot ) { out_link = (Channel *) (0x80000000 | (slot<<2)); in_link = (Channel *) (0x80000000 | ((slot+4)<<2)); } /*}}} */ /*{{{ static char inByte()*/ static char inByte() { char b; ChanIn ( in_link, &b, 1 ); return b; } /*}}} */ /*{{{ void resetLoop()*/ void resetLoop() { ProcWait ( 1000 ); } /*}}} */ /*{{{ void reset()*/ void reset() { ChanReset(in_link); ChanReset(out_link); resetLoop(); } /*}}} */ /*{{{ int32 outRecord(char *packet, int32 bytes )*/ int32 outRecord(char *packet, int32 bytes ) { int32 kill_time; kill_time = ProcTimePlus ( ProcTime(), 15625 * time_out_seconds ); if (ChanOutTimeFail ( out_link, packet, bytes, kill_time )) { link_io_error ( "outRecord managed %ld of %ld\n", 0, bytes ); } return(1); } /*}}} */ /*{{{ int32 inRecord(char *packet, int32 bytes )*/ int32 inRecord(char *packet, int32 bytes ) { int32 kill_time; kill_time = ProcTimePlus ( ProcTime(), 15625 * time_out_seconds ); if (ChanInTimeFail ( in_link, packet, bytes, kill_time )) { ChanReset (in_link); return(0); } else return(1); } /*}}} */ /*{{{ int32 inputReady (void)*/ int32 inputReady (void) { return ( ProcSkipAlt ( in_link, NULL ) == 0); } /*}}} */ /*{{{ int32 altRecord()*/ int32 altRecord(void) { return inputReady(); } /*}}} */ /*}}} */ #endif