Skip to content

Instantly share code, notes, and snippets.

@kizzlebot
Created April 11, 2014 16:24
Show Gist options
  • Save kizzlebot/10481842 to your computer and use it in GitHub Desktop.
Save kizzlebot/10481842 to your computer and use it in GitHub Desktop.
; James choi
; Lab #2 Part 2.2D - Print the SW1 and SW2 statuses to Hyperterminal
;---------------------------------------------------------------------------------------------------------
; Enable C-Headers
;---------------------------------------------------------------------------------------------------------
.cdecls C,LIST,"msp430fg4618.h"
;---------------------------------------------------------------------------------------------------------
; Assembler Directives Setup
;---------------------------------------------------------------------------------------------------------
.sect ".const"
.bss label, 4 ; Reserve 4 unitialized bytes in .bss section (located in RAM)
.word 0x1234
CHARACTER .byte 0x5f, 0x06, 0x6b, 0x2f, 0x36
.byte 0x3d, 0x7d, 0x07, 0x7f, 0x37
.byte 0x77, 0x7c, 0x68, 0x6E, 0x79, 0x71
.byte 0x20, 0x00
.sect ".sysmem"
LCD_SIZE .byte 11
;---------------------------------------------------------------------------------------------------------
; Enter program
;---------------------------------------------------------------------------------------------------------
.text ; program start
.global _START ; define entry point
;---------------------------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------------------------
START
mov.w #300h,SP ; Initialize stack pointer (immediate addressing)
mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop Watchdog Timer
bis.b #0x06, &P2DIR ; BItSet Port 2.1 and Port 2.2 Direction Ctrl as an output
bis.b #0x00, &P1DIR ; BItSet Port 1 Direction Ctrl as input
call #Init_UART ; Store PC+2 (MainLoop) and branch to immediate val (Init_UART)
call #Init_LCD
;---------------------------------------------------------------------------------------------------------
MainLoop ; Arguments: N/A
; Returns: N/A
;---------------------------------------------------------------------------------------------------------
xor.b #0x06,&P2OUT
mov.w #0xA000,R5
_Delay dec.w R5
jnz _Delay
;---------------------------------------------------------------------------------------------------------
;call #readHex2 ; Part 1 checked
;call #LCD_Out2
;call #CRLF
;call #addition ; Part 2 checked
;call #subtraction ; Part 3 checked
;call #multiply ; Part 4 checked
call #prompt ; Part 5 checked
;---------------------------------------------------------------------------------------------------------
jmp MainLoop
;---------------------------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------------------------
prompt
;---------------------------------------------------------------------------------------------------------
mov.w #0x3E, R4
call #OUTA
call #SPACE
_prompt call #INCHAR
chkM cmp.b #'*', R4
jnz chkAdd
call #CRLF
call #multiply
jmp prompt_ret
chkAdd cmp.b #'+', R4
jnz chkSub
call #CRLF
call #addition
jmp prompt_ret
chkSub cmp.b #'-', R4
jnz _prompt
call #CRLF
call #subtraction
prompt_ret ret
;----------------------------------------------------------------
LCD_Out4 ; R4 contains 0x0ABC
;----------------------------------------------------------------
push.w R5
push.w R4
mov.b #0x03, R5
swpb R4
rra.b R4
rra.b R4
rra.b R4
rra.b R4
and.b #0x0F, R4
call #LCD_Out1
pop.w R4
push.w R4
dec.b R5
swpb R4
and.b #0x0F, R4
call #LCD_Out1
pop.w R4
push.w R4
dec.b R5
rra.b R4
rra.b R4
rra.b R4
rra.b R4
and.w #0x0f, R4
call #LCD_Out1
pop.w R4
push.w R4
dec.b R5
and.w #0x0F, R4
call #LCD_Out1
pop.w R4
pop.w R5
ret
;----------------------------------------------------------------
LCD_Out3_Neg ; R4 contains 0x0ABC
;----------------------------------------------------------------
push.w R5
push.w R4
mov.w #0x10, R4
mov.w #0x02, R5
call #LCD_Out1
mov.w #0x11, R4
mov.w #0x03, R5
call #LCD_Out1
pop.w R4
push.w R4
dec.w R5
jmp l_out2
;----------------------------------------------------------------
LCD_Out3 ; R4 contains 0x0ABC
;----------------------------------------------------------------
push.w R5
push.w R4
mov.b #0x02, R5
push.w R5
push.w R4
mov.w #0x11, R4
mov.w #0x03, R5
call #LCD_Out1
pop.w R4
pop.w R5
l_out3 swpb R4
and.b #0x0F, R4
call #LCD_Out1
pop.w R4
push.w R4
dec.b R5
rra.b R4
rra.b R4
rra.b R4
rra.b R4
and.b #0x0F, R4
call #LCD_Out1
pop.w R4
push.w R4
dec.b R5
and.w #0x000F, R4
call #LCD_Out1
pop.w R4
pop.w R5
ret
;----------------------------------------------------------------
LCD_Out2
;----------------------------------------------------------------
push.w R5
push.w R4
mov.w #0x11, R4
mov.w #0x02, R5
call #LCD_Out1
pop.w R4
pop.w R5
push.w R5
push.w R4
l_out2 mov.b #0x01, R5
rra.b R4
rra.b R4
rra.b R4
rra.b R4
and.b #0x0F, R4
call #LCD_Out1
dec.b R5
pop.w R4
push.w R4
and.w #0x0F, R4
call #LCD_Out1
pop.w R4
pop.w R5
ret
;-------------------------------------------------------------------------
LCD_Out1 ; R4 val to print
; R5 segment
;-------------------------------------------------------------------------
push.w R6
push.w R7
; Move address to the indicated seg
mov.w #LCDM3, R7
add.w R5, R7
; move Adddress to indicated character
mov.w #CHARACTER, R6
add.w R4, R6
mov.b 0(R6), R6
mov.w R6, 0(R7)
pop.w R7
pop.w R6
ret
;-------------------------------------------------------------------------
LCD_Clr
;-------------------------------------------------------------------------
push.w R6
push.w R5
mov.w #LCDM3, R6
mov.w #0x06, R5
clrLCD mov.w #0x00, 0(R6)
dec.w R6
dec.w R5
jnz clrLCD
pop.w R5
pop.w R6
ret
;---------------------------------------------------------------------------------------------------------
; ___ _ _ _ _ _
; / _ \ (_)| | | | | | (_)
; / /_\ \ _ __ _ | |_ | |__ _ __ ___ ___ | |_ _ ___
; | _ || '__|| || __|| '_ \ | '_ ` _ \ / _ \| __|| | / __|
; | | | || | | || |_ | | | || | | | | || __/| |_ | || (__
; \_| |_/|_| |_| \__||_| |_||_| |_| |_| \___| \__||_| \___|
;---------------------------------------------------------------------------------------------------------
multiply
;*****************************************************************
push.w R7
push.w R6
push.w R5
push.w R4
mov.w #0x0000, R7 ; Accumulate in R7
call #readHex2
mov.w R4, R5
call #MULT
call #readHex2
_bitByBit mov.w R5, R6 ; Move R5 to R6 and test R6 for 1 in lsb
and.w #0x0001, R6
jz _nextIter
add.w R4, R7
_nextIter call #shiftLeftW ; ShiftL R4
mov.w R4, R6 ; Save R4 in R6 so I can shiftR R5
mov.w R5, R4 ; Use R5 as argument to shiftR
call #shiftRightW ; ShiftR R5
mov.w R4, R5 ; move result to r5
mov.w R6, R4 ; move R4 back
cmp.w #0x0000, R5 ; When out R5 contains no 1's, we're done
jnz _bitByBit
call #EQUALS
mov.w R7, R4
call #printVal4
call #CRLF
call #LCD_Out4
pop.w R4
pop.w R5
pop.w R6
pop.w R7
ret
;----------------------------------------------------------------
addition
;----------------------------------------------------------------
push.w R4
push.w R5
; Read first two hex digits
call #readHex2
mov.b R4, R5
call #PLUS
call #readHex2
call #EQUALS
; Calculate the sum into R4 and print it
add.w R5,R4
call #printVal3
call #CRLF
call #LCD_Out3
pop.w R5
pop.w R4
ret
;----------------------------------------------------------------
subtraction
;----------------------------------------------------------------
push.w R4
push.w R5
push.w R6
call #readHex2
mov.b R4, R6
call #MINUS
call #readHex2
mov.b R4, R5
mov.b R6, R4
call #EQUALS
sub.w R5,R4
jn _subNeg
jmp _printSub
_subNeg inv.w R4
add.w #0x0001, R4
call #NEGATIVE
call #LCD_Out3_Neg
call #printVal3
call #CRLF
jmp _subFin
_printSub call #printVal3
call #CRLF
push.w R5
push.w R4
mov.w #0x11, R4
mov.w #0x03, R5
call #LCD_Out1
pop.w R4
pop.w R5
call #LCD_Out2
_subFin pop.w R6
pop.w R5
pop.w R4
ret
;---------------------------------------------------------------------------------------------------------
; ______ _ _
; | ___ \ (_) | |
; | |_/ /_ __ _ _ __ | |_
; | __/| '__|| || '_ \ | __|
; | | | | | || | | || |_
; \_| |_| |_||_| |_| \__|
;---------------------------------------------------------------------------------------------------------
;*****************************************************************
printVal4
;*****************************************************************
push.w R4
swpb R4
and.w #0x00ff, R4
call #printVal2
pop.w R4
push.w R4
and.w #0x00ff, R4
call #printVal2
pop.w R4
ret
;*****************************************************************
printVal3
;*****************************************************************
push.w R4
swpb R4
and.w #0x000f, R4
call #printVal1
pop.w R4
push.w R4
and.w #0x00ff, R4
call #printVal2
pop.w R4
ret
;*****************************************************************
printVal2
;*****************************************************************
push.w R4 ; R4: (0011 1110)
rra.b R4 ; R4: (0001 1111)
rra.b R4 ; R4: (1000 1111)
rra.b R4 ; R4: (1100 0111)
rra.b R4 ; R4: (1110 0011)
and.w #0x000F, R4 ; R4: (0000 0011)
call #printVal1
pop.w R4
push.w R4
and.w #0x000F, R4 ; R4: (0000 1110)
call #printVal1
pop.w R4
ret
;*****************************************************************
printVal1 ; If R4 = 0x0A, will print 'A' to terminal
;*****************************************************************
cmp.b #0x0A, R4
jl isNum
add.b #0x37, R4
call #OUTA
sub.b #0x37, R4
ret
isNum add.b #0x30, R4
call #OUTA
sub.b #0x30, R4
ret
;----------------------------------------------------------------
readTwoArgs4 ; Returns two sets of 4 digit hex in R4 and R5
;----------------------------------------------------------------
push.w R6
call #readHex4
mov.w R4, R6
call #SPACE
call #readHex4
mov.w R4, R5
mov.w R6, R4
call #SPACE
pop.w R6
ret
;----------------------------------------------------------------
readHex4
;----------------------------------------------------------------
push.w R5
mov.w #0x0000, R5
call #readHex2
mov.w R4,R5
swpb R5
call #readHex2
and.w #0x00FF, R4
xor.w R5, R4
pop.w R5
ret
;----------------------------------------------------------------
readHex2
;----------------------------------------------------------------
push.w R5
call #readHex
mov.b R4, R5
and.w #0x00FF,R5
rla.b R5
rla.b R5
rla.b R5
rla.b R5
call #readHex
and.w #0x00FF,R4
xor.w R5, R4
pop.w R5
ret
;*****************************************************************
readHex ; Reads a asciiHex, prints it, converts it to the
; value it represents and returns
;*****************************************************************
call #INCHAR
call #validateAsciiHex
cmp.b #0x00, R4
jz readHex
call #OUTA
call #asciiToVal
ret
;----------------------------------------------------------------
validateAsciiHex ; Will put 0x00 into R4 if R4 isn't valid hex
; ascii range
;----------------------------------------------------------------
; check for 0-
cmp.b #0x30,R4 ; R4 < 0
jl invalid ; If less, read again
; check fo -9
cmp.b #0x3A,R4
jn verified
; check for ~A-
cmp.b #0x41,R4 ; 0x41 < R4
jl invalid ; If less, read again
; check fo -F
cmp.b #0x47,R4 ; R4-0x47 < 0
jn verified
; check for ~a-
cmp.b #0x61,R4 ; R4-0x2F > 0
jl invalid ; If n set, jump to ret
; check fo ~-f
cmp.b #0x67,R4
jn Cap
jmp invalid
Cap sub.b #0x20,R4
verified ret
invalid mov.b #0x00, R4
ret
;----------------------------------------------------------------
asciiToVal ; Takes ascii byte in R4 and makes it into
; hexadecimal digit. R4 must be verified to
; be a valid g
;----------------------------------------------------------------
and.w #0x00FF,R4
cmp.b #0x41, R4
jhs isChar
sub.b #0x30, R4
jmp asciiToValFin
isChar sub.b #0x37, R4
asciiToValFin ret
;----------------------------------------------------------------
waitForEnter
;----------------------------------------------------------------
push.w R4
enterWait call #INCHAR
cmp.b #0x0D, R4
jnz enterWait
pop.w R4
ret
;---------------------------------------------------------------------------------------------------------
; _ _ _
; | | | | | |
; | |_| | ___ | | _ __ ___ _ __ ___
; | _ | / _ \| || '_ \ / _ \| '__|/ __|
; | | | || __/| || |_) || __/| | \__ \
; \_| |_/ \___||_|| .__/ \___||_| |___/
; | |
; |_|
;---------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------
shiftLeftW
;----------------------------------------------------------------
rla.w R4 ; Move MSB to LSB
and.w #0xFFFE, R4 ; Zero out the LSB
ret
;----------------------------------------------------------------
shiftRightW
;----------------------------------------------------------------
rra.w R4
and.w #0x7FFF, R4
ret
;---------------------------------------------------------------------------------------------------------
; _____ _ _
; / __ \| | | |
; | / \/| |__ __ _ _ __ __ _ ___ | |_ ___ _ __ ___
; | | | '_ \ / _` || '__|/ _` | / __|| __|/ _ \| '__|/ __|
; | \__/\| | | || (_| || | | (_| || (__ | |_| __/| | \__ \
; \____/|_| |_| \__,_||_| \__,_| \___| \__|\___||_| |___/
;---------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------
CR
;----------------------------------------------------------------
push.w R4
mov.b #0x0D, R4 ; CR
call #OUTA
pop.w R4
ret
;----------------------------------------------------------------
LF
;----------------------------------------------------------------
push.w R4
mov.b #0x0A, R4 ; LF
call #OUTA
pop.w R4
ret
;----------------------------------------------------------------
NULL
;----------------------------------------------------------------
push.w R4
mov.b #0x00, R4
call #OUTA
pop.w R4
ret
;----------------------------------------------------------------
CRLF
;----------------------------------------------------------------
call #CR
call #LF
call #NULL
ret
;----------------------------------------------------------------
SPACE
;----------------------------------------------------------------
push.w R4
mov.b #0x20, R4 ; SPACE
call #OUTA
pop.w R4
ret
;----------------------------------------------------------------
PLUS
;----------------------------------------------------------------
call #SPACE
push R4
mov.b #0x2B, R4 ; +
call #OUTA
pop R4
call #SPACE
ret
;----------------------------------------------------------------
MINUS
;----------------------------------------------------------------
call #SPACE
push R4
mov.b #0x2D, R4 ; -
call #OUTA
pop R4
call #SPACE
ret
;----------------------------------------------------------------
EQUALS
;----------------------------------------------------------------
call #SPACE
push R4
mov.b #0x3D, R4 ; =
call #OUTA
pop R4
call #SPACE
ret
;----------------------------------------------------------------
MULT
;----------------------------------------------------------------
call #SPACE
push R4
mov.b #0x2A, R4 ; =
call #OUTA
pop R4
call #SPACE
ret
;----------------------------------------------------------------
NEGATIVE
;----------------------------------------------------------------
push R4
mov.b #0x2D, R4 ; -
call #OUTA
pop R4
ret
;---------------------------------------------------------------------------------------------------------
;------------------------------UART Input/Output Procedures ----------------------------------------------
;---------------------------------------------------------------------------------------------------------
Init_LCD
;---------------------------------------------------------------------------------------------------------
mov.b #0x00, R6
mov.w #LCDM3,R5
mov.b #0x00, R7
lpt mov.b R7, 0(R5)
inc.w R5
inc.b R6
cmp.b LCD_SIZE, R6
jnz lpt
mov.b #0x1C, &P5SEL
mov.b #0x00, &LCDAVCTL0
mov.b #0x7E, &LCDAPCTL0
mov.b #0x7d, &LCDACTL
ret
;---------------------------------------------------------------------------------------------------------
Init_UART ; Initalize registers for UART
;---------------------------------------------------------------------------------------------------------
mov.b #0x30, &P2SEL ; According to schematics for fg4618: P2.4 (TX), P2.5 (RX)
mov.b #0x00, &UCA0CTL0
mov.b #0x41, &UCA0CTL1
mov.b #0x00, &UCA0BR1
mov.b #0x03, &UCA0BR0
mov.b #0x06, &UCA0MCTL
mov.b #0x00, &UCA0STAT
mov.b #0x40, &UCA0CTL1
mov.b #0x00, &IE2
ret
;---------------------------------------------------------------------------------------------------------
INCHAR ; Save R5. Keep checking RXFlag to see if RXBuffer full. When it is, move the data from
; RXbuffer to R4, restore R5 and return to calling procedure
;---------------------------------------------------------------------------------------------------------
push R5 ; Preserve current value in R5 by pushing to stack
lpb
mov.b &IFG2,R5 ; Move BufferFlagReg to R5. Mem[IFG2] -> R5
and.b #0x01,R5 ; Isolate val of R5.1 (RXIFG)
cmp.b #0x00,R5 ; Do R5-0x00
jz lpb ; If prev. instruction results in zero jump back
mov.b &UCA0RXBUF,R4 ; Move Received Data from rx buffer to Register 4
pop R5 ; Restore former value of R5
ret ; Return to calling procedure
;---------------------------------------------------------------------------------------------------------
OUTA ; Save R5. Keep checking TXFlag to see if TXBuffer empty. When it is, move the data from
; R4 to TXBuffer, restore R5 and return to calling procedure
;---------------------------------------------------------------------------------------------------------
push R5 ; Preserve current value in R5 by pushing to stack
lpa
mov.b &IFG2,R5 ; Move BufferFlagReg to R5. Mem[IFG2] -> R5
and.b #0x02,R5 ; Isolate val of R5 bit 2
cmp.b #0x00,R5 ; Do R5-0x00
jz lpa ; If prev. instruction results in zero, jump back
mov.b R4,&UCA0TXBUF ; Move data to transmit from R4 to tx buffer
pop R5 ; Restore R5
ret ; Return to calling procedure
;---------------------------------------------------------------------------------------------------------
;------------------------------! END UART Input/Output Procedures END! -----------------------------------
;---------------------------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------------------------
; Interrupt Vector Assembly Directives
;---------------------------------------------------------------------------------------------------------
.sect ".reset" ; MSP430 RESET Vector
.short START ;
.end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment