Files
TeslaRel410/sda4/DPL3/LINKIO.C
T
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00

428 lines
7.8 KiB
C++

/*
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 <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <basictyp.h>
#include <linkio.h>
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 <dos.h>
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++ ) {
if (OUTPUT_READY) return(1);
}
printf ( "Fail in outputOrFail\n" );
link_io_EXITZERO;
}
/*}}} */
/*{{{ int32 inputOrFail ( unsigned char *b)*/
int32 inputOrFail ( unsigned char *b)
{
int32 i;
link_io_ABORTCHECK;
for (i=0; i<failed; i++ ) {
if (INPUT_READY) {
*b = read_C012(inputData);
return(1);
}
}
linkio_error ( "Fail in inputOrFail\n" );
return 0;
link_io_EXITZERO;
}
/*}}} */
/*{{{ void resetLoop()*/
static void resetLoop()
{
clock_t the_time=clock();
while (the_time==clock());
while (the_time==clock());
}
/*}}} */
/*{{{ static void reset()*/
void reset()
{
write_C012(analyseRoot,0);
write_C012(resetRoot, 0);
resetLoop();
write_C012(resetRoot, 1);
resetLoop();
write_C012(outputStatus, 0);
write_C012(inputStatus, 0);
write_C012(resetRoot, 0);
}
/*}}} */
/*{{{ int32 outRecord(register char *packet, int32 bytes )*/
int32 outRecord(register char *packet, int32 bytes )
{
int32 i;
int32 j;
time_t now, then=clock();
link_io_ABORTCHECK;
/*
if (outveryfast(packet, C012, bytes)) return 1;
linkio_error ("timeout in outRecord\n");
goto abort;
*/
for (j=0; j<bytes; j++ ) {
for (i=0; 1; i++ ) {
if (OUTPUT_READY) {
OUTBYTE(*packet++);
break;
}
else if (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<bytes; j++ ) {
for (i=0; 1; i++ ) {
if (INPUT_READY) {
*packet++ = INBYTE();
break;
}
else if (i>=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 <sys/types.h>
#include <sys/fcntl.h>
#include <sys/dbi0110.h>
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 <process.h>
#include <channel.h>
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