Received: from ultb.isc.rit.edu by karazm.math.UH.EDU with SMTP id AA02032 (5.65c/IDA-1.4.4 for ); Mon, 7 Oct 1991 11:46:29 -0500 Received: by ultb.isc.rit.edu (5.57/5.3 (Postmaster DPMSYS)) id AA02651; Mon, 7 Oct 91 12:42:36 -0400 Received: from lithium.CS (lithium.ARPA) by junior.rit.edu (4.1/5.17) id AA01637; Mon, 7 Oct 91 12:32:14 EDT From: jdb9608@cs.rit.edu (John D Beutel) Message-Id: <9110071632.AA01637@junior.rit.edu> Subject: C hires code for ATARI 1040 ST (fwd) To: glove-list@karazm.math.uh.edu Date: Mon, 7 Oct 91 12:43:19 EDT Cc: jxw1578@cs.rit.edu (John X Whitehurst), rwr9481@cs.rit.edu (Robert W Reay), rxc9885@cs.rit.edu (Robert X Costello) X-Mailer: ELM [version 2.3 PL8] HIRES HIRES HIRES HIRES HIRES HIRES HIRES HIRES HIRES HIRES This is it, folks! I can't believe it. It really works. I didn't do any of its development, but I have tested it with Sozoban C (with minor adjustments--changing "tos.h" to "osbind.h", and deleting two void's in forward function declarations). Manfredo has tried posting it to the glove-list, but it's disappeared into some black hole somewhere, so he asked me to post it for him. I've gotten the data packets in the right sequence, but not the right order. They've started with Z and ended with A0 X Y, so I don't have it all figured out yet, but that doesn't really matter since even if the data packet is out of order, I can still tell which byte is which by seeing where A0, 0, 0, 3F, FF, FF occur. The problem with this program is that it uses busy loops for very long times (i.e., over 75,000 microseconds). That makes the sample rate a little slow (which is okay since my ST can't do much per second anyway), and---most importantly---it hogs all the CPU time. I'm working on a modification which uses the MFP's timer A to generate an interrupt after the appropriate long interval (D2SLOW) and then handle the rest of the protocol in an ISR. That should free up the CPU for graphics. I'll post it when I get it working. I'll also put this source in karazm.math.uh.edu:pub/incoming/VR tonite when the anonymous ftp is allowed (Eric...). If anyone has special questions about how the ST works, for converting this code to other computers, I'll be happy to see what answers I can dig up. Now, does anyone have freely--distributable source for a nice 3D graphics library (PHIGS, maybe?), before I go write my own?... Forwarded message: > From manfredo@medap1.cs.tu-berlin.de Wed Oct 2 12:12:02 1991 > From: manfredo@medap1.cs.tu-berlin.de (Manfred Krauss) > Message-Id: <9110021622.AA09307@medap1.cs.tu-berlin.de> > Subject: C hires code for ATARI 1040 ST > To: jdb9608@rit > Date: Wed, 2 Oct 91 17:22:37 MET > X-Mailer: ELM [version 2.3 PL6] > > Hi, > > Following C program switches the glove into hi-res mode. > The protocol goes via latch. The code works very well. > > Next project is to build a little controller with a 68HC11 > processor to connect the glove to any? computer via RS232 > interface. I've no experience in programming such a processor. > Is anyone out there who is familiar with the 68HC11? > I can send a complete timing diagramm and support the work > with my knowledge. > > Waiting for hints and comments. > > manfredo > > -------------------- cut here -------------------------------------- /********************************************************************** power.c (c) manfredo 9/91 enjoy "HiRes" mode manfredo@opal.cs.tu-berlin.de This program is without any WARRANTY use at your OWN risk @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The code is very ugly, but it was the only way to get speed on this poor hardware in C. It was developed on an ATARI 1040ST with TC 1.1 using a logic analyzer to get the correct timings. connect NINTENDO POWERGLOVE to ATARI 1040ST parallel port PG ATARI +5V pin7 power supply +5V GND pin1 pin18 parallel port & power supply GND data pin4 pin1 parallel port latch pin3 pin2 parallel port clock pin2 pin3 parallel port Datapacket: (12 bytes) 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. A0 X Y Z rot finger keys 00 00 3F FF FF **********************************************************************/ #include #include /* PSG (Programable Sound Generator) */ #define PSG 0xff8800 /* sound chip read data */ #define PSGW 0xff8802 /* sound chip write data */ /* registers in PSG */ #define CONREG 7 /* read/write control reg */ #define AREG 14 /* port A */ #define BREG 15 /* port B */ /* read / write bits in PSG register 7 */ #define AREAD 0xbf /* A read bit in register 7 */ #define BREAD 0x7f /* B read bit in register 7 */ #define AWRITE 0x40 /* A write bit in register 7 */ #define BWRITE 0x80 /* B write bit in register 7 */ /* bits from parallel port */ #define GDATA 0x20 /* Strobe (Pin 1) PG data in */ #define GLATCH 0x01 /* bit1 (pin2) PG latch out */ #define GCLOCK 0x02 /* bit2 (pin3) PG clock out */ #define GCLOLAT 0x03 /* bit2 + bit 1 */ /* Delay timing */ #define delay(val) { \ register unsigned long i = val /7; \ for ( ;i-- > 0; ) \ ; \ } #define D2BYTES 192 /* delay between 2 bytes 96 us */ #define D2BITS 21 /* delay between 2 bits 22 us */ #define D2SLOW 32000 /* 4 slow bytes in packet 14720 us */ #define C0L0() *wr = 0 /* clock 0 latch 0 */ #define C0L1() *wr = GLATCH /* clock 0 latch 1 */ #define C1L0() *wr = GCLOCK /* clock 1 latch 0 */ #define C1L1() *wr = GCLOLAT /* clock 1 latch 1 */ #define setporta() *rd = CONREG; \ *wr = *rd & AREAD; \ *rd = AREG #define setportb() *rd = CONREG; \ *wr = *rd | BWRITE; \ *rd = BREG void Hires (void); unsigned char getbyte (void); void main () { long lola; unsigned char buf[12]; register unsigned char *bp; lola = Super (0L); /* set supervisor mode to access hardware directly */ printf ("lola <0x%x>\n", lola); /* satisfy TC compiler */ Hires (); /* set PG into 'hires' mode */ for ( ; ; ) /* read 12 byte packets */ { bp = buf; *bp++ = getbyte (); delay (D2BYTES); *bp++ = getbyte (); delay (D2BYTES); *bp++ = getbyte (); delay (D2BYTES); *bp++ = getbyte (); delay (D2BYTES); *bp++ = getbyte (); delay (D2BYTES); *bp++ = getbyte (); delay (D2BYTES); *bp++ = getbyte (); delay (D2BYTES); *bp++ = getbyte (); delay (D2SLOW); *bp++ = getbyte (); delay (D2SLOW); *bp++ = getbyte (); delay (D2SLOW); *bp++ = getbyte (); delay (D2SLOW); *bp++ = getbyte (); delay (D2SLOW); printf ("Glove %-2x %-2x %-2x %-2x %-2x %-2x %-2x %-2x %-2x %-2x %-2x %-2x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]); } } unsigned char getbyte () { register unsigned char *rd = (unsigned char *)PSG; register unsigned char *wr = (unsigned char *)PSGW; register int i; register unsigned Glov = 0; /* prepare port b as output port */ setportb (); /* generate a reset (latch) pulse */ C1L0 (); C1L1 (); for (i = 1; i-- > 0; ); /* 5 us delay */ C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); return Glov; /* return the byte */ } void Hires () { register unsigned char *rd = (unsigned char *)PSG; register unsigned char *wr = (unsigned char *)PSGW; register unsigned char Glov = 0; register int i; /* read 4 bits from glove */ setportb (); /* generate a reset (latch) pulse */ C1L0 (); C1L1 (); for (i = 1; i-- > 0; ); /* 5 us delay */ C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* configure port a as input */ setporta (); /* read a bit */ *rd &= GDATA; Glov <<= 1; Glov += *rd >> 7; /* prepare port b as output port */ setportb (); /* generate a clock pulse */ C0L0 (); C1L0 (); /* end of read 4 bits */ /* prepare port b as output port */ setportb (); C1L0 (); delay (16950); /* 7212 us delay */ setportb (); C1L1 (); delay (4750); /* 2260 us delay */ /* prepare port b as output port */ setportb (); C1L0 (); /* Start of 1. Byte */ C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L1 (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L0 (); C0L0 (); C1L0 (); delay (D2BYTES); /* prepare port b as output port */ setportb (); C1L1 (); /* Start of 2. Byte */ C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L0 (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L1 (); C0L1 (); C1L1 (); delay (D2BYTES); /* prepare port b as output port */ setportb (); C1L0 (); /* Start of 3. Byte */ C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L1 (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L0 (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BYTES); /* prepare port b as output port */ setportb (); C0L0 (); /* start of 4. byte */ C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BYTES); /* prepare port b as output port */ setportb (); C0L0 (); /* start of 5. byte */ C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L1 (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L0 (); C0L0 (); C1L0 (); delay (D2BYTES); /* prepare port b as output port */ setportb (); C1L1 (); /* start of 6. byte */ C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L1 (); C1L1 (); delay (D2BYTES); /* prepare port b as output port */ setportb (); C1L0 (); /* start of 7. byte */ C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C0L0 (); C1L0 (); delay (D2BITS); /* prepare port b as output port */ setportb (); C1L1 (); C0L1 (); C1L1 (); delay (1090); /* 892 us delay (end of 7. byte) */ /* prepare port b as output port */ setportb (); C1L0 (); delay (60000); /* some time for the glove controller to relax */ } -------------------- cut here -------------------------------------- ----------------------------------------------------------------- Manfred Krauss, manfredo@opal.cs.tu-berlin.de Dept of Computer Science, Technical University of Berlin, Franklinstr. 28-29, W-1000 Berlin 10, Sekr. FR3-3, Germany ----------------------------------------------------------------- -- J. David Beutel 11011011 jdb9608@cs.rit.edu "I am, therefore I am."