Advertisements
Archive | Assembly RSS feed for this section

MELODY CONVERTER Assembly Language-Tugas I Pengantar Organisasi Komputer

6 Jun

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

Advertisements