Tribbles (May 2, 2004)

(home)
  1. From: "John R. Hogerhuis" May 2, 2004
  2. From: "donhamilton2002" May 2, 2004
  3. From: "Cyrano Jones" May 2, 2004


Subject: Tribbles

From: "Cyrano Jones" <cyranojones_lalp@...>

May 2, 2004

unit unit_tribbles;

interface

function sendbyte_as_tribbles(b: byte): boolean;
function receivebyte_as_tribbles: byte;
function receivebyte_as_tribbles_blocking: byte;
function mailstationbusy: boolean;
procedure resettribble;
procedure resetmailstation; //on ms with reset mod only!

implementation
uses ports, crt, unit_globals; //globals is just for db flag

var timer: cardinal;
const bsyout = $08;
stbout = $10;
bsyin = $40;
stbin = $80;
const tribmask: byte = $07;
dibmask: byte = $03;

procedure e(code: integer);
begin
if code=1 then
writeln('timeout waiting for ms to drop busy. ', code);
if code=2 then
writeln('timeout waiting for ms to ack. ', code);
if code=3 then
writeln('timeout waiting for ms to strobe. ', code);
if code=4 then
writeln('timeout waiting for ms to drop strobe. ', code);
if code=5 then
writeln('timeout waiting for ms to drop busy/ack', code);
if code=6 then
writeln('aborted waiting for ms to send', code);
errcount:=errcount+1;
if errcount>20 then
begin
errcount:=0;
writeln('Too many errors? hit esc to bail, other to continue:');
repeat until keypressed; bail := (readkey = ^[);
//bail needs to get reset somewhere!
end;
end;

function sendtribble(t: byte): boolean;
begin
timer:=250000; {arbitrary big number}
//timer is dependent on your cpu speed, but this should be big enough.
//timeouts should NOT happen, but if they do ('cause you forgot to hook
//up the laplink) and this is too big, you will be waiting several
//seconds or even weeks for the timeout error message. I did it this
//seemingly crappy way because I wanted the delay waiting for these
//signal edges to be as short as possible. I will leave it as an exercise
//for someone who cares more than I do to calculate an appropriate cpu
//speed dependent timeout value.

portb[888] := bsyout; {raise our busy}

repeat {wait for ms to drop busy}
timer:=timer-1;
if timer=0 then begin e(1); exit(false); end;
until (portb[889] and bsyin) = 0;
//drop busy first, so won't trip reset
portb[888] := t and tribmask; {send trib & no busy }
portb[888] := t and tribmask or stbout; {send trib & strobe & no busy }

repeat {wait for ms to ack}
timer:=timer-1;
if timer=0 then begin e(2); exit(false); end;
until (portb[889] and bsyin) <> 0;

// drop strobe before raising busy, don't trip reset!!!
portb[888] := 0; {drop strobe}
portb[888] := bsyout; {drop strobe, raise busy}
// busy stays up, till we wanna hear something.
exit(true);
end;

function receivetribble: byte;
var t: byte;
wastetime: cardinal;
begin
//if db then write('receivetribble-');
portb[888] := 0; {drop our busy/ack}

timer:=350000; {arbitrary big number}

repeat
timer:=timer-1;
if timer=0 then begin e(3); exit; end;
until (portb[889] and stbin) = 0; {wait for *inv* strobe}

//delay(1); //should we wait for data to settle??? doesn't seem neccesary!
t := portb[889] shr 3 and tribmask; {grab trib}
portb[888] := bsyout; {raise busy/ack}

repeat
timer:=timer-1;
if timer=0 then begin e(4); exit; end;
until (portb[889] and stbin) <> 0; {wait for *inv* UNstrobe}
//delay(1);//fudge, works, avoids false dataavail, but try in clearport instead

//portb[888] := 0; {drop busy/ack, so we're not sayin "I wanna send"}
//portb[888] := bsyout;//TRY THIS, maybe don't want ms to send if we not listening
// maybe busy means "I'm not listnen" rather than "I wanna talk"????
// busy is left set since acking trib

// The following repeat loop seems to stop false dataavail on clearports
// (when clearport is called very close after here)
//// **** loop removed, to see if crud-catcher works instead
//repeat
// timer:=timer-1;
// if timer=0 then begin e(5); exit(t); end;
//until (portb[889] and bsyin) = 0; {wait for UNbusy (done sendin)}
//TODO: CHECK IF MBUG SEND ALWAYS DROPS its busy when done sendin,
// FERINST WHEN EXEC 'GO 0000'///////*********************
exit(t);
end;

function sendbyte_as_tribbles(b: byte): boolean;
begin
if not sendtribble(b) then exit(false);
b:=b shr 3;
if not sendtribble(b) then exit(false);
b:=b shr 3;
if not sendtribble(b) then exit(false);
exit(true);
end;

function receivebyte_as_tribbles: byte;
var newbyte: byte;
begin
//if db then write('receivebyte_as_tribbles---');
newbyte := receivetribble + receivetribble shl 3 + (receivetribble and dibmask) shl 6;
//if db then writeln;
exit(newbyte);
end;

function receivebyte_as_tribbles_blocking: byte;
begin
// receivebyte_as_tribbles (above) will drop strobe (via receivetribble) and receive a byte, only if
// it comes within the timeout period. Here we drop our busy before calling
// receivebyte_as_tribbles, and then wait for a strobe, avoiding the timeout
// that would occur if we just called receivebyte_as_tribbles directly. When we see a
// strobe, we can hand off to the regular receivebyte_as_tribbles.
portb[888] := 0; {drop our busy/ack}

repeat
if keypressed then if readkey=^[ then begin e(6); exit($00); end;
until (portb[889] and stbin) = 0; {wait for *inv* strobe}

exit(receivebyte_as_tribbles);
end;

function mailstationbusy: boolean;
begin
exit((portb[889] and bsyin) <> 0);
end;

procedure resettribble;
begin
portb[888] := 0;
end;

procedure resetmailstation;
// This will only reset a mailstation with my reset mod!!!!!
// It raises both busy and strobe together, which is detected by the mod.
// This saves using an extra conductor in cable, so a standard par laplink
// cable can be used.
begin
portb[888] := stbout or bsyout;
delay(100); //3ms is minimum that works
portb[888] := 0;
end;

end.


1: Subject: Re: [mailstation] Tribbles

(top)

From: "John R. Hogerhuis" <jhoger@...>

May 2, 2004

With the name Cyrano Jones, I knew the mortal enemies of the Klingon
Empire were going to come into the picture sooner or later.


2: Subject: Re: Tribbles

(top)

From: "donhamilton2002" <donhamilton2002@...>

May 2, 2004


WOW !

I have not seen pascal in years !!, or is this some pascal derivative.

Anyway,

Is there a schematic of the cable available ?

What is this extra wire you mentioned.

thanks

hamilton


3: Subject: Re: Tribbles

(top)

From: "Cyrano Jones" <cyranojones_lalp@...>

May 2, 2004


(URL)


There are almost as many different pinouts for this cable
as there are websites with a pinout. But all of them
have in common the pins that are actually used by the
mailstation (pins 2, 3, 4, 5, 6, 15, 13, 12, 10, 11, and
at least one of the eight ground pins)

You need to cross the low 5 data pins at "one" end, to
the status pins at the other.
D0 2 to 15
D1 3 to 13
D2 4 to 12
D3 5 to 10
D4 6 to 11

And cross the 5 status lines at end "one" to the
low 5 data pins at the other.
/ACK 10 to 5
BUSY 11 to 6
PAPEROUT 12 to 4
SEL 13 to 3
/FAULT15 to 2

And at least one ground.
GND 25 to 25


I used a Belkin F3D508-10. IIRC, it did not
have any extra conductors, and I wanted to
be able to reset the mailstation from the PC.
So I added the logic to the mailstation
to reset whenever the PC asserted both
busy and strobe at the same time.

NOTE!!!!! the "busy" and "strobe" signals refered
to in my code are NOT THE SAME as the
busy and strobe lines on your standard parallel port.
The signal names in the table above ARE the names
from the standard parallel port, just for reference.

I may make up a better diagram sometime.
Also, I noticed that the web inteface to the list
mangled the pascal code (removed indents).
I uploaded a zip of the same file to the file section.

Cyrano Jones