From: willegen@research.ptt.nl
Newsgroups: comp.sys.hp48
Subject: HP48 remote control programs
Date: 7 Apr 92 08:15:13 GMT

BEGIN_RDM ir.rdm
Here are the remote control programs. It is sent in the 'standard' HP48
source format. Enjoy!

For those of you that don't have ASC or UUE/UUD, pse mail again. I have
source of UUD and UUE, and ASC can be sent UUEncoded. Pse note that this
version of ASC runs on an IBM-PC. The UUE/UUD are written in C and run on
(almost) any machine.

I also wrote a program to take apart this file. Source available if you want
to read it (+/- 50 lines C, very much indented, so approx 10 lines after
space removal). There also is another program that takes these files apart,
but I don't have it.

Christ
END_RDM

----------8<------------------------8<------->8--------------------->8-------

BEGIN_DOC ir.txt
IR (and IR2) Documentation
--------------------------

IR & IR2 - IR remote-control sampling programs by Steve VanDevender

These program embody a new way of performing infrared remote
control sampling on the HP48.  The previously distributed remote
sampling programs sampled IR input by continually reading the IR
input and immediately writing it out to memory.  These programs
use a different approach--they continually sample the IR input
while incrementing a timing count, and only write information to
memory when the IR state changes or the counter overflows.  This
approach increases the effective sampling rate under many
circumstances and greatly reduces the amount of memory needed to
store samples.  I have also paid special attention to instruction
timing to make sure that the timing characteristics of the
sampling and playback routines are as nearly identical as
possible; this has been a problem with some previous attempts at
remote sampling.

One of my motivations for writing these programs was that the
other IR samplers I tried wouldn't work at all with my VCR.  Both
of these work with my VCR, although I have obtained mixed results
using these programs with other kinds of remotes.  I am hoping
that these programs will be more effective than previous
attempts, and that the techniques I have used here can be
improved upon by others.

There are two separate IR sampling systems included here.  The
first, in ir (listed in irsamp.star & irplay.star), were the
first programs I developed that worked.  They store 3-nibble
sample units--1 nibble for the current IR input state, and 2
nibbles for a repeat count.  The inner loop of the sampling and
playback routines runs at about 25 microseconds per loop
iteration, and take about 40 microseconds to write out the sample
data and re-enter the inner loop.  These routines will make
samples of about 90 bytes that work with my VCR.  The second, in
ir2 (listed in irsamp2.star & irplay2.star), use 2-nibble
samples containing a 1-nibble repeat count.  The inner loop of
these routines runs at about 23 microseconds per iteration, but
sample string are a little over twice as long, at 224 bytes for
samples that work with my VCR.  Interestingly enough, though,
Lutz Vieweg's RFP program will pack samples created by either set
of routines to about the same length of 60 bytes.

This documentation includes STAR assembler source for all
machine-language routines.

The directory IR contains the 3-nibble sampling routines, and the
directory IR2 contains the 2-nibble sampling routines.  IR
contains the user RPL programs SAMPLE and PLAYBACK and the
machine code objects IRSAMP and IRPLAY.  IR2 contains SAMPLE2,
PLAYBACK2, IRSAMP2, and IRPLAY2.  Similarly, irsamp.star and
irplay.star are the STAR source for the 3-nibble
sampling/playback routines, while irsamp2.star and irplay2.star
are the source for the 2-nibble routines.

The program SAMPLE (SAMPLE2) will take either a real number in
level 1, which is used to generate a string of that length to
receive the sample, or a string which will be overwritten with
sample data.  It calls the machine-language program IRSAMP
(IRSAMP2) which performs the sampling.  IRSAMP checks for a
string object in level 1, which must have SIZE > 1, and aborts if
it doesn't find one.  It then waits up to 15 seconds for IR
input, (that is, for you to place your remote control next to the
calculator and press the button for the remote function you want
to sample) and aborts if none is received in that time.
Otherwise it begins sampling and exits when the end of the string
in level 1 is reached.  I have found that holding an IR remote
too close to the calculator during sampling will often result in
ineffective samples; I get best results with the remote about
5-10 cm from the IR input port.

