[comp.sources.amiga] v91i069: IRC 1.0 - IR remote reader, Part01/05

amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (03/22/91)

Submitted-by: ron@vicorp.uucp (Ron Peterson)
Posting-number: Volume 91, Issue 069
Archive-name: devices/irc-1.0/part01

[ includes uuencoded iff file.  the file IRMasterImage.h was split to
  allow posting; combine all IRMI.h.?? files to IRMasterImage.h ...tad ]

This code is an uncompleted version of an IR remote controlled AREXX
utility.  It is uncompleted because no one wants to pay me to finish
it (great sadness...)  I have placed it in the public domain as an
example of how to read an IR remote control signal using the parallel
port.

The code runs as it is on an Amiga 1000 with 1.5M of RAM (I suspect it
will run in 512K also) when compiled using Lattice's V5.04 C compiler
and asm assembler.  I've only run it under V1.2 of the operating
system so I don't know how it will work under V1.3 and higher.  I've
pulled out all the AREXX specific code so that you don't have to have
AREXX to compile or run it.  The file Schematic.ilbm contains a simple
electronics schematic for hooking a Radio Shack IR receiver to the
parallel port on an A1000.  NOTE that if you have an Amiga other than
an A1000 you must change the +5Vdc and gnd connections and use a male
connector instead of a female.  I think the connections for other
machines is pin 14 = +5Vdc and pin 25 = gnd but don't trust my
memory---verify it!

ron@vicorp.com or uunet!vicorp!ron

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 5)."
# Contents:  BackGround.c LetGo.asm Schematic.uu VERSION.h irc.c irc.h
#   ircserver.asm linkirc readme tmp
# Wrapped by tadguy@ab20 on Fri Mar 22 10:16:01 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'BackGround.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'BackGround.c'\"
else
echo shar: Extracting \"'BackGround.c'\" \(827 characters\)
sed "s/^X//" >'BackGround.c' <<'END_OF_FILE'
X/*----------------------- B a c k G r o u n d . c ----------------------*/
X/* This routine draws the raised background for the user interface in   */
X/* IRMaster.c.  It was put into a seperate module so that the Image     */
X/* data could be seperated from the rest of the gadget, text, etc.      */
X/* structures in order to be able to fit everything into the available  */
X/* RAM space when compiling.                                            */
X/*----------------------------------------------------------------------*/
X
X#include "irc.h"
X#include "IRMasterImage.h"
X
Xextern struct RastPort *WRPort;
X
Xint BackGround()
X{
X   /*--- Draw raised background. */
X
X   DrawImage(WRPort, &Image53, (short)0, (short)0);
X
X   /*--- Draw border for help messages. */
X
X   DrawBorder(WRPort, &Border4, (short)0, (short)0);
X
X   return(0);
X}
END_OF_FILE
if test 827 -ne `wc -c <'BackGround.c'`; then
    echo shar: \"'BackGround.c'\" unpacked with wrong size!
fi
# end of 'BackGround.c'
fi
if test -f 'LetGo.asm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'LetGo.asm'\"
else
echo shar: Extracting \"'LetGo.asm'\" \(1365 characters\)
sed "s/^X//" >'LetGo.asm' <<'END_OF_FILE'
X;
X; LetGo.asm
X;
X; Reads from parallel port until detects a quiescent state.
X;
X        csect text
X
X	xdef _LetGo
X
X        xref _ciab
X        xref _NSamples
X
X        xref _Forbid
X        xref _Disable
X        xref _Enable
X        xref _Permit
X
Xdata1             equ   $bfe101
Xdir1              equ   $bfe301
X
X_LetGo
X;
X; Save registers on stack.
X;
X         MOVEM.L A2-A6/D2-D7,-(SP)  ;  Push Registers 
X;
X; Set up parallel port for reading.
X;
X         move.b   #0,dir1           * all lines read
X         move.b   #0,data1
X;
X; Read from parallel port until see no change for 10000 cycles.
X;
Xagain:  move.l   #$2710,_NSamples  ; Initialize the counter to BIG.
X                                   ; FFF0 * .1397us/clock * 50 clocks = .5sec
X        move.l   #0,d1             ; Zero the detection flag.
X
Xloop:   move.b   data1,d0          ; Move byte from parallel port to buffer.
X        andi.b   #1,d0             ; Mask off bit of interest.
X        bne      over
X        addq.l   #$1,d1            ; Found a zero = still getting signal.
Xover:   subq.l   #$1,_NSamples     ; Decrement counter.
X        bne      loop              ; Loop if haven't done 10000 yet.
X
X        tst.l    d1                ; Still receiving signal?
X        bne      again
X;
X; Clean up, restore registers and return.
X;
X        MOVEM.L (SP)+,A2-A6/D2-D7  ;  Pop Registers
X        RTS
X
X        END
END_OF_FILE
if test 1365 -ne `wc -c <'LetGo.asm'`; then
    echo shar: \"'LetGo.asm'\" unpacked with wrong size!
