; Wuerfel mit 7 led an 4 portpins
;c. b.f.2005
; 3,6Volt - int. ozzilator ca.500 khz
; power save mode
;plus piezopiepser fuer blinde :-)) an port pb1
; trigger - level interupt on port pb1

.include "2343def.inc"
.device at90s2343
; Bit 76543210
.equ WZ6 = 0b1101000 ; bits for numbers
.equ WZ5 = 0b11100100
.equ WZ4 = 0b11101100
.equ WZ3 = 0b11100101
.equ WZ32 = 0b11110100 ; 2th for 3
.equ WZ2 = 0b11101101
.equ WZ22 = 0b11111100 ; 2th for 2
.equ WZ1 = 0b11110101
.equ WZa = 0b00011101 ; All LEDs
.equ key = 0x01 ; Key on Port-Bit 1 from Port B
.def Dice_Reg = r17 ; Register for the pictures
.def Temp = r16 ; scratch
.def T1 = r1
.def T2 = r2
.def count = r18 ;count for number
.def speed = r21 ; Delay
.def status =r0 ;low register to preserve status register
.def mask = r19
.def zahl = r20
;****EEProm*************************************************************
.eseg
.org 0


;****Source code***************************************************
.cseg ;CODE segment
.org 0
rjmp reset ;Reset handler
rjmp scan ; ext. interrupt
reti ;unused interrupt
reti
;*** Reset handler **************************************************
;*** to provide initial port, timer and interrupt setting up

RESET:
ldi r16,low(RAMEND); Main program start , you must set this correctly for Stack
out SPL,r16

ldi Temp, Wza ; Switch Port B as bit 0 -3 Output , bit 4 as input
out DDRB, Temp
ldi Temp, Wza ; All LEDs off
out PortB,Temp

ldi temp,0b00110000 ;turn on sleep mode and power
out MCUCR,temp ;down plus interrupt on low level.
ldi temp,0x40 ;enable external interrupts
out GIMSK,temp
;**************************************************
main: cli ;disable global interrupts



sei ;enable global interrupts ready
sleep ;fall asleep !!!!!!!!
nop
cli
rcall Loop ;flash LEDs for example usage

ldi temp,0x40
out GIMSK,temp ;enable external interrupt
rjmp main ;go back to sleep after keyscan

; ***** repeat loop endlessly, show if key is pressed.
Loop:
in temp,PINB
andi temp,0b00000010
breq Loop
in temp,PINB ;wait if pin pb1 low , timer is still running
andi temp,0b00000010 ; zufallszahl
breq Loop

in count,TCNT0 ; read timer

LD6: ldi Dice_Reg, WZ6 ; show '6'
out PORTB,Dice_Reg
rcall Delay
ldi zahl,6
dec count
breq ende2
LD5: ldi Dice_Reg, WZ5
out PORTB, Dice_Reg
rcall Delay
ldi zahl,5
dec count
breq ende2
LD4: ldi Dice_Reg, WZ4
out PORTB, Dice_Reg
rcall Delay
dec count
ldi zahl,4
breq ende2
LD3: ldi Dice_Reg, WZ3
out PORTB, Dice_Reg
rcall Delay
ldi zahl,3
dec count
breq ende2

LD2: ldi Dice_Reg, WZ2
out PORTB, Dice_Reg
rcall Delay
ldi zahl,2
dec count
breq ende2
LD1: ldi Dice_Reg, WZ1
out PORTB, Dice_Reg
rcall Delay
ldi zahl,1
dec count
breq ende2
rjmp LD61
ende2:
nop ; jump - branch only over 255 Byte adr. space
rjmp ende



LD61: ldi Dice_Reg, WZ6 ; show '6'
out PORTB,Dice_Reg ; the same as before but with alternate 2 + 3
rcall Delay
ldi zahl,6
dec count
breq ende
LD51: ldi Dice_Reg, WZ5
out PORTB, Dice_Reg
rcall Delay
ldi zahl,5
dec count
breq ende
LD41: ldi Dice_Reg, WZ4
out PORTB, Dice_Reg
rcall Delay
dec count
ldi zahl,4
breq ende

LD32: ldi Dice_Reg, WZ32
out PORTB, Dice_Reg
rcall Delay
ldi zahl,3
dec count
breq ende

LD22: ldi Dice_Reg, WZ22
out PORTB, Dice_Reg
rcall Delay
ldi zahl,2
dec count
breq ende
LD11: ldi Dice_Reg, WZ1
out PORTB, Dice_Reg
rcall Delay
ldi zahl,1
dec count
breq ende
rjmp LD6

ende:
ldi speed,2
rcall longDelay
ldi temp,0b11111111
;Port B bit 1 ztw. ausgang
out DDRB,temp ; for the piezobuzzer option
dec zahl
rcall ton
ldi temp,Wza

out DDRB,temp
ldi speed,4
rcall longDelay

ldi Temp, Wza ; All LEDs off
out PortB,Temp

ret

;***Tactile feedback note generation routine*****************
;***provides a 4 kHz TONE to the piezo sounder for 5 ms*****
; at 4mhz crystal :-) so we must change
ton:
clr mask

tactile:
cbi PORTB,key ;turn on piezo
ldi temp,20 ;for a short time
t1again: dec temp
brne t1again
sbi PORTB,key ;turn on piezo
ldi temp,20 ;for a short time
t2again: dec temp
brne t2again
inc mask
cpi mask,240 ;is half second up
brne tactile
ldi temp,200
rcall Delay_3
dec zahl ; how many beep's
brpl ton

ret
;sbrs flags,ms5 ;repeat for 5ms
;rjmp tactile



;**********************************************************************

longDelay:
mov temp,speed
clr T1 ;T1 used as delay 2nd count
clr T2 ;T2 used as delay 3d count
delay_1: dec T2
brne delay_1
dec T1
brne delay_1
dec temp ;temp must be preset as
brne delay_1 ; delay master count
ret
;*****************************************************************************
Delay:
ldi temp,60
;mov T1,temp
delay_3: clr T1
delay_2: dec T1
brne delay_2
dec temp ;temp must be preset as
brne delay_2 ; delay master count
ret




;****external rInterrupt service routine***************************************
scan:
in status,SREG ;preserve status register

;xxxxxxxxxxxxxxxxx
;put some code when you want
ldi temp,1
out TCCR0,temp ; start int.Timer for generating flukiness dice

;xxxxxxxxxxxxxxxxx
out SREG,status ;restore status register

ldi temp,0x00
out GIMSK,temp ;disable external interrupt
;have to do this, because we're
;using a level-triggered interrupt

reti