; Specify Device.
.include "tn28def.inc"

;
; registers used 
;

.DEF reg1           =r3;
.DEF reg2           =r4;
.DEF reg3           =r5;
.DEF reg4           =r6;
.DEF reg5           =r7;
.DEF reg6           =r8;
.DEF reg7           =r9;
.DEF reg8           =r10;
	
.DEF rgen1          =r20; general register 1
.DEF rgen2          =R21; general register 2
.DEF rgen3          =R22; general register 3
.DEF rgen4          =R23; general register 4
.DEF old_exponent =r24; 
.DEF exponent     =r25;


; Constants

.EQU OUT_PORT   =PORTD; handles LEDs displaying exponent
.EQU PULSE_OUT  =PORTA; pushes the pulse out
.EQU IN_PORT    =PINB;  Various push buttons
.EQU LED1       =0;
.EQU LED2       =1;
.EQU LED3       =2;
.EQU LED4       =3;
.EQU LED5       =4;
.EQU LED6       =5;
.EQU LED7       =6;
.EQU LED8       =7
.EQU PULSE_PIN  =0;

;
; Code segment start
;
.CSEG

	rjmp Start; 
	rjmp Start;
	rjmp Start;
;
; Subroutines
;

exponent_loop:
    ldi rgen2, 1
    mov reg1, rgen2
    mov reg2, rgen2
    mov reg3, rgen2
    mov reg4, rgen2
    mov reg5, rgen2
    mov reg6, rgen2
    mov reg7, rgen2
    mov reg8, rgen2
    ldi rgen2, 10

    cbr exponent, 0b11000000    ;this game doesnt work for really long values
    mov rgen1, exponent
    cbr rgen1, 0b01111111    ;wipe all bits except one
    cpi rgen1, 0b10000000    ;check if its filled
    brne loop1
    mov reg1, rgen1
loop1:
    mov rgen1, exponent
    cbr rgen1, 0b10111111    ;wipe all bits except one
    cpi rgen1, 0b01000000    ;check if its filled
    brne loop2
    mov reg2, rgen1
loop2:
    mov rgen1, exponent
    cbr rgen1, 0b11011111    ;wipe all bits except one
    cpi rgen1, 0b00100000    ;check if its filled
    brne loop3
    mov reg3, rgen1
loop3:
    mov rgen1, exponent
    cbr rgen1, 0b11101111    ;wipe all bits except one
    cpi rgen1, 0b00010000    ;check if its filled
    brne loop4
    mov reg4, rgen1
loop4:
    mov rgen1, exponent
    cbr rgen1, 0b11110111    ;wipe all bits except one
    cpi rgen1, 0b00001000    ;check if its filled
    brne loop5
    mov reg5, rgen1
loop5:
    mov rgen1, exponent
    cbr rgen1, 0b11111011    ;wipe all bits except one
    cpi rgen1, 0b00000100    ;check if its filled
    brne loop6
    mov reg6, rgen1
loop6:
    mov rgen1, exponent
    cbr rgen1, 0b11111101    ;wipe all bits except one
    cpi rgen1, 0b00000010    ;check if its filled
    brne loop7
    mov reg7, rgen1
loop7:
    mov rgen1, exponent
    cbr rgen1, 0b11111110    ;wipe all bits except one
    cpi rgen1, 0b00000001    ;check if its filled
    brne loop8
    mov reg8, rgen2
loop8:
    dec reg8
    brne loop8
    dec reg7
    brne loop7
    dec reg6
    brne loop6
    dec reg5
    brne loop5
    dec reg4
    brne loop4
    dec reg3
    brne loop3
    dec reg2
    brne loop2
    dec reg1
    brne loop1
    ret
	
delay20ms:
    ldi rgen1, 60
outer_loop:
    ldi rgen2, 255
inner_loop:
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    dec rgen2
    brne inner_loop
    dec rgen1
    brne outer_loop
    ret

delaysec:
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
    rcall delay20ms          ;call a debounce delay routine
	ret

; Start of program
;
Start:
;
; Setup the stack for the use of subroutines
;

; .EQU LEDS_OUT   =PORTD; handles LEDs displaying exponent
; .EQU PULSE_OUT  =PORTA; pushes the pulse out
; .EQU IN_PORT    =PINB;  Various push buttons

    ldi rgen1, 0b00001011     ;load register with all 1's
    out PACR, rgen1           ;configure PORT A

    ldi rgen1, 0b11111111     ;load register with all 1's
    out DDRD, rgen1           ;configure PORT D
	

main_loop:
    in  rgen2, IN_PORT

; must go to most significant bit with a one, and then fill all the bits to that point with ones
; e.g., convert 00101000  --> 00111111
	com rgen2                ; invert all the bits, HIs are set to LOs
    cbr rgen2, 0b10000000    ;not looking at the last bit
    mov rgen1, rgen2
	
    cbr rgen1, 0b11011111    ;wipe bits
    cpi rgen1, 0b00100000    ;check bit
    brne check_next1         ;check more
    ldi rgen1, 0b00111111    ;load value
	rjmp end_checks

check_next1:
    mov rgen1, rgen2
    cbr rgen1, 0b11101111    ;wipe bits
    cpi rgen1, 0b00010000    ;check bit
    brne check_next2         ;check more
    ldi rgen1, 0b00011111    ;load value
	rjmp end_checks

check_next2:
    mov rgen1, rgen2
    cbr rgen1, 0b11110111    ;wipe bits
    cpi rgen1, 0b00001000    ;check bit
    brne check_next3         ;check more
    ldi rgen1, 0b00001111    ;load value
	rjmp end_checks

check_next3:
    mov rgen1, rgen2
    cbr rgen1, 0b11111011    ;wipe bits
    cpi rgen1, 0b00000100    ;check bit
    brne check_next4         ;check more
    ldi rgen1, 0b00000111    ;load value
	rjmp end_checks

check_next4:
    mov rgen1, rgen2
    cbr rgen1, 0b11011101    ;wipe bits
    cpi rgen1, 0b00000010    ;check bit
    brne check_next5         ;check more
    ldi rgen1, 0b00000011    ;load value
	rjmp end_checks

check_next5:
    mov rgen1, rgen2
    cbr rgen1, 0b11011110    ;wipe bits
    cpi rgen1, 0b00000001    ;check bit
    brne end_checks          ;check more
    ldi rgen1, 0b00000001    ;load value

end_checks:

  	out OUT_PORT, rgen1       ;light em up.
    mov	exponent, rgen1

	
    in rgen1, IN_PORT        ;read input buffer
    cbr rgen1, 0b10111111    ;wipe all bits except the first
    cpi rgen1, 0b01000000    ;check its on
    breq switch_tests_done   ;if not check more

wait_for_rel_of_up:
    in rgen1, IN_PORT        ;read input buffer
    cbr rgen1, 0b10111111    ;wipe all bits except the 2nd
    cpi rgen1, 0b01000000    ;perform test for release
    brne wait_for_rel_of_up
    rcall delay20ms          ; debounce after release
	sbi PULSE_OUT, PULSE_PIN 
    rcall exponent_loop
	cbi PULSE_OUT, PULSE_PIN
	rcall delaysec

	
switch_tests_done:


rjmp main_loop
