Pada tugas I, Anda diminta untuk membuat converter lagu dari not angka diterjemahkan menjadi lafal nada tersebut, atau pun sebaliknya. Misalnya, 1 = Do, 2 = Re, dst. Input not angka lagu ini diletakkan di flash / program memory. Kemudian, hasil outputnya harus Anda tampilkan di LCD.
Contoh:
Input di flash : 1 2 3
Output di LCD : c d e
Input di Flash : c d e
Output di LCD : 1 2 3
Input di Flash : 1 d 3
Output Di LCD : c 2 e
Kemudian, program tersebut dapat menggunakan operator #. Operator # ini menaikkan tangga nada setengah kali.
#1 = cis
#(1 2) = cis dis
#(1 2 3) = cis dis es
##(1 2 3) = d e f
Not atau not-not angka yang dikenai operator #, terletak pada satu baris yang sama.
C D E F G A B = 1 2 3 4 5 6 7
Kode Programnya:
.include "m8515def.inc"
.def temp = r16
.def inputR = r17 ; Register that saves input
.def outputR = r18 ; Register that saves output
.def PB = r19 ; output portB di LCD
.def cKres = r21 ; counter of #
.def lingkup = r22 ; as a status bit is there are any # next to the local input
rjmp START
INIT_LCD:
cbi PORTA,1
ldi PB,0x38
out PORTB,PB
sbi PORTA,0 ; SETB EN
cbi PORTA,0
rcall WAIT_LCD
cbi PORTA,1
ldi PB,$0E
out PORTB,PB
sbi PORTA,0
cbi PORTA,0
rcall WAIT_LCD
cbi PORTA,1
ldi PB,$06
out PORTB,PB
sbi PORTA,0 ; SETB EN
cbi PORTA,0
rcall WAIT_LCD
ret
CLEAR_LCD:
cbi PORTA,1
ldi PB,$01
out PORTB,PB
sbi PORTA,0 ; SETB EN
cbi PORTA,0
rcall WAIT_LCD
ret
WAIT_LCD:
ldi temp, 4
CONT:
dec temp
brne CONT
ret
input:
.db "#(12)"
.db 0 ; the end of input
START:
ldi temp,low(RAMEND)
out SPL,temp
ldi temp,high(RAMEND)
out SPH,temp
rcall INIT_LCD
rcall CLEAR_LCD
ser temp
; initilize port outputR n B as output
out DDRA,temp
out DDRB,temp
ldi ZH,high(2*input)
ldi ZL,low(2*input)
push cKres ; push the value of cKres which is 0
ldi lingkup,1 ; set T
rjmp LoadInput
LoadInput:
lpm inputR,Z+
tst inputR
breq quit
cpi inputR,'A' ; if Capital or not (Letter)
brsh toLetter
cpi inputR,'1' ; if Number
brsh angka
cpi inputR,'('
breq bukaKurung
cpi inputR,')'
breq tutupKurung
cpi inputR,'#'
breq kres
rjmp LoadInput
kres:
inc cKres
ldi lingkup,1
rjmp LoadInput
bukaKurung:
pop temp ; get the cKres value that will affect this char input
push temp ; save the cKres value that maybe will affect the next char input
add cKres,temp ;so now the total cKress that will affect just for this char input
push cKres ; and save it
ldi lingkup,0 ; assign F (to go to the next char input)
ldi cKres,0 ; assign 0 (to go to the next char input)
rjmp LoadInput
tutupKurung:
pop inputR
ldi lingkup,0 ;assign F (to go to the next char input)
rjmp LoadInput
write:
sbi PORTA,1 ; SETB RS
out PORTB, outputR
sbi PORTA,0 ; SETB EN
cbi PORTA,0 ; CLR EN
ret
QUIT :
rjmp QUIT
toLetter:
rjmp Letter
toLoadInput:
rjmp LoadInput
angka:
subi inputR,'1' ;to get the difference value (0-8) not in asci
add inputR,inputR ;mul (*2) to make it easy in finding the output text whether it is affected with # or not
pop temp ;get the value of how many "#" that has already been found
push temp ;store it in stack again
add inputR,temp ; inputR +=cKres
cpi lingkup,1 ; cp if there are any single "#" next to the number(of input)
breq jlhKres
rjmp cekValue
JlhKres:
add inputR, cKres
cekValue:
ldi lingkup,0 ;there's no # next to the input so set F
ldi cKres,0 ;so there's no need push action (no need to update cKres)
tst inputR
;check the value of inputR
InRangeorNot:
breq cetakC dec inputR
breq cetakCis dec inputR
breq cetakD dec inputR
breq cetakDis dec inputR
breq cetakE dec inputR
breq cetakEs dec inputR
breq cetakF dec inputR
breq cetakFis dec inputR
breq cetakG dec inputR
breq cetakGis dec inputR
breq cetakA dec inputR
breq cetakAis dec inputR
breq cetakB dec inputR
breq cetakBis dec inputR
rjmp InRangeorNot ;if inputs>7 than decrement it until equals with the suitable one
cetakC:
ldi outputR, 'C' rcall write
rjmp toLoadInput
cetakCis:
ldi outputR, 'C' rcall write
ldi outputR, 'i' rcall write
ldi outputR, 's' rcall write
rjmp toLoadInput
cetakD:
ldi outputR, 'D' rcall write
rjmp toLoadInput
cetakDis:
ldi outputR, 'D' rcall write
ldi outputR, 'i' rcall write
ldi outputR, 's' rcall write
rjmp toLoadInput
cetakE:
ldi outputR, 'E' rcall write
rjmp toLoadInput
cetakEs:
ldi outputR, 'E' rcall write
ldi outputR, 's' rcall write
rjmp toLoadInput
cetakF:
ldi outputR, 'F' rcall write
rjmp toLoadInput
cetakFis:
ldi outputR, 'F' rcall write
ldi outputR, 'i' rcall write
ldi outputR, 's' rcall write
rjmp toLoadInput
cetakG:
ldi outputR, 'G' rcall write
rjmp toLoadInput
cetakGis:
ldi outputR, 'G' rcall write
ldi outputR, 'i' rcall write
ldi outputR, 's' rcall write
rjmp toLoadInput
cetakA:
ldi outputR, 'A' rcall write
rjmp toLoadInput
cetakAis:
ldi outputR, 'A' rcall write
ldi outputR, 'i' rcall write
ldi outputR, 's'
rcall write rjmp toLoadInput
cetakB:
ldi outputR, 'B' rcall write
rjmp toLoadInput
cetakBis:
ldi outputR, 'B' rcall write
ldi outputR, 'i' rcall write
ldi outputR, 's' rcall write
rjmp toLoadInput
sub20:
subi inputR, $20 ; the difference between small caps and capital is $20
rjmp PreValue
Letter:
cpi inputR,$60 ;if small caps then convert it to the capital one
brsh sub20
PreValue: ;if the input has already been in Capital Letter so
subi inputR, $12 ;get the value that represents in number
pop temp ;get the value of cKres
push temp
cpi lingkup,1 ;check if there are any #next to the input that has already been update
breq jlhKresF
rjmp PreNext
JlhKresF: ;
add temp, cKres ;temp is filled with the total cKress value that this input get affected
PreNext:
ldi cKres,0 ;set 0 utk jlh cKres yg hanya berhubungan dgn input sekrg utk tdk mengefek pd input sesudahnya
rjmp loop
add7:
; if it is A n B then add 7 to it, in intend to gain the correct output that ought to be
ldi r20,7
add inputR,r20
rjmp Output_angka
loop:
subi temp, $2; is k larger set c flag
in r19, SREG
brsh tambah1 ; maonya clear
continue:
out SREG, r19 ; get the saved one of status register
brmi cetakKres ; if the Negative flag from SREG is 1 go to cetakKres
tst temp ; jika cKres == 0
breq Value
rjmp loop
Value:
cpi inputR,'1' ; for letter A,B compare if the input(that has been represented in number) is lower than 1 or not
brlo add7
Output_angka:
;if the answer has already been the correct answer then print it
mov outputR,inputR
rcall write
rjmp LoadInput ;check the next character of the input
tambah1:
inc inputR
rjmp continue
cetakKres:
inc temp ;make temp register not negative
inc temp
cpi temp,$0
breq Value
ldi outputR,'#' ; jika input yg bersangkutan jumlah # nya ganjil maka ada #
rcall write
rjmp Value
Recent Comments