fi
# end of 'LetGo.asm'
fi
if test -f 'Schematic.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Schematic.uu'\"
else
echo shar: Extracting \"'Schematic.uu'\" \(6940 characters\)
sed "s/^X//" >'Schematic.uu' <<'END_OF_FILE'
Xbegin 666 Schematic.ilbm
XM1D]230``$S1)3$)-0DU(1````!0"@`#(``````$``0````H+`H``R$--05``:
XM```&````\/#P1%!05@```&@```````````%H```!0`#(``(`6@`)````"@``9
XM``H````````````````````````````````````````````````````!``(`-
XM`````````````````0`"``````````````````$``D-23D<````(```*J@`!M
XM`0%#4DY'````"```"JH``0$!0U).1P````@```JJ``$``$-23D<````(```*.
XMJ@`!``!#04U'````!```P`!"3T19```20K$`L0"Q`+$`L0"Q`+$`L0"Q`+$`S
XML0"Q`+$`L0`&``/W`,``!_X``'#\``-P``#`_```!_X``.#[``C`P>'AX```O
XM!_#]``!'^P`)<`'``,``P```P/H`_\$`P/T``@`"T_X```/^```P_```,/D`2
XM!`,```&P_``)`>'#,S,P```#,/T``,/[``0P`,`!X/T``,#Y`/_`_0#_`$;#U
XM8<'P`V'G8;,9YV'@`;'A\<';X`,9YV,Q\`&!YV`!X^`!X,-S<W````,!YV`!,
XMX?-AYV`#,>&QX,`!XS'!V>&!\`,QXS`#&?[`_0#_`$;#L,,``[`SLW-8,[,PV
XM`W,S`,,S,`-;,[-C``/#,[``,S`#,,/S\_````/#,[`#,,.S,[`#NS-S,,`#:
XM,[C#,#`#``,S,S`#6/[`_0#_`$;#,,'@`S#S,S-8\S/P`S/QX,,S,`-;,S/!%
XMX`&#,S``\S`#\,.SL[````,#,S`#,,,S\S`#6S,S\,`#\UC#,/`!X`,S,S`#-
XM6/[`_0#_`$;#,,`P`S,S`S&S,P,``S,`,,'C,`&S,P-@,`&#,P`#,S`&&,,SF
XM,S#```,#,P`#,-,S`P`#&S,S`,`&&QC!XS``,`'C,S`!L/[`_0!+``'G,>/@S
XM!S'?@=FQWX'@`=GCX>8S,`&QYX<SX`/!YX`!VS`&&_'AX>#```>!YX`!X&<Q/
XMYX`#&>'9X>`&&QGF,=@#X`#!X=@!L>'AX/T`[@`!`^#8``$#X/X``0.`]@"Q,
XM`+$``0`'_``#0```!_L``$?^``,#]AAP_0``</X``'#Z``%`P/L``!SC``$`4
XM`_P``\````/[``##_@`#PP88,/T``##^```P^@``P/H```SC`"4``V'C,>`!1
XM\>`!XV'CX=G@`?-AX`##XS&QX`'CX;`!V^&P`>'CX_[A#/'!X^'P`'CX;`#,S
XM?'CG``L``[`S,S``PS`#,[#^,Q,P`,.S,`/P,S-S,``S,W`#,S-P`_PS#3#`\
XMPS,S```,S-P`S,#,YP`C``,P\S/P`,,P`P,P\S,S\`##,_``P#'C,P``\S,P]
XM`S,S,`,#_C,.\P#`PS,QX``\S,P`S'C\YP`)``,S,>,``-,P`_XS%3'C``#39
XM,P``PS'C,S`#,S,P`>,S,`/],P<#,-##,S`P`/[,`P#,#,#G`#4`!S'8P>``2
XM8>`!YS';-C'@`&<QX``!X,'9X`';,=@&,S'8`>'C,S'AX&'AXS/@`';,=@!V&
XM^'CG`/0``0/@\@`!`^#1`,,``#_^`/\.!@`.`#\```+\`,,`#!F````&!@`&N
XM`!F```;\`,,`#1F/.P\&!@\&`!F/.P^`_0#[``G@``/C\`#Q^`/@^@``(-L`H
XM#!\!G8&&!AF&`!\9G8;\`/L`"6```;&8`9F``;#Z``!@VP`,&`>9AX8&'X8`V
XM&!F9AOP`_P`1\`&8\&#P`9F8`!GP`9@`\/'Q_O`"^/.PW0`-&!F8&88&&`8`,
XM&!F8!H#]`/\`#A@!W!AAF`&9\?AP&`&8`?R9`YAAF=C=``0\#OP.S_X/!``\7
XM#SP#_`#_``]X`:QX8?@!F9@`P!@!F`&!_ID$^8!AF9C+`!```9@!C9AA@`&Q&
XMF`&9F`&P`?V9!8&8:9F`8,P`_P`8[`&,[/#P`^/P`?CP`^``\/&9F/#P,//`Q
XM8,P`L0"Q`+T`_O\`P/D`O0`#@```0/D`O0`%@```0?!X^P"]``6```!`V,S[!
XM`+T`!8>``$#,W/L`O0`%C,``0,S\^P"]``6`P`!`S.S[`+T`!8.``$#8S/L`6
XMY```!]O_!88``$'P>/L`Y```!-L``XS``$#Y`.0```3;``./P`!`^0#D```$U
XMVP`#@```0/D`Y```!-L``X```$#Y`.0```3;``.```!`^0#D```$VP`#@```;
XM0/D`Y```!-L``X```$#Y`.0```3;``.```!`^0#D```$VP`#@```0/D`Y```:
XM!-L``X```$#Y`.0```3;``.```!`^0#D```$VP`#@```0/D`Y```!-L``X``?
XM`$#Y`.0```3;``.```!`^0#D```$VP`&@```0,'G,/P`Y``!'\#<``:#!X!!&
XMXS,P_`#D``%_\-P`!H<,P$'F`V#\`.0``?_XW``&@PW`0S8#P/P`Y`#:_P:#=
XM#\!#]@-@_`#D``'_^-P`!H,.P$8;,S#\`.0``7_PW``&@PS`1AGG,/P`Y``!2
XM'\#<``./QX!`^0#D```$VP`#@```0/D`Y```!-L``X```$#Y`/L``!_Y__,`0
XM``3;``.```!`^0#[``@0`PP``&```8'S```$VP`#@```0/D`^P`($`&8\9CX:
XM``.!\P``!-L``X```$#Y`/L`"!`!F9F88``!@?,```3;``.```!`^0#[``@0S
XM`/&9F&```8'S```$VP`#@```0/D`^P`($`#QF9AH``&!\_\`_-L``X```$#YV
XM`/L`"!``8/#L,``!@<P``X```$#Y`/L``!#[``$'X<P``X```$#Y`/L``!#Z%
XM```!S``#@```0/D`^P``$/H```',``.```!`^0#[``00``'[#/X```',``.`\
XM``!`^0#[``@0`&&##````\',``.```!`^0#[``@0`&'QF```!F',``.```!`[
XM^0#[``00`?@9F/X``&',``.```!`^0#[``@0`&`8\````</F_^<``X```$#Y@
XM`/L`"!``89CP```#`><```'G``.```!`^0#[``@0``#P8```!F'G```!YP`#G
XM@```0/D`^P``$/L``0?AYP```><``X```$#Y`/L``!#Z```!YP```><``X``+
XM`$#Y`/L``!#Z```!YP```><``X```$#Y`/L``!#^```X_@```><```'G``.`<
XM``!`^0#[```0_@`$&````\'G```!YP`#@```0/D`^P`($`#M\-@```9AYP``#
XM`><``X```$#Y`/L`!!`!F9FX_@``8><```'G``.```!`^0#[``@0`9F9F```F
XM`</8__4``X```$#Y`/L`!!``\9F8_@``8><```'T```!]0`#@```0/D`^P`(M
XM$`,9F.P```9AYP```?0```'U``.```!`^0#[``(0`?#]``$#P><```'T```!"
XM]0`#@```0/D`^P``$/H```'G```!]````?4``X```$#Y`/L``!#Z```!YP``R
XM`?0```'U``.```!`^0#[```?^?_G```!]````?4`!H```$```'#\`-@```'T*
XM```!]0#_AP2`0```,/P`V````?0```'U``:,S,!!V^&P_`#8```!]````?4`Y
XM!H#`P$,S,W#\`-@```'T```!]?__@P2`0S,S,/P`V````><`!H8&`$'C,S#\-
XM`-@```'G``:,S,!&,S'8_`#8```!YP`$C\_`0^#Z`/X``0/._0`'`\_!AF?C2
XMS##I```!YP`#@```0/D`_@`!!F;]``<&9F.&9@9F8.D```'G``.```!`^0#^*
XM``T'!L/.S<`,!F&&9\!CP.D```'G``.```!`^0#^``T#AV!G9F`,Y\&&8&'!F
XM@.D```'G``.```!`^0#]``SF8>9F8`QF`89@8P/`Z0```><``X```$#Y`/X`3
XM``;^9@4'P`9F`8;^9@!@Z0```><``X```$#Y`/X`#0/.8[\&``/O!^/CQ^PP@
XMZ0```><``X```$#Y`/H```_@```!YP`#@```0/D`V````><``X```$#Y`-@`N
XM``'G``.```!`^0#^``,'X`'`_0`&X`_````!@.H```'G``.```!`^0#^``,!0
XM@`-@_0`"8`9@Y@```><``X```$#Y`/X`"@&'PP[#SL/#8`9C_L,#AF/.P.T`;
XM``'G``6```!``_#[`/X`$0&&9X=@9V9FX`?&9F9AAF9G8.T```'G`/^'`H!`<
XMP_H`_@`1`89C!F'F9^9@!L?F!^&&9^9@[0```><`!8S,P$##X/L`_@`0`89C&
XM!@9F!@9@!F8&9@&#Q@;L```!Y_\%@,#`0_`P^P#^``H'YF>/`[\#P[`.,_[#A
XM`L&#S]$`_X,#@$#`,/L`O0`%A@#`0,,P^P"]``6,S,!``>#[`+T``X_'@$#Y1
XM`/T`$\_``.&```/.```.``/'X<`!@\?CU0`#@```0/D`_@`5`89@`&````9F/
XM```&``9F8P`#AF9A@-8``X```$#Y`/X`%0,&8\-C@\`'!L/#QF``8&8``8!@_
XM8,#6``.```!`^0#^`!(#!\!FX89@`X=@9F;``<#'Q^&!_L#6``.```!`^0#^N
XM`!4#!L'F889@`.9AY@>``P&&8`&`88#`U@`#@```0/D`_@`'`89F9F&&8`;]`
XM9@G`!F&&8`&&88&`U@`#@```0/D`_0`3SC.SL\/``\YCL\Y@!^&#P`?CP8/5T
XM``.```!`^0"]``.```!`^0"]``.```!`^0"]``.```!`^0"]``.```!`^0"]=
XM``.```!`^0"]``.```!`^0"]``.```!`^0"]``.```!`^0#^```_^```!_X`A
XM``S\```<]@`%!`!P```$Y@`#@```0/D`_@``#/@```/X```,]@`%#``P```,%
XMY@#^_P#`^0#^``(,`';^'O\S'AX^&P`S'QP^'8`>``P>/AV`/AYV=AXQ@!\S6
XM-AX`'Q[;`/X``@P`._XS#CN[LS,W`#,P##,S``,`#/XS#@`S`SL[,S6`##,[V
XM,P`,,]L`_@`4#``S/S`S-;6_,S,`,QX,,S,`#P`,_C,"`#,/_C,(-8`,,S,_!
XM``PSVP#^`"8,`#`P,S,QL;`S,P`S`PPS'@`S``PS,QX`,S,P,#,;``TS,S``5
XM#3/;`/X``C\`>/X>(#&QGC,=@!V^'C-C`!V`'AXS8P`S'?AX'AL`!AV>'@`&Z
XM'ML`[@``/OL``#[,`+$`L0#^``D,```<``0```1P^P``#/T```[[``IP#```&
XM!``<#`!P!-L`^P`&#``,```,,/8``!O[```P_@`&#``,```P#.P``0'\_@`&2
XM<``!\?AX_/P`_@`,'!\>#!X?'@`?-AX`=OX>%APS'G8`&'8>,P`>,S8<'CX?/
XM``P<';8?ZP``S/X`!C```-C,S,#\`/X`#`PP,PP###,`##LS`#O^,Q8,,S,[A
XM`#P[,SN``SN[##,S#``,##,[#.L`"L!XS'@P>`#,S`SX_`#^`"8,'C,,#PP_&
XM``PS/P`S/S`_##,_,P`8,S,U@`\ULPP_,PP`#`PS,PSK``KPS.X,,,P`S/@XQ
XM#/P`_@`G#`,S##,-,``-,S``,#`S,`P>,#``&#`S,8`S,;,,,#,-``P,'C,-=
XM#.P`"L#\UCPP_`#,S&`,_`#^``P>/AX>'88>``9S'@!X_1X6#!YX`#QX'C&`$
XM';&>'AXS!@`>'F-S!@SL`/_`!<;,,,``V/[,_`#:```^Z@`+`>!XQG9X>`'Q9
XM^/QX_`"Q`/X`!QYP#``<!P`'_@`!<!S\`!,<!P`,!`!P```$`'``!``,```,O
XM!-H`_@`',S````P#``/^``$P#/P`#0P#``P,`#````P`,``,_0#_#-H`_@`E`
XM.#8<'@P;'AL`'AXV#!X`,9XS#!L^&!\`-C-V'P`V,Q\`'!\^&!_K``,!\``0G
XM]`#^`"4<.PPS##<S-P`S`SL,,P`ULS,,-S,`#``[,SL,`#LS#``,,#,`#.H`[
XM`M@`,/0`_@`7!S,,/PPS/S,`,`\S##\`-;,S##,S``P`_C,*#``S,PP`#!XSU
XM``SJ``7,`'S-N'CW`/X`_S,&##`,,S`S`/XS&0PP`!LS,PPS,P`-`#,S,`T`T
XM,S,-``P#,P`-Z@`"S/PP_LSW`/X``1YS_AX@'9X=@!X=GAX>`!L>'9X=LP`&J
XM`',=^`8`'AV&`!X^,P`&Z@`%S``PS,S\]P#!``78`#1X^,#W`,(`!@'P`!@P4
XMP'CW`+X``>'@]@#T```._0`#<```!,<`]```&_T``S````S'`/X``#[^'O\?J
XM$1YV,P`8'G8`'S8>=A\`=C,^']P``'C\```0^`#^`/TS_S`1`SLS`#PS.P`PC
XM.S,[#``[,S,PW```S/P``##X`/X`#C,_,#\>'@\S,P`8,S,`'OXS`0P`_C,`[
XM'MT`"0&`>/CX>'A\>=CZ`/X`&#,P,S`#`S,P'@`8,S```S,S,`T`,#,S`PS>K
XM``$!@/S,`C#,[/H`_@``,_X>_SX2'?@,`#P>>``^<QYX!@!X';,^#-X``0&`\
XM_LP$_,`PS,SZ`/8``#C-`/W,!,#,-,S`^@#!`/]X_\S_>`(8>>#Z`+$`L0"Q4
X3`+$`L0"Q`+$`L0"Q`+$`L0"Q`,#,%
X``
Xend
Xsize 4924
END_OF_FILE
if test 6940 -ne `wc -c <'Schematic.uu'`; then
    echo shar: \"'Schematic.uu'\" unpacked with wrong size!
fi
# end of 'Schematic.uu'
fi
if test -f 'VERSION.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'VERSION.h'\"
else
echo shar: Extracting \"'VERSION.h'\" \(26 characters\)
sed "s/^X//" >'VERSION.h' <<'END_OF_FILE'
X
X#define VERSION " V1.0"
X
END_OF_FILE
if test 26 -ne `wc -c <'VERSION.h'`; then
    echo shar: \"'VERSION.h'\" unpacked with wrong size!
fi
# end of 'VERSION.h'
fi
if test -f 'irc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'irc.c'\"
else
echo shar: Extracting \"'irc.c'\" \(27153 characters\)
sed "s/^X//" >'irc.c' <<'END_OF_FILE'
X/*------------------------------- i r c . c  -------------------------------*/
X/* Experimental interrupt handler.                                          */
X/* This routine sets up a level 2 interrupt server that is triggered by the */
X/* ACK pin of the parallel port going low.  The interrupt server then uses  */
X/* Timer B in CIA-B to time reading in data from the parallel port.         */
X/* The ACK and one data input pin on the parallel port are tied             */
X/* together by the hardware I built.  Initially the ACK interrupt is        */
X/* enabled and the software sits and waits for something to happen.         */
X/*                                                                          */
X/* NEED TO CHECK RESOURCES  ---- FREEMEM!!!!!!!!!!!!!!!!*/
X/*--------------------------------------------------------------------------*/
X 
X/*--- Includes and Defines. */
X
X#include "irc.h"
X#include "IRMaster.h"   /* Definitions of Screen, Window and gadgets. */
X
X/* DBG = 1 --> Turn on debug printf's, DBG = 0 --> Turn off debug printf's. */
X#define DBG 1
X/* Set DEBUG to 0 to comment out code related to opening screen and window.*/
X#define DEBUG 1
X
X#define NOERROR 0
X#define ERROR 1
X/*--- NSAMPLES is the number of data samples to be read into buffer. */
X#define NSAMPLES 3000
X/*--- TOLERENCE is the number of samples difference that is tolerated in */
X/*--- order to match two patterns. */
X#define TOLERENCE 50
X
X/*--- External system variables. */
X
Xextern struct Custom custom;
Xextern struct CIA ciab;
X
Xextern struct GfxBase *GfxBase;
Xextern struct IntuitionBase *IntuitionBase;
Xextern struct WBStartup *WBenchMsg;  /* For Workbench startup. */
X
X/**********************************************************/  
X/***************** Timer B Interrupt code *****************/
X/**********************************************************/  
X/*
X   Update Timer every TIME_SLICE microseconds.
X   TIME_SLICE = 1.397 * (desired # of microseconds) [71 = 100us]
X   71, 50 work.
X*/
X#define TIME_SLICE ((unsigned short)35)
X
X/* Defines to make the code more readable. */
X
X#define ciatlo		ciab.ciatblo
X#define ciathi		ciab.ciatbhi
X#define ciacr		ciab.ciacrb
X#define ciaicr		ciab.ciaicr
X
Xint TimerSigBit = -1;   /* Allocated signal bit. */
XULONG TimerSigMask;      /* TimerSigBit converted into a mask. */
Xstatic struct Library *CIAResource = NULL;
Xstruct Task *thisTask;
X
Xint NSamples;           /* Number of samples in buffer. */
X
Xint SetUpTimer()
X{
X   char temp;
X   unsigned short micros;
X
X   /*--- Check to see if timer B in CIA-B is already in use. */
X   /*--- If START bit is set timer is probably being used. */
X
X#if DBG
X   printf("\n Timer B control register = %X",ciab.ciacrb);
X#endif
X   if(ciab.ciacrb & 0x01)
X   {
X      printf("\n Timer B is already allocated.  Proceding anyway.");
X   }
X
X   /*--- Set latched value for timer to count down from. */
X
X   micros = TIME_SLICE;
X#if DBG
X   printf("\n Sampling interval = %d * 1.397 microseconds", micros);
X#endif
X   ciatlo = micros & 0xFF;
X   ciathi = micros >> 8;
X
X   /*--- Get ID for this task so can send it a signal. */
X
X   thisTask = NULL;
X   thisTask = FindTask(NULL);
X   if(thisTask == NULL)
X   {
X      printf("\n Error - Can't find this task ID.");
X      return(ERROR);
X   }
X
X   /*--- Get a signal bit. */
X
X   if((TimerSigBit = AllocSignal(-1L)) == -1)
X   {
X      printf("\n Timer: AllocSignal failed.");
X      StopTime();  /* Deallocate resources. */
X      return(ERROR);
X   }
X   TimerSigMask = 1L << TimerSigBit;
X
X   /*--- Open the CIA resource. */
X
X   if((CIAResource = OpenResource(CIABNAME)) == NULL)
X   {
X      printf("\n Timer: Couldn't open %s.", CIABNAME);
X      StopTime();  /* Deallocate resources. */
X      return(ERROR);
X   }
X
X   /*--- Interrupts have been enabled so may already */
X   /*--- have an interrupt.  So do this... */
X
X   ciab.ciacrb &= ~CIACRBF_START;	/* stop timer */
X
X   temp = ciaicr;  /* Read IRC register to clear interrupt. */
X
X   SetSignal(0, TimerSigMask);	/* clear signal */
X
X#if DBG
X   printf("\n About to set RUNMODE");
X#endif
X   ciacr &= ~CIACRBF_RUNMODE; /* Set it to reload upon underflow. */
X   ciacr &= ~CIACRBF_PBON; /* Output line PB7 is left alone. */
X   ciacr &= ~CIACRBF_INMODE0; /* Count clock pulses. */
X   ciacr &= ~CIACRBF_INMODE1; /* Count clock pulses. */
X
X#if DBG
X   printf("\n About to strobe LOAD");
X#endif
X   ciacr |= CIACRBF_LOAD; /* Strobe Load to latch in countdown value. */
X
X#if DBG
X   printf("\n About to enable timer b interrupts");
X#endif
X   ciaicr = 0x7D;  /* Disable all other CIA-B interrupts. */
X   ciaicr = CIAICRF_SETCLR|CIAICRF_TB;  /* Enable timer B interrupts. */
X#if DBG
X   printf("\n Enabled timer b interrupts");
X#endif
X
X   return(NOERROR);
X}
X
Xint StopTime()
X{
X   if(thisTask != NULL)
X   {
X      /*--- Disable timer B interrupts. */
X
X#if DBG
X      printf("\n Stopping timer B.");
X#endif
X      ciaicr = CIAICRF_TB;
X
X      /*--- Halt timer. */
X
X      ciacr &= ~CIACRBF_START;
X
X      /*--- Free resources. */
X
X      if(TimerSigBit != -1)
X      {
X#if DBG
X         printf("\n Freeing signal bit.");
X#endif
X         FreeSignal(TimerSigBit);
X      }
X   }
X
X   return(NOERROR);
X}
X
X/**********************************************************/  
X/***************** LEVEL 2 Interrupt code *****************/
X/**********************************************************/  
X
Xextern void ircserver();
Xstruct Interrupt intrpt;
X
Xint AddINT2Server()
X{
X   /*--- init NODE structure */
X
X   intrpt.is_Node.ln_Type = NT_INTERRUPT;
X   /* Was 0 but glasses flickered.  3 fixed it. */
X   intrpt.is_Node.ln_Pri  = 127;
X   intrpt.is_Node.ln_Name = "WWB";
X   intrpt.is_Code        = ircserver;
X   intrpt.is_Data        = NULL;
X
X#if DBG
X   printf("\n About to add interrupt server...");
X#endif
X
X   AddIntServer(INTB_PORTS, &intrpt);		/* Add server to chain */
X
X#if DBG
X   printf("\n Added interrupt server.");
X#endif
X
X   return(NOERROR);
X}
X
X
Xint RemoveServer()
X{
X   RemIntServer(INTB_PORTS, &intrpt);
X
X   return(NOERROR);
X}
X
X
X/**********************************************************/  
X/************************** MAIN **************************/
X/**********************************************************/  
X
Xunsigned char *buffer;  /* Pointer to storage for data to be read in. */
Xunsigned char zuffer[NSAMPLES];  /* Storage for data to be read in. */
Xunsigned char pattern[20][NSAMPLES];  /* Stored signal patterns. */
Xchar *address, mask;
X
Xstruct Screen *Screen = NULL;
Xstruct Window *Window = NULL;
Xstruct RastPort *WRPort;
Xstruct ViewPort *WVPort;
X
Xstruct IntuiMessage *message;
XULONG class;
XUSHORT code;
Xstruct Gadget *igad;
XUSHORT gadget_id;
Xextern int BackGround();
Xint helptxt();
Xint IRButtonOff();                 /* Unhighlight button. */
Xint IRButtonOn();                  /* Highlight button. */
Xint IRButtonLabel();               /* Relabel button. */
Xint GetPattern();                  /* Get signal pattern. */
Xint DisplayPattern();              /* Draw the signal pattern. */
Xint DPattern();                    /* Debug. */
X
X/*--- Buffers for area fill and text. */
X
XWORD chip areaArray[100];  /* Max of 20 vertices times 5 words per vertex. */
Xstruct AreaInfo myAreaInfo;
XPLANEPTR workspace;
Xstruct TmpRas myTmpRas;
X
X#define NOTHING 0
Xint active[21] =  /* Used to remember which buttons have patterns. */
X{ 
X   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
X   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
X   FALSE
X};
X
X
X
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X   int it, error, iz, is, try;
X   int diff[4], match, smallest;
X   BOOL exitflag;
X   int mode;  /* Current mode of program (LEARN, NOTHING, etc. ) */
X   int IRButtonSelected = -1;         /* Index of button currently selected. */
X
X   /*--- Ignore CTRL-C and CTRL-D. */
X
X   signal(SIGINT, SIG_IGN);
X
X   /*--- Open graphics and Intuition Libraries. */
X
X   GfxBase = NULL;
X   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33);
X   if(GfxBase == NULL)
X   {
X      printf("\n Error opening graphics library.");
X      goto ShutDown;
X   }
X
X   IntuitionBase = NULL;
X   IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 33);
X   if(IntuitionBase == NULL)
X   {
X      printf("\n Error opening Intuition library.");
X      goto ShutDown;
X   }
X
X   /*--- Open a new screen. */
X
X   Screen = (struct Screen *) OpenScreen(&NewScreenStructure); 
X   if(Screen == 0L)
X   {
X      printf("\n Error opening a new screen.");
X      goto ShutDown;
X   }
X
X#if DEBUG
X   /*--- Open window in screen. */
X
X   NewWindowStructure1.Screen = Screen;
X 
X   Window = (struct Window *) OpenWindow(&NewWindowStructure1);
X 
X   if(Window == 0L)
X   {
X      printf("\nError opening a new window");
X      goto ShutDown;
X   }
X
X   /*--- Get pointers to window structures. */
X
X   WRPort = Window->RPort;   /* Get pointer to windows' RastPort. */
X   WVPort = (struct ViewPort *)ViewPortAddress(Window); /* Get pointer to window viewport. */
X
X   /*--- Set up area fill and text work buffers. */
X
X   InitArea(&myAreaInfo, &areaArray[0], 20);
X   WRPort->AreaInfo = &myAreaInfo;
X
X   workspace = AllocRaster(640, 200);
X   if(workspace == 0)
X   {
X      printf("\n Error - No space for temporary raster.");
X      goto ShutDown;
X   } else
X   {
X      InitTmpRas(&myTmpRas, workspace, RASSIZE(640,200));
X      WRPort->TmpRas = &myTmpRas;
X   }
X
X   /*--- Set color map. */
X
X   LoadRGB4(WVPort, Palette, (SHORT)16);
X
X   /*--- Draw raised background areas. */
X
X   BackGround();
X
X   /*--- Redraw the gadgets on top of the raised background. */
X
X   RefreshGadgets(&ARexx, Window, 0);
X#endif /*DEBUG*/
X
X   /*--- Allocate the parallel port resource so that other tasks know it  */
X   /*--- is taken. (This might not be a good idea.  Online! allocates the */
X   /*--- the parallel port and this prevents me from doing                */
X   /*--- "copy file to par:" in a seperate window.  So leave it out for   */
X   /*--- now.  User will know if one program walks over another.          */
X
X   /*****************
X   MR_ALLOCMISCRESOURCE(MR_PARALLELPORT, "IRMaster");
X   MR_ALLOCMISCRESOURCE(MR_PARALLELBITS, "IRMaster");
X   *****************/
X
X   /*--- Set up pointer to data buffer for SoftHandler(). */
X   /*--- Assembler doesn't seem to recognize zuffer but DOES buffer. */
X
X   buffer = &zuffer[0];
X#if DBG
X   printf("\n buffer = %X", buffer);
X#endif
X
X   /*--- Set up all the interrupt servers. */
X
X   AddINT2Server();
X
X   error = SetUpTimer();
X   if(error)goto Fini;
X
X   /*--- Explicitly enable level6 and level2 interrupts (even though */
X   /*--- they already seem to be enabled by default).                */
X
X/********* Causes sometimes guru.
X   Disable();
X   custom.intena |= INTF_SETCLR | INTF_EXTER;
X   custom.intena |= INTF_SETCLR | INTF_SOFTINT;
X   Enable();
X*********/
X
X#if DBG
X   /* This is slightly dangerous since it might clear any pending interrupts. */
X   /*printf("\n Enabled interrupts are: %X", custom.intenar);*/
X#endif
X
X   /*--- Set address for IRC register (used in GetSample.) */
X
X   address = (char *)0xBFED01;/* Address of the Interrupt Control Register in 8520-A */
X
X   /*--- MAIN PROGRAM LOOP. */
X   /*--- Get messages from window until user presses CloseWindow gadget. */
X
X#if DEBUG
X   exitflag = FALSE;
X   mode = NOTHING;
X   while(exitflag == FALSE)
X   {
X      /*--- If in DOIT mode wait for IR input. */
X 
X      if(mode == DOIT)
X      {
X         /*--- Wait for user to press a button. */
X
X         GetSample();
X
X         /*--- Match input to stored samples. */
X
X         match = find_match();
X      }
X
X      /*--- Check for user action. */
X
X      message = (struct IntuiMessage *)GetMsg(Window->UserPort);
X      if(message != 0)
X      {
X         class = message->Class;
X         code = message->Code;
X         igad = (struct Gadget *)message->IAddress;/*get pointer to gadget */
X         ReplyMsg((struct Message *)message);
X
X         if(class == GADGETUP)
X         {
X            gadget_id = igad->GadgetID;   /* get my gadget code */
X            switch(gadget_id)
X            {
X               case COMMANDSTR3:
X#if DBG
X                  printf("COMMANDSTR3\n");
X#endif
X                  break;
X
X               case COMMANDSTR1:
X#if DBG
X                  printf("COMMANDSTR1 = %s\n", commandstr1SIBuff);
X#endif
X                  /*--- Change the label on the button. */
X
X                  IRButtonLabel(commandstr1SIBuff, IRButtonSelected);
X
X                  /*--- Prompt user for next action. */
X
X                  helptxt("Now press the button on your handheld IR remote control",
X                     "that you want memorized.");
X
X                  /*--- Get verified signal sample from the IR receiver. */
X
X                  GetPattern(IRButtonSelected);
X
X                  /*--- Remember which buttons have patterns stored. */
X
X                  active[IRButtonSelected] = TRUE;
X
X                  /*--- Unhighlight the control button. */
X
X                  IRButtonOff(&IRButtonSelected);
X                  mode = NOTHING;
X
X                  break;
X
X               case COMMANDSTR2:
X#if DBG
X                  printf("COMMANDSTR2\n");
X#endif
X                  break;
X
X              default:
X                  break;
X            } /* switch(gadget_id) */
X         } /* if(GADGETUP) */
X
X         if(class == GADGETDOWN)
X         {
X            gadget_id = igad->GadgetID;   /* get my gadget code */
X            switch(gadget_id)
X            {
X               case EXIT:
X#if DBG
X                  printf("EXIT\n");
X#endif
X                  goto Fini;
X                  break;
X
X               case AUTHOR:
X#if DBG
X                  printf("AUTHOR\n");
X#endif
X                  break;
X
X               case DOIT:
X#if DBG
X                  printf("DOIT\n");
X#endif
X                  mode = DOIT;
X                  break;
X
X               case GETSET:
X#if DBG
X                  printf("GETSET\n");
X#endif
X                  break;
X
X               case SAVESET:
X#if DBG
X                  printf("SAVESET\n");
X#endif
X                  break;
X
X               case LEARN:
X#if DBG
X                  printf("LEARN\n");
X#endif
X                  helptxt("Press one of the twenty control buttons above.","");
X                  mode = LEARN;
X                  break;
X
X               case AREXX:
X#if DBG
X                  printf("AREXX\n");
X#endif
X                  break;
X
X               case IR20:
X               case IR19:
X               case IR18:
X               case IR17:
X               case IR16:
X               case IR15:
X               case IR14:
X               case IR13:
X               case IR12:
X               case IR11:
X               case IR10:
X               case IR9:
X               case IR8:
X               case IR7:
X               case IR6:
X               case IR5:
X               case IR4:
X               case IR3:
X               case IR2:
X               case IR1:
X                  /*--- Unhighlight any currently selected button. */
X
X                  IRButtonOff(&IRButtonSelected);
X
X                  /*--- Set current button to highlight and highlight it. */
X
X                  IRButtonSelected = (gadget_id - IR1) + 1;
X
X                  IRButtonOn(IRButtonSelected);
X#if DBG
X                  printf("IR-%d\n", (gadget_id - IR1) + 1);
X#endif
X                  if(mode == LEARN)
X                  {
X                     /*--- Prompt user. */
X
X                     helptxt("Enter the label name for the control button,",
X                        "then press RETURN.");
X                  } else
X                  {
X                     helptxt("Please choose a function button first.", "");
X                  }
X                  break;
X
X
X               default:
X                  mode = NOTHING;
X                  printf("Error - Got a hit on an unknown gadget\n");
X                  printf(" Gadget id was: hex: %X  decimal: %d\n", gadget_id,
X                     gadget_id);
X                  break;
X            } /* switch(gadget_id) */
X         } /* if(message) */
X      } /* if(class...) */
X   } /* while(GetMsg) */
X#endif /*DEBUG*/
X
X
X#if DBG
X   printf("\n Timer B control register = %X",ciab.ciacrb);
X   printf("\n buffer = %X", buffer);
X#endif
X
X   /*--- Shut down timer B */
X
XFini:
X   StopTime();
X
X   /*--- Turn off the 8520's recognition of the ACK as an interrupt. */
X
X   mask = 0x10; /* Hex 10 = 00010000 Should disable the 8520 FLAG interrupt. */
X   *address = mask;  /* Disable the interrupt. */
X
X   /*--- Remove the level2 interrupt server from server chain. */
X
X   RemoveServer();
X
X   /*--- Exit cleanly. */
X
XShutDown:
X
X   /*--- Deallocate parallel port resource. Commented out for reasons above. */
X
X   /*****************
X   MR_FREEMISCRESOURCE(MR_PARALLELPORT);
X   MR_FREEMISCRESOURCE(MR_PARALLELBITS);
X   *****************/
X
X   /*--- Close window and screen. */
X
X#if DEBUG
X   if(Window)CloseWindow(Window);
X   if(Screen)CloseScreen(Screen);
X#endif /*DEBUG*/
X
X   /*--- Close libraries. */
X
X   if(GfxBase)CloseLibrary((struct Library *)GfxBase);
X   if(IntuitionBase)CloseLibrary((struct Library *)IntuitionBase);
X
X   /*--- Free allocated memory. */
X#if DEBUG
X   if(workspace != 0)FreeRaster(workspace, 640, 200);
X#endif /*DEBUG*/
X
X   return(0);  /* To keep compiler happy. */
X} /* End of main(). */
X
X
X
Xint GetSample()
X{
X   int idx;
X
X   /*--- Set up for taking another sample. */
X
X#if DBG
X   printf("\n Setting up for next sample.");
X#endif
X   for(idx=0; idx<NSAMPLES; idx++)zuffer[idx] = 0; /* Zero the buffer. */
X   NSamples = NSAMPLES;  /* Reset sample counter. */
X   buffer = &zuffer[0];  /* Reset pointer to start of buffer. */
X
X   ciacr |= CIACRBF_LOAD; /* Strobe Load to latch in countdown value. */
X   ciaicr = CIAICRF_SETCLR|CIAICRF_TB;  /* Enable timer B interrupts. */
X   mask = *address;  /* Clear any pending interrupts. */
X   mask = 0x90;  /* Hex 90 = 10010000 Should enable the 8520 FLAG interrupt. */
X   *address = mask;  /* Enable the ACK interrupt. */
X
X   /*--- Interrupts are now all armed and dangerous.  */
X   /*--- Wait until data is ready. */
X
X#if DBG
X   printf("\n Waiting...press a button.");
X#endif
X   Wait(TimerSigMask);  /* Wait for full buffer. */
X
X   /*--- Stop timer B from counting. */
X
X#if DBG
X   printf("\n Stopping timer B");
X#endif
X   ciacr &= ~CIACRBF_START;
X
X   /*--- Wait until user lets go of button. */
X
X   LetGo();
X
X   return(0);
X}
X
X#if DEBUG
X/*-------------------- h e l p t x t . c ------------------------*/
X/* This routine clears the help message area and writes a new    */
X/* message into it.                                              */
X/*---------------------------------------------------------------*/
X
Xint helptxt(msg1, msg2)
X  char *msg1, *msg2;
X{
X
X   /*--- Erase any old text that exists. */
X
X   SetAPen(WRPort, 0);
X   RectFill(WRPort, 24, 163, 617, 188);
X
X   /*--- Write new text. */
X
X
X   SetAPen(WRPort, 1);
X   Move(WRPort, 25, 173);
X   Text(WRPort, msg1, strlen(msg1));
X   Move(WRPort, 25, 185);
X   Text(WRPort, msg2, strlen(msg2));
X
X   return(0);
X}
X
X/*---------------------- I R B u t t o n s O f f . c ---------------------*/
X/* This routine unhighlights any currently selected control button.       */
X/*------------------------------------------------------------------------*/
X
Xint IRButtonOff(button)
X  int *button;  /* Button to turn off. */
X{
X   USHORT position;
X
X   if((*button >= 1) && (*button <= 20))
X   {
X      /*--- Remove currently selected gadget from list. */
X
X      position = RemoveGList(Window, IR[*button-1], 1L);
X
X      /*--- Unselect the gadget. */
X
X      IR[*button-1]->Flags &= (~SELECTED);
X
X      /*--- Put the gadget back into the same place in the list. */
X
X      AddGList(Window, IR[*button-1], (LONG)position, 1L, NULL);
X
X      /*--- Refresh gadgets on display. */
X
X      RefreshGList(IR[*button-1], Window, NULL, 1L);
X
X      /*--- Set currently selected gadget to none. */
X
X      *button = -1;
X   }
X
X   return(TRUE);
X}
X
X
X/*---------------------- I R B u t t o n s O n . c -----------------------*/
X/* This routine highlights the currently selected control button.         */
X/*------------------------------------------------------------------------*/
X
X
Xint IRButtonOn(button)
X  int button;  /* Button number to highlight. */
X{
X   USHORT position;
X
X   if((button >= 1) && (button <= 20))
X   {
X      /*--- Remove the selected gadget from list. */
X
X      position = RemoveGList(Window, IR[button-1], 1L);
X
X      /*--- Select the gadget. */
X
X      IR[button-1]->Flags |= SELECTED;
X
X      /*--- Put the gadget back into the same place in the list. */
X
X      AddGList(Window, IR[button-1], (LONG)position, 1L, NULL);
X
X      /*--- Refresh gadgets on display. */
X
X      RefreshGList(IR[button-1], Window, NULL, 1L);
X   }
X
X   return(TRUE);
X}
X
X/*------------------- I R B u t t o n L a b e l . c -------------------*/
X/* This routine relabels the selected button.                          */
X/*---------------------------------------------------------------------*/
X
Xint IRButtonLabel(buffer, button)
X  UBYTE *buffer;
X  int button;
X{
X   USHORT position;
X
X   if((button >= 1) && (button <= 20))
X   {
X      /*--- Remove the selected gadget from list. */
X
X      position = RemoveGList(Window, IR[button-1], 1L);
X
X      /*--- Change the label. */
X
X      strncpy(IR[button-1]->GadgetText->IText , (char *)buffer, 7);
X
X      /*--- Put the gadget back into the same place in the list. */
X
X      AddGList(Window, IR[button-1], (LONG)position, 1L, NULL);
X
X      /*--- Refresh gadgets on display. */
X
X      RefreshGList(IR[button-1], Window, NULL, 1L);
X   }
X
X   return(TRUE);
X}
X
X
X/*------------------ G e t P a t t e r n . c ---------------------*/
X/* This routine gets a signal sample from the IR receiver and     */
X/* then tries up to four times to verify it.                      */
X/*----------------------------------------------------------------*/
X
XGetPattern(button)
X  int button;  /* Currently selected control button. */
X{
X   int it, iz, is, try;
X   int diff[4], match, smallest;
X
X#if DBG
X   printf("\n\n **** Storing pattern %d ****", button);
X#endif
X
X   /*--- Get a sample. */
X
X   GetSample();
X
X   /*--- Plot data on screen. */
X
X   helptxt("Data received.", "");
X   /*DPattern(button, 1);*/
X   DisplayPattern(button, 0);
X
X#if DBG
X   printf("\n NSamples=%d", NSamples);
X#endif
X
X   /*--- Transfer data to storage. */
X
X#if DBG
X   printf("\n Xferring to pattern memory.");
X#endif
X   for(iz=0; iz<NSAMPLES; iz++)
X   {
X      pattern[button-1][iz] = zuffer[iz] & 0x01;
X#if DBG
X/*
X      if(pattern[button-1][iz] == 1)printf("|");
X      if(pattern[button-1][iz] == 0)printf("_");
X*/
X#endif
X   }
X
X   helptxt("Press the button again to verify the pattern.", "");
X
X   match = 0;
X   for(try=0; try<4; try++)  /* Try four times to get a match. */
X   {
X      GetSample(); /* Read IR signal again. */
X
X      helptxt("Data received.  Verifying match.", "");
X/*   DPattern(button, try+2);*/
X      DisplayPattern(button, 1);
X
X      /*--- Find number of cells that don't match. */
X
X      diff[try] = 0;
X      smallest = NSAMPLES+10;
X      for(iz=0; iz<NSAMPLES; iz++)
X      {
X         zuffer[iz] = zuffer[iz] & 0x01;
X         if(pattern[button-1][iz] != zuffer[iz])
X         {
X            diff[try]++;
X         }
X#if DBG
X/*
X         if(zuffer[iz] == 1)printf("|");
X         if(zuffer[iz] == 0)printf("_");
X*/
X#endif
X      }
X      if(diff[try] > TOLERENCE)
X      {
X#if DBG
X         printf("\n Samples do not match:%d  Please try again.",diff[try]);
X#endif
X         helptxt("Samples do not match.  Please press button again.", "");
X         if(diff[try] < smallest)
X         {
X            /*--- Store the best pattern so far. */
X            smallest = diff[try];
X            for(iz=0; iz<NSAMPLES; iz++)
X            {
X               pattern[button-1][iz] = zuffer[iz];
X            }
X         }
X      } else
X      {
X         match = 1;
X         break;
X      }
X   }
X   if(match == 0)
X   {
X      helptxt("Could not verify pattern.  Will use the best match of four tries.", "");
X#if DBG
X      printf("\n Could not verify pattern.  Will use the best match.");
X      printf("\n Try the analyzer to verify compatability of your unit.");
X#endif
X   } else
X   {
X      helptxt("Successful pattern match!", "");
X      DisplayPattern(button, 0);
X   }
X
X   return(TRUE);
X}
X
X
X/*-------------------- D i s p l a y P a t t e r n . c ------------------*/
X/* This routine draws the acquired pattern on the screen in the help     */
X/* message area.                                                         */
X/*-----------------------------------------------------------------------*/
X
Xint DisplayPattern(button, mode)
X  int button;  /* Currently selected control button. */
X  int mode;    /* 0 = draw pattern, 1 = draw difference. */
X{
X   int it;
X   SHORT row;
X
X   /*--- Any old text or pattern that existed should have been erased with */
X   /*--- a help message. */
X
X   /*--- Draw pattern. X range = 24 to 617 */
X
X   SetAPen(WRPort, 1);
X   row = 0;
X   for(it=0; it<NSAMPLES; it++)
X   {
X      if(mode == 0)
X      {
X         if((zuffer[it] & 0x01) == 1)
X         {
X            Move(WRPort, 26 + (SHORT)(it%590), 175 + row);
X            Draw(WRPort, 26 + (SHORT)(it%590), 175 + row);
X         }
X      } else
X      {
X         if((zuffer[it] & 0x01) != pattern[button-1][it])
X         {
X            Move(WRPort, 26 + (SHORT)(it%590), 175 + row);
X            Draw(WRPort, 26 + (SHORT)(it%590), 175 + row);
X         }
X      }
X
X      /*--- Space the data in rows. */
X
X      if((it%590 == 0) &&(it != 0))row = row + 2;
X   }
X#if DBG
X   printf("\n Drew the pattern.");
X#endif
X
X   return(TRUE);
X}
X
X
X
Xint DPattern(button, mode)
X  int button;  /* Currently selected control button. */
X  int mode;    /* 0 = draw pattern, 1 = draw difference. */
X{
X   int it;
X   SHORT row;
X
X   /*--- Any old text or pattern that existed should have been erased with */
X   /*--- a help message. */
X
X   /*--- Draw pattern. X range = 24 to 617 */
X
X   SetAPen(WRPort, 1);
X   row = 0;
X   for(it=0; it<NSAMPLES; it++)
X   {
X      if((zuffer[it] & 0x01) == 1)
X      {
X         Move(WRPort, 26 + (SHORT)(it%590), 175 + row - mode*20);
X         Draw(WRPort, 26 + (SHORT)(it%590), 175 + row - mode*20);
X      }
X
X      /*--- Space the data in rows. */
X
X      if((it%590 == 0) &&(it != 0))row = row + 2;
X   }
X
X   return(TRUE);
X}
X#endif /*DEBUG*/
X
X/*-------------------- f i n d _ m a t c h . c ----------------------*/
X/*  Find pattern which is the closest match to the one just read in. */
X/*-------------------------------------------------------------------*/
X
Xint find_match()
X{
X   int match, it, smallest;
X   int diff, pat;
X
X#if DBG
X   printf("\n Matching patterns...");
X#endif
X
X   /*--- Mask of bit of interest in zuffer. */
X
X   for(it=0; it<NSAMPLES; it++)zuffer[it] = zuffer[it] & 0x01;
X
X   /*--- Compare data to stored patterns. */
X
X   match = -1;
X   smallest = NSAMPLES+10;
X   for(pat=0; pat<20; pat++)  /* Step through all stored patterns. */
X   {
X      if(active[pat+1])  /* Only examine active patterns to save time. */
X      {
X         diff = 0;
X         for(it=0; it<NSAMPLES; it++)
X         {
X            if(pattern[pat][it] != zuffer[it])diff++;
X         }
X      }
X      if(diff < smallest)
X      {
X         smallest = diff;
X         match = pat;
X      }
X#if DBG
X      printf("\n diff(%d)=%d", pat, diff);
X#endif
X   }
X
X#if DBG
X   printf("\n Best match is pattern %d", match);
X   if(match == -1)
X   {
X      printf("\n No match for pattern!");
X   }
X#endif
X
X   return(match);
X}
END_OF_FILE
if test 27153 -ne `wc -c <'irc.c'`; then
    echo shar: \"'irc.c'\" unpacked with wrong size!
