
;------------------------------------------------------------------------------
; Title       : wc.asm
; Description : WonderCommand
; Author      : KAWAMOTO "nanashino" Yasuhisa
; Email       : nanashi@yk.rim.or.jp
; Date        : 07/28/2000
;------------------------------------------------------------------------------

.include "1200def.inc"

;--  Modulation-freq(38.4KHz) setting --
.equ	N=52			; 13us@4.0MHz and R=1
;.equ	N=130			; 13us@10.0MHz and R=1
.equ	R=1			; 1/1
.equ	BAUD_9600=8		; 
.equ	BAUD_2400=32		; 

;-- Global register --
.def	t_tmp		=r16	; Scratch register
.def	t_sr		=r17	; Status register storage
.def	t_reload	=r18	; Reload register
.def	t_st		=r19	; Status register
.def	t_rsv_wc	=r20	; IR receive wait counter
.def	t_rsv_bc	=r21	; IR receive bit counter
.def	t_rsv_bf	=r22	; IR receive buffer
.def	t_trn_wc	=r23	; IR tramsmit wait counter
.def	t_trn_bit	=r24	; IR tramsmit bit register
.def	t_trn_wave	=r25	; IR tramsmit modulation wave
.def	trn_one_c	=r26	; IR tramsmit '1' counter
.def	trn_bf		=r27	; IR tramsmit buffer
.def	tmp		=r28	; Scratch register
.def	tmp2		=r29	; Scratch register2

;-- Bit position in Status register --
.equ	RD		=0	; IR receive data ready bit
.equ	TR		=7	; IR tramsmit ready bit

	.cseg
;-- Reset and interrupt vector --
	.org $0000
	rjmp	main		; Reset handler
	.org INT0addr
	reti			; External interrupt handler (Not Used)
	.org OVF0addr
	rjmp	tim0_ovf	; Timer0 overflow handler
	.org ACIaddr
	reti			; Analog comparator handler (Not Used)

;-- Timer0 overflow handler --
tim0_ovf:
	in	t_sr,SREG		; Store SREG
	out	TCNT0,t_reload		; Reload timer
;-- Modulation wave output --
	com	t_trn_wave
	mov	t_tmp,t_trn_bit
	or	t_tmp,t_trn_wave
	out	PORTB,t_tmp
	dec	t_trn_wc
	brne	trn_skip
	ldi	t_trn_wc,BAUD_2400
	sbr	t_st,(1<<TR)
trn_skip:
;-- IR receive --
	dec	t_rsv_wc
	brne	rsv_skip
	cpi	t_rsv_bc,0		; Check signal
	brne	rsv_0
	sbic	PIND,2
	rjmp	rsv
	ldi	t_rsv_wc,BAUD_9600/8	; 1/8bit
	rjmp	rsv_exit
rsv:
	inc	t_rsv_bc
	ldi	t_rsv_wc,BAUD_9600/2	; 1/2bit
	rjmp	rsv_exit
rsv_0:
	cpi	t_rsv_bc,1		; Start bit
	brne	rsv_1
	sbis	PIND,2
	rjmp	rsv_err
	inc	t_rsv_bc
	ldi	t_rsv_wc,BAUD_9600	; 1bit
	rjmp	rsv_exit
rsv_1:
	cpi	t_rsv_bc,10		; Check stop bit
	brne	rsv_10
	sbic	PIND,2
	rjmp	rsv_err
	sbr	t_st,(1<<RD)
	ldi	t_rsv_bc,0
	ldi	t_rsv_wc,BAUD_9600/8	; 1/8bit
	rjmp	rsv_exit
rsv_10:
	sec
	sbic	PIND,2
	clc
	ror	t_rsv_bf
	inc	t_rsv_bc
	ldi	t_rsv_wc,BAUD_9600	; 1bit
	rjmp	rsv_exit
rsv_err:
	ldi	t_rsv_bc,0
	ldi	t_rsv_wc,BAUD_9600/8	; 1/8bit
rsv_exit:
rsv_skip:
	out	SREG,t_sr		; Restore SREG
	reti

;-- Init hardware --
init:
	ldi	t_reload,(256-N+8)	; Set reload value
	ldi	t_st,0
	ldi	t_rsv_wc,BAUD_9600/8	; 1/8bit
	ldi	t_rsv_bc,0
	ldi	t_trn_wc,BAUD_2400
	ldi	t_trn_bit,$ff
	ldi	t_trn_wave,0
	ldi	tmp,0b11111111
	out	DDRB,tmp
	ldi	tmp,0b11111111
	out	PORTB,tmp
	ldi	tmp,0b01111011
	out	DDRD,tmp
	ldi	tmp,0b01111011
	out	PORTD,tmp
	ldi	tmp,R
	out	TCCR0,tmp		; Start timer and set clock source
	out	TCNT0,t_reload
	ldi	tmp,(1<<TOV0)		; Clear T/C0 overflow flag
	out	TIFR,tmp
	ldi	tmp,(1<<TOIE0)		; Enable T/C0 overflow interrupt
	out	TIMSK,tmp
	ret

;-- Data transmit --
transmit:
	ldi	tmp,8
	ldi	trn_one_c,0
trn_f:
	sbrs	t_st,TR
	rjmp	trn_f
	cbr	t_st,(1<<TR)
trn_st:
	sbrs	t_st,TR
	rjmp	trn_st
	cbr	t_st,(1<<TR)
	clr	t_trn_bit
trn_d:
	sbrs	t_st,TR
	rjmp	trn_d
	cbr	t_st,(1<<TR)
	clr	tmp2
	ror	trn_bf
	brcc	trn_d0
	ser	tmp2
	inc	trn_one_c
trn_d0:
	mov	t_trn_bit,tmp2
	dec	tmp
	brne	trn_d
trn_pt:
	sbrs	t_st,TR
	rjmp	trn_pt
	cbr	t_st,(1<<TR)
	clr	tmp2
	sbrs	trn_one_c,0
	ser	tmp2
	mov	t_trn_bit,tmp2
trn_sp:
	sbrs	t_st,TR
	rjmp	trn_sp
	cbr	t_st,(1<<TR)
	ser	t_trn_bit
	ret

;-- Main --
main:
	rcall	init			; Init
	sei				; Enable interrupt

loop1:
	sbrs	t_st,RD
	rjmp	loop1
	cbr	t_st,(1<<RD)
	cpi	t_rsv_bf,$55
	brne	loop1
	ldi	ZL,0
	st	Z,t_rsv_bf
	inc	ZL
loop2:
	sbrs	t_st,RD
	rjmp	loop2
	cbr	t_st,(1<<RD)
	st	Z,t_rsv_bf
	inc	ZL
	cpi	ZL,11
	brlo	loop2			; ZL < 11

	ldi	ZL,0
loop3:
	ld	trn_bf,Z
	rcall	transmit
	inc	ZL
	cpi	ZL,11
	brlo	loop3			; ZL < 11

	rjmp	loop1