The program PLAYBACK (PLAYBACK2) will take a string in level 1
and feed it to IRPLAY (IRPLAY2), then drop the string.  You can
feed strings directly to IRPLAY if you wish, but they will be
left on the stack (although this is a useful way to test samples
without having to recover them with LASTARG).  You should only
feed strings created with IRSAMP to PLAYBACK or IRPLAY.  It is
possible to create strings which leave the HP-48 IR LED on for
long periods of time, which drains the batteries and may cause
hardware damage.  In any case, IRPLAY will turn the IR LED off
before exiting.

Two of my friends who have tested these programs have reported
that they have experienced crashes while using them, although one
report did not appear to involve memory corruption or any other
damage.  Therefore, I do not guarantee these programs to be
bug-free--they may cause crashes, memory corruption, or even
hardware damage if used improperly, although I can also say that
I have had no problems for over a week since I debugged the
routines in the IR directory.  Neither are they guaranteed to
work with any IR remote control, although I suspect they will
have greater success than previous remote sampling programs.

I would like to thank Dave Marsh for his original IR sampling
programs, which I have copied small parts of and which were my
main source of technical information in writing these programs,
and Jan Brittenson for his excellent STAR assembler and MLDL
debugger which made writing and debugging these programs easy.

---

;irsamp.star:  ML core of a learning remote control sampler using run-length
;encoding for samples.  This version uses a 2-nibble repeat count.

;requires a string in stack level 1, and overwrites its contents with the
;sample data.

		header	`x'

		code

		move.a	@d1, a		;put TOS pointer in a
		call	save_regs	;save RPL registers
		call	#01115		;disable interrupts
		call	#01bbd		;turn off display

		move.a	a, d1		;put TOS obj pointer in d1
		move.a	@d1, a		;get obj prolog
		move.p5	type_string, c	;get string prolog
		brne.a	c, a, bailout	;if not a string prolog abort
		add	5, d1		;move past string prolog
		move.a	@d1, c		;get string length field
		add	5, d1		;d1 now points to string data
		sub.a	5, c		;subtract 5 to get length of chars

		move.a	c, b
div3:		srb.a	c		;divide c by 4
		srb.a	c
		add.a	c, b		;add to b
		brnz.a	c, div3		;while c > 0
		srb.a	b		;divide b by 4, to get approx. c/3
		srb.a	b		;c.a is 0
		inc.a	c		;c.a is 1
		brle.a	b, c, bailout	;if b <= 1, no room for samples
		dec.a	b		;trust me, you need this

		move.5	#0011a, d0	;have d0 point to IR LED input nib
		clr.a	c
		move.1	c, @d0		;clear LED status
		move.p5	#80000, c	;move timeout count to c
					;should last about 16 s
wait:		dec.a	c		;c is timeout counter
		brcs	bailout		;if we dec past 0, bail out
checkled:	move.xs	@d0, a		;otherwise, check IR LED input
		brbc	8, a, wait	;if no input, wait for it

sample:		clr.b	c		;c.b is the repeat count
		move.xs	a, c		;copy current input state from a.xs
samploop:	move.xs	@d0, a		;get IR LED status
		inc.x	c		;increment repeat count
		breq.xs	c, a, samploop	;while c.xs is undisturbed, loop
		move.3	c, @d1		;write state and repeat count
		add	3, d1		;increment d1
		dec.a	b		;one less sample
		brcc	sample		;back for new sample
		
bailout:	call	#010e5		;allow interrupts
		call	#01b8f		;turn on display
		jump	rr_rplcont	;back to RPL

		endcode

---
;irplay.star:  ML core of playback program for learning remote control

;requires a string in stack level 1 generated by irsamp

		header	`x'

		code

		move.a	@d1, a		;put TOS obj pointer in a
		call	save_regs	;save RPL registers
		call	#01115		;disable interrupts
		call	#01bbd		;turn off display

		move.a	a, d1		;put TOS obj pointer in d1
		move.a	@d1, a		;get obj prolog
		move.p5	type_string, c	;get string prolog
		brne.a	c, a, bailout	;if not a string prolog abort
		add.a	5, d1		;move past string prolog
		move.a	@d1, c		;get string length field
		add.a	5, d1		;d1 now points to string data
		sub.a	5, c		;subtract 5 for length of string chars

		move.a	c, b
