Category : Files from Magazines
Archive   : DDJ-0591.ZIP
Filename : GPIB.591

 
Output of file : GPIB.591 contained in archive : DDJ-0591.ZIP
_IMPLEMENTING THE GPIB_
by Don Morgan

[LISTING ONE]

#include
#include "gpib.h" /*local header file containing declares and defines */

/*Reinitialize local interface, whether from power up or device or interface
clear. It will do nothing, however to initialize system interrupts to take
advantage of TMS9914A interrupts; you do that */
void Gpib_Init()
{
int address;
outp(AUXCMD,SWRST);
/*software reset*/
address = (inp(DIPSW) & 0x1f);
/* Read dipswitch for address of device. Lower 5 bits carry legal
address of device, clearing upper bits and enables talker & listener
functions, as well as, disabling dual primary addressing mode.*/
outp(ADDRES,address);
outp(IMSK0,BI | BO | SPAS | END);
/*set the interrupts BI, BO, SPAS, and END*/
outp(IMSK1, DCAS | IFC);
/*and DCAS and IFC*/
outp(SERPOL,0x0);
serial_poll = serial_poll_mask = 0x0;
/*clear the serial poll byte and mask*/
outp(AUXCMD,SWRSTC);
/*clear the software reset*/
}
/* Each time a condition arrises in the device that sets a bit int the serial
poll status byte, this routine is called. It is passed the mask (MAV or TRG, at
the moment) for the bit to be set and does three things. 1) sets the bit in
the serial poll status byte. 2) sets the corresponding bit in global variable
we created serial_poll. This is for reference, the serial poll status byte is
write only. 3) It checks to see whether this condition is one the user has
determined should cause an SRQ.*/
void Check_Mask(mask);
{
serial_poll |= mask;
outp(SERPOL, serial_poll);
if(serial_poll_mask & mask)
outp(AUXCMD,RSV2);
}
/* Vectored to by system interrupts.*/
void Gpib_Int_Han()
{
int status_byte; /*This is where we will save interrupt status
registers until we are through with them*/
int chr; /*character holder*/
status_byte = inp(ISTAT0);
/*get what is in interrupt status register 0*/
if(status_byte & SPAS) {
/*place routine here to perform any maintainance necessary
after controller reads the serial poll byte. If you are
using rsv1, you would reset bit 1 (D0 is MSB), otherwise it
may be a reset to any bits gone active since the last SRQ.*/
}
if(status_byte & INT0) {
/*this bit will be set if there is at least one active,
unhandled interrupt in int status 0. The interrupts that we
will be concerned about here are: BI, BO, SPAS, and END*/
if(status_byte & BI) {
/*checking for a byte received from the bus*/
chr = inp(DATIN); /*get the character*/
if(status_byte & EOI)
flag = TRUE;
else;
flag = FALSE;
receive(chr,flag); /*receive is your function that accepts
character and places it in whatever buffer
scheme is your favorite. flag, is set if an EOI
is detected signalling the end of a string.*/
}
else { if(status_byte & BO) {
chr = get_byte();
if((chr >> 0x8) == TRUE) {
outp(AUXCMD, FEOI);
serial_poll &= ~MAV;
outp(SERPOL,serial_poll);
/*since this is the last character of string, we take this
time to reset 'message available' bit in serial_poll byte*/
}
outp(AUXCMD,chr);
/*Toutine for retrieving next byte from transmit buffer. If
you are using the EOI, include some way to indicate that this
is last character of string, as FEOI must be placed in
auxiliary command register before last character is sent. In
this case, I assumed upper byte of chr was used to carry a
flag explaining the status of that character*/
}
}
if(status_byte & INT1) {
inp(ISTAT1); /*Get contents of interrupt status register 1. Here we
are interested in DCAS (device clear) and IFC
(interface clear*/
if((ISTAT1 & DCAS) || (ISTAT1 & IFC)) Gpib_Init();
/*whether we receive a device clear or an interface
clear, we will do the same thing, reinitialize the
local interface*/
}


[LISTING TWO]

/*GPIB HEADER FILE*/

/* The following are defines for address mapping, they are written assuming
a linear addressing scheme and an 8 bit bus. Depending on the width and
decoding scheme you use, these defines might be different.*/

#define DIPSW ?? /*place dipswitch setting device address address here*/
#define IEEE ?? /*place base address of TMS9914A here*/
#define IMSK0 IEEE+0 /*interrupt mask register 0*/
#define ISTAT0 IEEE+0 /*interrupt status register 0*/
#define IMASK1 IEEE+1 /*interrupt mask register 1*/
#define ISTAT1 IEEE+1 /*interrupt status register 1*/
#define ADSTAT IEEE+2 /*address status register*/
#define BUSTAT IEEE+3 /*bus status register*/
#define AUXCMD IEEE+3 /*address register*/
#define ADRSWI IEEE+4 /*address switch register*/
#define ADDRES IEEE+4 /*address register*/
#define SERPOL IEEE+5 /*serial poll register*/
#define CMDPAS IEEE+6 /*command pass through register*/
#define PARPOL IEEE+6 /*parallel poll register*/
#define DATIN IEEE+7 /*data from bus register*/
#define DATOUT IEEE+7 /*data to bus register*/

/*next, define some bit masks to be used in the interrupt routines. These will
be AND'd with interrupt status registers to determine proper action to take*/
#define INT0 0x80 /*interrupt register 0 has an interrupt, int status 0*/
#define INT1 0x40 /*interrupt register 1 has an interrupt, int status 0*/
#define BI 0x20 /*Byte In, int status 0*/
#define B0 0x10 /*Byte Out, int status 0*/
#define DCAS 0x8 /*device clear, int status 1*/
#define EOI 0x8 /*End of Identify, int status 0*/
#define SPAS 0x4 /*serial poll active state, int status 0*/
#define IFC 0x1 /*interface clear, int status 1*/

/*now, defines for some of the auxiliary commands used*/
#define SWRST 0x80 /*sets the software reset*/
#define SWRSTC 0x0 /*clears the software reset*/
#define FEOI 0x88 /*sent prior to last byte in string to indicate end*/
#define RSV2 0x98 /*alternate and preferred method of asserting SRQ*/

/*these bits are used as definitions of serial poll status byte and mask*/
#define MAV 0x20 /*message available*/
#define TRG 0x1 /*trigger*/

/*other stuff*/
#define TRUE 0xff
#define FALSE 0x0

/*declarations*/
int serial_poll; /*global variable containing a record of the mask
written to the serial poll register in the TMS9914A.*/
int serial_poll_mask;
/*for our purposes, the serial poll status byte and serial poll mask byte is
to be defined as follows, remember D0 is MSB:
D0 D1 D2 D3 D4 D5 D6 D7
X RQS MAV X X X X TRG
RQS is the request for service and is read as a 1 by controller during a
serial poll when this device has asserted an SRQ. MAV is 'message available'
and is set when there is something in the transmit buffer, reset otherwise.
TRG is the trigger bit and is set when the oscilloscope has been triggered.*/

/*function prototypes, these are example only, yours may well be different*/
extern int get_byte(void);
extern void receive(int,int);
extern void Gpib_Int_Han(void);
extern void Gpib_init(void);
extern void Check_Mask(int);




  3 Responses to “Category : Files from Magazines
Archive   : DDJ-0591.ZIP
Filename : GPIB.591

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/