fi
# end of 'irc.c'
fi
if test -f 'irc.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'irc.h'\"
else
echo shar: Extracting \"'irc.h'\" \(948 characters\)
sed "s/^X//" >'irc.h' <<'END_OF_FILE'
X/*------------------------------ i r c . h ---------------------------------*/
X/* Include files and variable definitions for irc.c                         */
X/*--------------------------------------------------------------------------*/
X
X#include "stdio.h"
X#include "stdlib.h"   /* Contains alloc() and free() definitions. */
X#include "workbench/workbench.h"
X#define INTUITIONPRIVATE   /* Allow access to private parts of IntuitionBase. */
X#include "intuition/intuitionbase.h"
X#include "graphics/gfxbase.h"
X#include "graphics/rastport.h"
X#include "proto/all.h"  /* Do I really need this? */
X#include "exec/execbase.h"
X#include "exec/exec.h"
X#include <exec/types.h>
X#include <exec/tasks.h>
X#include <exec/interrupts.h>
X#include <exec/memory.h>
X#include "hardware/intbits.h"
X#include "hardware/custom.h"
X#include <hardware/cia.h>
X#include <resources/cia.h>
X#include "workbench/startup.h"
X#include "string.h"
X#include "signal.h"
X#include "VERSION.h"
X
END_OF_FILE
if test 948 -ne `wc -c <'irc.h'`; then
    echo shar: \"'irc.h'\" unpacked with wrong size!
