; Filename: prob4Game.s ; Author: ECE 353 staff ; Description: solution code for hw#4 prob 4 ARM EXPORT __main INCLUDE aduc7026.inc AREA FLASH, CODE, READONLY __main ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setup PLL for operation from internal oscillator ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LDR R7, = (PLL_MMR_BASE) MOV R0, #0x55 MOV R1, #0x21 ;This is not necessary since this is default MOV R2, #0xAA ;PLLCON value for normal op from internal osc STR R0, [R7, #PLLKEY1] ;Must write KEY1 and KEY2 with correct data STR R1, [R7, #PLLCON] ;Write PLLCON for oscillator operation STR R2, [R7, #PLLKEY2] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setup POWCON for active mode, and div 8 HCLK (5.22MHz) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV R0, #0x01 MOV R1, #0x03 ;This is not necessary either since it is default MOV R2, #0xF4 ;POWCON value for normal with div 8 HCLK STR R0, [R7, #POWKEY1] ;Must write KEY1 and KEY2 with correct data STR R1, [R7, #POWCON] ;Write POWCON for normal op at 5.22MHz STR R2, [R7, #POWKEY2] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setup Timer0 for div 16 operation and reload ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LDR R7, =(TIMER_MMR_BASE) ; Base pointer for timer registers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Don't need the reload functionality, I was just checking something else ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LDR R0, =(0xFFFD) ; reload value for T0VAL = 0 at 0.1sec when at 5.22MHz STR R0, [R7,#T0LD] MOV R0, #0xC8 ; Enable timer for reload and div 16 STR R0, [R7,#T0CON] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setup Port0 direction and data ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LDR R8, =(GPIO_MMR_BASE) ;Base pointer for GPIO registers MOV R0, #0 STR R0, [R8,#GP0CON] ;Setup P0 for all GPIO LDR R0, =(0xFF010000) ;Setup P0 for all output with a 0x01 as data STR R0, [R8,#GP0DAT] ;Actually write to GP0DAT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setup Port1 direction and data ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV R0, #0 STR R0, [R8,#GP1CON] ;Setup P1 for all GPIO LDR R0, =(0xFF000000) ;Setup P1 for all output with a 0x00 as score STR R0, [R8,#GP1DAT] ;Actually write to GP1DAT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setup Port2 direction and data ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV R0, #0 STR R0, [R8,#GP2CON] ;Setup P2 for all GPIO LDR R0, =(0x00000000) ;Setup P2 for all input STR R0, [R8,#GP2DAT] ;Actually write to GP1DAT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Grab current state of Timer0 MSB ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LDR R1, [R7,#T0VAL] ; R1 will contain capture of current T0 MSB MOV R3, #0x00010000 ; will start with LSB of Port0 set ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Initialize score and try counter ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Restart MOV R4, #0; ; Score starts at zero STR R4, [R8,#GP1DAT] ; actually write score register MOV R5, #0; ; Try counter starts at zero main_poll ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This portion tests the T0 MSB ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LDR R0, [R7,#T0VAL] ; read current value of T0 EOR R2, R1, R0 ; XOR to check MSB (bit 15) TST R2, #0x00008000 ; is bit 15 set BNE Shft_port ; Routine to move the LED on Port0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Polls Port2.0 input to see if ;; ;; stop_n/start button pushed. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LDR R0, [R8,#GP2DAT] TST R0, #0x01 ; Test the stop/start_n bit for a stop BEQ stop_bttn B main_poll Shft_port MOV R1, R0 ; update R1 (T0 MSB capture value) STR R3, [R8,#GP0CLR] ; Clear the port bits TEQ R3, #0x00800000 ; is MSB of Port0 data set MOVNE R3, R3, LSL #1 ; if not in MSB then left shift MOVEQ R3, #0x00010000 ; if is in MSB then set to LSB STR R3, [R8,#GP0SET] ; Set the port bits B main_poll ; return to main loop stop_bttn ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; First check where LED was, and compute score ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CMP R3, #0x00800000 ADDEQ R4, R4, #1 ; only 1 point for a near miss CMP R3, #0x00400000 ADDEQ R4, R4, #10 ; 10 points for right on CMP R3, #0x00200000 ADDEQ R4, R4, #1 ; only 1 point for a near miss MOV R0, R4, LSL #16 ; shift up into output position STR R0, [R8, #GP1DAT] ; write the score out. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Now wait for Port2.0 to be raised ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; wait_start_n LDR R0, [R8,#GP2DAT] ; Read Port2 to test TST R0, #0x01 ; Test the stop/start_n bit for a stop BEQ wait_start_n ADD R5, R5, #1 ; increment try counter CMP R5, #5 ; compare to 5 tries/game BEQ Game_Over B main_poll ; return to main loop Game_Over LDR R0, [R8,#GP2DAT] TST R0, #0x02 ; Test the stop/start_n bit for a stop BNE Game_Over ; Stay in this loop till Port2.1 cleared Wait_Set LDR R0, [R8,#GP2DAT] ; Read Port2.1 looking for rise TST R0, #0x02 BEQ Wait_Set B Restart END