div3:		srb.a	c		;divide c by 4
		srb.a	c
		add.a	c, b		;add to b
		brnz.a	c, div3		;while c > 0
		srb.a	b		;divide b by 4, to get approx. c/3
		srb.a	b		;c.a is 0
		inc.a	c		;c.a is 1
		brle.a	b, c, bailout	;if b <= 1, no room for samples
		dec.a	b		;trust me, you need this

		move.5	#0011c, d0	;d0 points to IR LED output
playback:	move.3	@d1, c		;get a sample
		add	3, d1
		dec.x	c		;decrement repeat count
		move.xs	c, a		;copy IR state to a
playloop:	move.xs	c, @d0		;output current LED state
		dec.x	c		;decrement counter
		breq.xs	c, a, playloop	;timing only-branch never taken
		dec.a	b		;one less sample
		brcc	playback	;repeat until out of samples

		clr.a	c		;clear c.0
		move.1	c, @d0		;clear LED output

bailout:	call	#010e5		;allow interrupts
		call	#01b8f		;turn on display
		jump	rr_rplcont	;back to RPL

		endcode

---
;irsamp2.star:  ML core of a learning remote control sampler using run-length
;encoding for samples.  This version uses a one-nibble repeat count.

;requires a string in stack level 1, and overwrites its contents with the
;sample data.

		header	`x'

		code

		move.a	@d1, a		;put TOS pointer in a
		call	save_regs	;save RPL registers
		call	#01115		;disable interrupts
		call	#01bbd		;turn off display

		move.a	a, d1		;put TOS obj pointer in d1
		move.a	@d1, a		;get obj prolog
		move.p5	type_string, c	;get string prolog
		brne.a	c, a, bailout	;if not a string prolog abort
		add	5, d1		;move past string prolog
		move.a	@d1, c		;get string length field
		add	5, d1		;d1 now points to string data
		sub.a	5, c		;subtract 5 to get length of chars

		move.a	c, b
		srb.a	b		;divide string length by two
		clr.a	c
		inc.a	c		;set c.a to 1
		brle.a	b, c, bailout	;if b <= 1, no room for samples
		dec.a	b		;trust me, you need this

		move.5	#0011a, d0	;have d0 point to IR LED input nib
		move.p5	#80000, c	;move timeout count to c
		move	1, p
		clr.a	a
		move.b	a, @d0		;clear IR status nibble
wait:		dec.a	c		;c is timeout counter
		brcs	bailout		;if we dec past 0, bail out
		move.b	@d0, a		;otherwise, check IR LED input
		brbc	4, a, wait	;if no input, wait for it

sample:		clr.b	c		;c.0 is the repeat count
		move.p	a, c		;copy current input state from a.1
samploop:	move.b	@d0, a		;get IR LED status
		inc.b	c		;increment repeat count
		breq.p	c, a, samploop	;while c.1 is undisturbed, loop
		move.b	c, @d1		;write state and repeat count
		add	2, d1		;increment d1
		dec.a	b		;one less sample
		brcc	sample		;back for new sample
		
bailout:	move	0, p
		call	#010e5		;allow interrupts
		call	#01b8f		;turn on display
		jump	rr_rplcont	;back to RPL

		endcode

---
;irplay2.star:  ML core of playback program for learning remote control

;requires a string in stack level 1 generated by irsamp2

		header	`x'

		code

		move.a	@d1, a		;put TOS obj pointer in a
		call	save_regs	;save RPL registers
		call	#01115		;disable interrupts
		call	#01bbd		;turn off display

		move.a	a, d1		;put TOS obj pointer in d1
		move.a	@d1, a		;get obj prolog
		move.p5	type_string, c	;get string prolog
		brne.a	c, a, bailout	;if not a string prolog abort
		add.a	5, d1		;move past string prolog
		move.a	@d1, c		;get string length field
		add.a	5, d1		;d1 now points to string data
		sub.a	5, c		;subtract 5 for length of string chars

		move.a	c, b
		srb.a	b		;divide string length by two
		clr.a	c
		inc.a	c		;set c.a to 1
		brle.a	b, c, bailout	;if b <= 1, no room for samples
		dec.a	b		;trust me, you need this

		move.5	#0011b, d0	;d0 points to IR LED output - 1
		clr.a	a
		move	1, p