fi
# end of 'irc.h'
fi
if test -f 'ircserver.asm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ircserver.asm'\"
else
echo shar: Extracting \"'ircserver.asm'\" \(4686 characters\)
sed "s/^X//" >'ircserver.asm' <<'END_OF_FILE'
X;
X;  ircserver.asm
X;
X;  This Lattice V5.04 assembly language routine gets added to the
X;  level 2 interrupt server chain to deal with INT2 interrupts
X;  caused by bringing the ACK pin on the parallel port low.
X;
X;
X;  NOTE: Lattice asm doesn't like: move.l _irc, a1
X;          and DOES like: move.l _irc,a1
X;          Only difference is the space before "a1".
X; Also, calling an external Lattice C routine from assembly must be
X; done after the Enable(), Permit().  (Would probably work before
X; the Forbid(), Disable() too.)
X; To pass a variable which is a pointer to a C function use:
X;
X;          [struct Interrupt *SoftInterrupt; Cause(SoftInterrupt);]
X;
X;        move.l     _SoftInterrupt,a1   ; Put address of Interrupt structure
X;        move.l     a1,-(a7)            ; onto stack.
X;        JSR       _Cause
X;        ADDQ      #4,A7                ; Fix the stack pointer.
X;
X; To pass a variable which is NOT a pointer AS a pointer to a C function use:
X;
X;          [struct Interrupt SoftInterrupt; Cause(&SoftInterrupt);]
X;
X;        LEA       _SoftInterrupt,A1
X;        MOVE.L    A1,-(A7)
X;        JSR       _Cause
X;        ADDQ      #4,A7                ; Fix the stack pointer.
X;
X;
X;
X        csect data,1,,2,2
X        xref _LVOSignal
X
X        csect text
X
X	xdef _ircserver
X
X        xref _ciab
X        xref _SoftInterrupt
X        xref _thisTask
X        xref _TimerSigMask
X        xref _buffer
X        xref _NSamples
X
X        xref _Forbid
X        xref _Disable
X        xref _Enable
X        xref _Permit
X
X        xref _custom
X
Xdata1             equ   $bfe101
Xdir1              equ   $bfe301
X
X_ircserver
X;
X; Save registers on stack.
X;
X        MOVEM.L A2-A6/D2-D7,-(SP)  ;  Push Registers 
X;
X; Disable interrupts and tasking.
X;
X        JSR       _Forbid  ; RKM says this is a no-no but don't work without it.
X        JSR       _Disable
X; Machine is MINE now until I let it go!
X;
X;
X;  Read from parallel port to see if IR hardware triggered this interrupt.
X;  If not then let the server chain continue without further ado.
X;
X;
X; Set up parallel port for reading.
X;
X      move.b   #0,dir1           * all lines read
X      move.b   #0,data1
X      move.b   data1,d0       ; Move byte from parallel port to register.
X      andi.b   #$01,d0        ; Mask off bit 0.
X      beq      proceed        ; If bit is one, then proceed to capture data.
X
X      JSR       _Enable
X      JSR       _Permit  ; RKM says this is a no-no but don't work without it.
X      MOVEM.L (SP)+,A2-A6/D2-D7  ;  Pop Registers
X      MOVEQ     #$00,D0          ; Continue the server chain.
X      RTS
X;
X; Disable the ACK interrupt until after processing is done.
X; (Is re-enabled in irc.c)
X; Hex 10 = 00010000 Should disable the 8520 FLAG interrupt.
X;
Xproceed:   move.b  #$10,$BFED01
X;
X; Turn off the display so that DMA access for screen update doesn't
X; steal cycles from the 68000 processor.
X;  $0100 = clear BPLEN bit; custom+$96 = dmacon register
X;
X           move.w #$100,$96+_custom
X;
X; Start timer B.
X;
X        lea.l _ciab,a1      ; Get address of ciab
X        adda.l  #$F00,a1    ; Add offset for ciacrb register.
X        or.b #$01,(a1)      ; $01 = CIACRBF_START ---> Starts timer b!
X;
X; Read data from parallel port until buffer is full.
X;
Xhold: move.b    $bfdd00,d0  ; Read 8520 IRC register to get/reset interrupt bit
X      andi.l    #$02,d0     ; Mask off timer B interrupt bit.
X      beq       hold        ; Loop till get an interrupt.
X;
X; Read a byte from 8250-A (parallel port)  The data direction registers are
X; set up in SoftHandler.
X;
X      movea.l  _buffer,a1        ; a1 now holds buffer location
X      move.b   data1,(a1)+       ; Move byte from parallel port to buffer.
X      move.l   a1,_buffer        ; Update pointer to buffer.
X      subq.l   #$1,_NSamples     ; 8
X      bne      hold              ; Go wait for next timeout if buffer not full.
X
X      move.b #$02,$BFDD00   ; Disable timer B interrupts.
X      move.b    $bfdd00,d0  ; Read 8520 IRC register to reset interrupt bit.
X;
X; Turn on the display (enable bitplane DMA).
X;  $8100 = set BPLEN bit; custom+$96 = dmacon register
X;
X           move.w #$8100,_custom+$96
X;
X; Enable interrupts and tasking.
X;
X        JSR       _Enable
X        JSR       _Permit  ; RKM says this is a no-no but don't work without it.
X;
X; Signal main task to wake up.  Data is ready!
X;
X      move.l    _TimerSigMask,d0     ; Set up data in registers.
X      movea.l    _thisTask,a1
X      movea.l   $4,a6
X      jsr       _LVOSignal(a6)       ; Send signal (see note above.)
X;
X;
X; Clean up, restore registers and return.
X;
X        MOVEM.L (SP)+,A2-A6/D2-D7  ;  Pop Registers
X        MOVEQ     #$00,D0          ; Continue the server chain.
X        RTS
X
X        END
END_OF_FILE
if test 4686 -ne `wc -c <'ircserver.asm'`; then
    echo shar: \"'ircserver.asm'\" unpacked with wrong size!
