Tuesday, October 28, 2014

DE0 and Assembly

Its been a while since the last post, but the future posts will definitely make up for that (be excited). As a small post, I can show you all something I've done for a class called Programming Digital Systems. PDS, as it is called, instructs on the architecture of embedded systems as well as the use of assembly as a language. Assembly is remarkably tedious, but very rewarding when functional. My future project, to be unveiled soon, will uses assembly exclusively.

Directional Arrow Scroll

/* John Dunn        */  
/* Oct, 28 2014        */
/*          */
/* This program goes through a series of screen states, then restarts. */
/* If PSHBTN1 or PSHBTN2 is presse the states are reversed.  */
/*          */
/* Register Usage:        */
/* - r5: Current State of Button after ldwio from r16   */
/* - r7: Delay Counter       */
/* - r8: Current State       */
/* - r9: State Counter (Starts at 8 and is checked for r9==0)  */
/* - r13: Direction indicator (0 is R2L, 1 is L2R)    */
/* - r14: Base Address of the current set of states (R2L or L2R)  */
/* - r15: HEX3_HEX0 Base Address      */
/* - r16: Pushbutton 1&2 Base Address     */

 .text
 .global _start
_start:
 movia r13, 0    /* Initially have go right to left. */ 
 movia  r14, R2L_STATES   
 movia  r15, 0x10000020 
 movia r16, 0x10000050   
     ldw  r8, 0(r14)   /* Load the STATE into r8. */
     addi  r9, r0, 8         /* Set our STATE counter to 8. */

CHECK_R2L_RESET:
 bne r13, r0, CHECK_L2R_RESET /* IF the Direction is L2R, GOTO CHECK_L2R_RESET. */
     beq  r9, r0, R2L_RESET    /* ELSE the Direction must be R2L. */
      /* See if the state counter is at 0. */
      /* If it is, GOTO R2L_RESET. */ 
 br DO_DISPLAY    
CHECK_L2R_RESET:
     beq  r9, r0, L2R_RESET    /* ELSE the Direction must be L2R. */
      /* See if the state counter is at 0. */
      /* If it is, GOTO L2R_RESET. */
 br DO_DISPLAY 

R2L_RESET:
     movia r14, R2L_STATES   /* Reset the State address back to */
      /* the base address for R2L_STATES. */
     ldw r8, 0(r14)   /* Load the first state into r8. */
     addi    r9, r0, 8   /* Reset the State Counter to 8. */
     br      DO_DISPLAY
L2R_RESET:
     movia r14, L2R_STATES   /* Reset the State address back to */
      /* the base address for L2R_STATES.*/
     ldw r8, 0(r14)   /* Load the first state into r8. */
 addi    r9, r0, 8   /* Reset the State Counter to 8. */
 br DO_DISPLAY

DO_DISPLAY:
 stwio r8, 0(r15)   /* Display the value in r8 */
     addi r14, r14, 4       /* Get address of next state*/
     ldwio r8, 0(r14)   /* Load the next state into r8*/
     subi r9, r9, 1         /* Decrement the state counter*/
 
 ldwio r5, 0(r16)   /* Load the current state of the Pushbuttons to r5. */ 
 beq r5, r0, NO_BUTTON  /* If a button isn't pressed, GOTO NO_BUTTON. */
 beq r13,r0,SET_DIR_L2R  /* If the Direction is R2L, GOTO SET_DIR_L2R. */

SET_DIR_R2L:
 addi r13,r0,0   /* Change r13 from 1 -> 0. */
 br L2R_R2L_SWITCH_RESET  
SET_DIR_L2R:
 addi  r13,r0,1   /* Change r13 from 0 -> 1. */
 br R2L_L2R_SWITCH_RESET

L2R_R2L_SWITCH_RESET:
 addi    r9, r0, 8   /* Reset the State Counter*/
     movia r14, R2L_STATES   /* Reset the State address back to the base address */
     ldw r8, 0(r14)   /* Load the first state into r8 */
 br WAIT
R2L_L2R_SWITCH_RESET:
 addi    r9, r0, 8   /* Reset the State Counter*/
     movia r14, L2R_STATES   /* Reset the State address back to the base address */
     ldw r8, 0(r14)   /* Load the first state into r8 */
 
WAIT:
 ldwio  r5, 0(r16)   /* Wait for the button to be released */
 bne r5, r0, WAIT

NO_BUTTON:
 movia r7, 250000   /* Here we will delay. */ 

DELAY: 
 subi r7, r7, 1
 bne r7, r0, DELAY
 br  CHECK_R2L_RESET:
 
 .data

R2L_STATES:  
 .word  0x00000079
 .word  0x00007949
 .word 0x00794949
 .word 0x79494940
 .word  0x49494000
 .word 0x49400000
 .word 0x40000000
 .word 0x00000000

L2R_STATES:
 .word  0x4F000000
 .word  0x494F0000
 .word 0x49494F00
 .word 0x4049494F
 .word  0x00404949
 .word 0x00004049
 .word 0x00000040
 .word 0x00000000
 .end

GOBUFFS Cheer Screen

/* John Dunn        */  
/* Oct, 28 2014        */
/*          */
/* This program goes through a series of screen states, then restarts. */
/*          */
/* Register Usage:        */
/* - r7: Delay Counter       */
/* - r8: Current State       */
/* - r9: State Counter (Starts at 23 and is tested for r9==0)  */
/* - r14: Base address of STATES      */
/* - r15: Base address of HEX3_HEX0     */

 .text
 .global _start
_start:

 movia  r14, STATES  
 movia  r15, 0x10000020 
     ldw  r8, 0(r14)   /* Load the STATE into r8. */
     addi  r9, r0, 23        /* Set our STATE counter to 23. */

DO_DISPLAY:
     beq  r9, r0, RESET     /* If we have finished all the states, GOTO RESET. */
 stwio r8, 0(r15)   /* Display the value in r8. */


     addi r14, r14, 4       /* Get address of next state. */
     ldw r8, 0(r14)   /* Load the next state into r8. */
     subi r9, r9, 1         /* Decrement the state counter. */

 movia r7, 500000   /* Here we will Delay. */ 
DELAY: 
 subi r7, r7, 1
 bne r7, r0, DELAY
 br  DO_DISPLAY
RESET:
     addi    r9, r0, 23   /* Reset the State Counter*/
     movia r14, STATES   /* Reset the State address back to the base address */
     ldw r8, 0(r14)   /* Load the first state into r8 */
     br      DO_DISPLAY

 .data
STATES:
 .word 0x00063000
 .word 0x00300600
 .word 0x06000030
 .word 0x30000006
 .word 0x303D3F06
 .word 0x00000000
 .word 0x303D3F06
 .word 0x00000000
 .word 0x0000007C
 .word 0x00007C3E
 .word 0x007C3E71
 .word 0x7C3E7171
 .word 0x3E71716D
 .word 0x71716D00
 .word 0x716D0000
 .word 0x6D000000
 .word 0x00000000
 .word 0x2908010D
 .word 0x30090906
 .word 0x1901080B
 .word 0x2908010D
 .word 0x30090906
 .word 0x1901080B
 .end
-John "Large Finite State Machines are Large" Dunn