playback:	move.b	@d1, c		;get a sample
		add	2, d1
		dec.b	c		;predecrement c
		move.p	c, a		;copy IR state to a
playloop:	move.b	a, @d0		;output current LED state
		dec.x	c		;decrement counter
		breq.p	c, a, playloop	;while c.1 is unchanged, loop
		dec.a	b		;one less sample
		brcc	playback	;repeat until out of samples
		move	0, p

		clr.a	c		;clear c.0
		move.b	c, @d0		;clear LED output

bailout:	call	#010e5		;allow interrupts
		call	#01b8f		;turn on display
		jump	rr_rplcont	;back to RPL

		endcode

---
END_DOC

----------8<------------------------8<------->8--------------------->8-------

BEGIN_UUE ir.uue
table
 !"#$%&'()*+,-./0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
begin 600 ir
M2%!(4#0X+426*O!_/ (    &25)03$%9!LPM0 H 08._>0;X%1& W[L!,1$Tz
M0RPJ@&IB<11T<82!K]2%D2\8^<*!ZO$8^8&1'VZX_1++$0#<42]QHN.J&D6By
MXREBSUWD+5$,^.40@/^X =A#49 +  9)4E-!35 &S"VP"P!!@[]Y!O@5$8#?x
MNP$Q$31#+"J :GEQ%'1QA(&OU(61+QCYPH'J\1CY@9$?;KAM%*L1 "U1#$, w
M ,A.+5$B"&@HSZTNJA8ELF,I8A_5$B?<18Y?#@'XCQN /10%T "  ,44E"44v
M-+2$T-D"'C8R["*'^V&X'-ZBTJD>^B[2V0(L*C " %-T<FEN9R!E>'!E8W1Eu
M9#FCL1(#U2^"Y (&25)03$%9V/N18R,K,: )  9304U03$4&G2W@82.--]+9t
M H?[8;@<M*(BEQZH-]+9 DXJ4 $ UXP!       NI>&D A4 8&=%      #@s
M4AHK,5#](H?[8;@<WJ+2J1ZH-]+9 BPJ$ , 4F5A;"!O<B!3=')I;F<L('!Lr
?96%S93FCL1(#U2^R$@/5+X+D @9)4E-!35 Y-K(2 R!Oq
 p
end
END_UUE

----------8<------------------------8<------->8--------------------->8-------

BEGIN_UUE ir2.uue
table
 !"#$%&'()*+,-./0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
begin 600 ir2
M2%!(4#0X+426*O!_'P(    '25)03$%9,@?,+3 ) $&#OWD&^!41@-^[ 3$1z
M-$,L*H!J47$4='&$@:_4A9$?+6ZX+<,=NQ$ #1)!'Q=JKJA!J.,)<L]=Y@(My
M08Q?#@'XCQN /10%J@!PD"0U%=0$)7/ W *G ! T^)MG@%\1 ?B]&Q 303/$x
MH@*H-A9'01='&/A*71CYT>*&VT3<L1H!, 0 @!(-0<A.*$&*@$;SZJ)H0;IFw
M"7(?U''!7>8"^.40@/^X =A#4> +  E03$%90D%#2S()G2W@82/#+G*X'X;+v
MX2TJG>JA[R*=+<"B B, ,$4GE^9V!E*&!U<V1E=&EC,:*S%0_2)(+G"0) 7%u
M%)0E@[T?.3:R$@.> ' P%=0$Q50D<]#9 AXVTG@CG2UPN!^&RT$K*G+I@7HCt
MG2W@I (5 '#-&       X%(:3BI0 0!V5@0      "ZEL1(#U2]RN!^&R^$Ms
M*IWJ@7HCG2W H@(Q "!5%L8&\B8',D4GE^9VQ@("QU86-E>6,QHK,5#](BLQr
34/TB2"YPD"0U%=0$)9-C(RLQ "8'q
 p
end
END_UUE

----------8<------------------------8<------->8--------------------->8-------

BEGIN_ASC ir.asc
%%HP: T(1);
"69A20FF7C32000000060942505C4149560CCD204A0001438FB97608F511108FD
BB1013114334C2A208A626174147174818FA4D5819F2819F2C18AE1F819F1819
F1E68BDF21BC1100CD15F2172A3EAAA1542A3E9226FCD54ED215C08F5E0108FF
8B108D341509B0006094253514D40560CCD20BB0001438FB97608F511108FDBB
1013114334C2A208A697174147174818FA4D5819F2819F2C18AE1F819F1819F1
E68BD641BA1100D215C03400008CE4D21522808682FCDAE2AA61522B369226F1
5D2172CD54E8F5E0108FF8B108D341500D0008005C41495241434B480D9D20E1
6323CE2278BF168BC1ED2A2D9AE1AFE22D9D20C2A203200035472796E6760256
87075636475646933A1B21305DF2284E2060942505C414958DBF193632B2130A
9000603514D405C45460D9D20E1632D8732D9D2078BF168BC14B2A2279E18A73
2D9D20E4A20510007DC8100000000000E25A1E4A20510006765400000000000E
25A1B21305DF2278BF168BC1ED2A2D9AE18A732D9D20C2A2013000255616C602
F6270235472796E676C20207C656163756933A1B21305DF22B21305DF2284E20
6094253514D40593632B2130BF43"
END_ASC

----------8<------------------------8<------->8--------------------->8-------

BEGIN_ASC ir2.asc
%%HP: T(1);
"69A20FF7F12000000070942505C414952370CCD20390001438FB97608F511108
FDBB1013114334C2A208A615174147174818FA4D5819F1D2E68BD23CD1BB1100
D02114F171A6EA8A148A3E9027FCD56E20D214C8F5E0108FF8B108D34150AA00
07094253514D4052370CCD207A0001438FB97608F511108FDBB1013114334C2A
208A636174147174818FA4D5819F1D2E68BD44CD1BA1100340000821D0148CE4
8214A808643FAE2A8614AB669027F14D171CD56E208F5E0108FF8B108D34150E
B0009005C41495241434B42390D9D20E16323CE2278BF168BC1ED2A2D9AE1AFE
22D9D20C2A203200035472796E676025687075636475646933A1B21305DF2284
E2070942505C41495238DBF193632B2130E9000703514D405C4542370D9D20E1
632D8732D9D2078BF168BC14B2A2279E18A732D9D20E4A20510007DC81000000
00000E25A1E4A20510006765400000000000E25A1B21305DF2278BF168BC1ED2
A2D9AE18A732D9D20C2A2013000255616C602F6270235472796E676C20207C65
6163756933A1B21305DF22B21305DF2284E207094253514D4052393632B21302
BCE"
END_ASC

----------8<------------------------8<------->8--------------------->8-------

That's it!

C.P.vanWillegen@research.ptt.nl