fi
# end of 'ircserver.asm'
fi
if test -f 'linkirc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'linkirc'\"
else
echo shar: Extracting \"'linkirc'\" \(100 characters\)
sed "s/^X//" >'linkirc' <<'END_OF_FILE'
XFROM LIB:c.o+irc.o+ircserver.o+LetGo.o+BackGround.o
XTO irc
XLIBRARY LIB:lc.lib+LIB:amiga.lib
XNODEBUG
END_OF_FILE
if test 100 -ne `wc -c <'linkirc'`; then
    echo shar: \"'linkirc'\" unpacked with wrong size!
fi
# end of 'linkirc'
fi
if test -f 'readme' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'readme'\"
else
echo shar: Extracting \"'readme'\" \(1922 characters\)
sed "s/^X//" >'readme' <<'END_OF_FILE'
XThis code is an uncompleted version of an IR remote controlled AREXX
Xutility.  It is uncompleted because no one wants to pay me to finish
Xit (great sadness...)  I have placed it in the public domain as an example
Xof how to read an IR remote control signal using the parallel port.
XI take no responsibility for the correctness or usability of this
Xcode.  I would apologize for the funkyness of it but I'm giving
Xit to you for free so just be glad I'm reasonably free with comments
Xas to what's going on in it.
XThe code runs as it is on an Amiga 1000 with 1.5M of RAM (I suspect it
Xwill run in 512K also) when compiled using Lattice's V5.04 C compiler
Xand asm assembler.  I've only run it under V1.2 of the operating
Xsystem so I don't know how it will work under V1.3 and higher.
XI've pulled out all the AREXX specific code so that you don't have
Xto have AREXX to compile or run it.  The file Schematic.ilbm contains
Xa simple electronics schematic for hooking a Radio Shack IR receiver
Xto the parallel port on an A1000.  NOTE that if you have an Amiga
Xother than an A1000 you must change the +5Vdc and gnd connections and
Xuse a male connector instead of a female.  I think the connections
Xfor other machines is pin 14 = +5Vdc and pin 25 = gnd but don't
Xtrust my memory---verify it!
XTo try the code, plug in the hardware with the computer off, boot
Xthe computer, run the code, click on the LEARN button, then click
Xon one of the 20 buttons in the upper right, enter a short name
Xin the text requestor (next to the AREXX button) hit return and
Xthen press a button on your IR remote (you'll have press it twice
Xso that it can be verified.)  The pattern of the digitized data
Xwill be drawn on the screen followed by the pattern of the
Xdifferences between the first and second samples.  The code prompts
Xyou for most of this.  The rest of it I'll let you figure out for
Xyourselves.  Have fun!
X
Xron@vicorp.com or uunet!vicorp!ron
END_OF_FILE
if test 1922 -ne `wc -c <'readme'`; then
    echo shar: \"'readme'\" unpacked with wrong size!
fi
# end of 'readme'
fi
if test -f 'tmp' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tmp'\"
else
echo shar: Extracting \"'tmp'\" \(124 characters\)
sed "s/^X//" >'tmp' <<'END_OF_FILE'
X;
Xasm ircserver.asm
Xasm LetGo.asm
X;
Xlc -cc -ff -adb irc
Xlc -cc -ff -adb BackGround
X;
X; Link with BLINK
X;
Xblink with linkirc
END_OF_FILE
if test 124 -ne `wc -c <'tmp'`; then
    echo shar: \"'tmp'\" unpacked with wrong size!
fi
# end of 'tmp'
fi
echo shar: End of archive 1 \(of 5\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.