; 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