OpenCores
URL https://opencores.org/ocsvn/RISCMCU/RISCMCU/trunk

Subversion Repositories RISCMCU

[/] [RISCMCU/] [trunk/] [asm/] [simple_calculator.asm] - Rev 28

Compare with Previous | Blame | View Log

.include "riscmcu.inc"

.def    key = r16
.def    temp = r17
.def    B = r18
.def    C = r19
.def    addsub = r24
.def    counter = r25
.def    tcount = r26
.def    led = r27

.cseg
        rjmp    reset
        rjmp    extint
        rjmp    timer

extint:
        clr     B
        clr     C
        clr     addsub
        out     portb,c
        reti

timer:
        in      temp,sreg
        inc     tcount
        cpi     tcount,24
        brne    tback
        clr     tcount
        cpi     led,0b10000
        brne    t4
        ldi     led,0b0001      
t4:     com     led
        out     portc,led
        com     led
        lsl     led
        out     sreg,temp
tback:  reti                    


reset:

        clr     B
        clr     C
        clr     addsub
        ldi     counter,3
        ldi     led,0b0001

        ldi     temp,0b11110000
        out     ddrd,temp
        ser     temp
        out     ddrb,temp       ; PORT B as output
        out     ddrc,temp       ; PORT C as output
        out     portc,temp      ; PORT C leds OFF
        out     portd,temp      ; PORT D output HI
        out     gimsk,temp      ; Enable external interrupt
        out     timsk,temp      ; Enable Timer interrupt
        ldi     temp,5
        out     tccr0,temp      ; timer clock source = divide by 1024

        rcall   ldtable
        sei

;*************************************************
; Detect Keys

rescan: rcall   sdelay
        
        sbi     portd,6
        cbi     portd,4
        ldi     zp,table
        in      key,pind
        cbr     key,$F0
        cpi     key,$0F
        brne    press

        sbi     portd,4
        cbi     portd,5
        ldi     zp,table+1
        in      key,pind
        cbr     key,$F0
        cpi     key,$0F
        brne    press

        sbi     portd,5
        cbi     portd,6
        ldi     zp,table+2
        in      key,pind
        cbr     key,$F0
        cpi     key,$0F
        brne    press

        rjmp    rescan

press:
        rcall   sdelay
        in      temp,pind
        cbr     temp,$F0
        cpse    key,temp
        rjmp    rescan
        sbrs    key,1
        subi    zp,-3
        sbrs    key,2
        subi    zp,-6
        sbrs    key,3   
        subi    zp,-9
        ld      key,Z

;*************************************************
; Operation

        cpi     key,$A
        breq    addkey
        cpi     key,$B
        breq    subkey
        
        swap    B
        cbr     B,$0f
        add     B,key
        out     portb,B

        rjmp    holding

addkey:
        cbr     addsub,$01
        rjmp    arith

subkey:
        sbr     addsub,$01

arith:
        swap    addsub
        sbrc    addsub,0
        rjmp    subf
        rcall   BCDadd
        out     portb,C
        rcall   overflow
        clr     B
        rjmp    holding

subf:
        rcall   BCDsub
        out     portb,C
        rcall   overflow
        clr     B
        rjmp    holding

;*************************************************
; Key press released ?

holding:
        rcall   sdelay
        in      key,pind
        cbr     key,$F0
        ldi     temp,$0F
        cpse    key,temp
        rjmp    holding
        rjmp    rescan

;*************************************************
; overflow ?

overflow:
        sbrs    b,0
        ret
        cli
        sbi     ddrd,7
        cbi     portd,7
        rcall   delay
        sbi     portd,7
        cbi     ddrd,7
        sei
        ret

;*************************************************
; Short Delay

sdelay:
        clr     temp
s10:    dec     temp
        brne    s10
        ret

;*************************************************
; Load Table

ldtable:
        ldi     ZP,table
        ldi     temp,1
        st      Z+,temp
        ldi     temp,2
        st      Z+,temp
        ldi     temp,3
        st      Z+,temp
        ldi     temp,4
        st      Z+,temp
        ldi     temp,5
        st      Z+,temp
        ldi     temp,6
        st      Z+,temp
        ldi     temp,7
        st      Z+,temp
        ldi     temp,8
        st      Z+,temp
        ldi     temp,9
        st      Z+,temp
        ldi     temp,$B
        st      Z+,temp
        ldi     temp,0
        st      Z+,temp
        ldi     temp,$A
        st      Z+,temp
        ret

;*******************************************    
delay:
del:    ldi     ZP,count
        ld      temp,Z
        dec     temp
        st      Z,temp
        brne    del
        ldi     ZP,count+1
        ld      temp,Z
        dec     temp
        st      Z,temp
        brne    del
        dec     counter
        brne    del
        ldi     counter,3
        ret

;***** Subroutine Register Variables

.def    BCD1    =r19            ;BCD input value #1
.def    BCD2    =r18            ;BCD input value #2
.def    tmpadd  =r16            ;temporary register

;***** Code

BCDadd:
        ldi     tmpadd,6        ;value to be added later
        add     BCD1,BCD2       ;add the numbers binary
        clr     BCD2            ;clear BCD carry
        brcc    add_0           ;if carry not clear
        ldi     BCD2,1          ;    set BCD carry
add_0:  brhs    add_1           ;if half carry not set
        add     BCD1,tmpadd     ;    add 6 to LSD
        brhs    add_2           ;    if half carry not set (LSD <= 9)
        subi    BCD1,6          ;        restore value
        rjmp    add_2           ;else
add_1:  add     BCD1,tmpadd     ;    add 6 to LSD
add_2:  swap    tmpadd
        add     BCD1,tmpadd     ;add 6 to MSD
        brcs    add_4           ;if carry not set (MSD <= 9)
        sbrs    BCD2,0          ;    if previous carry not set
        subi    BCD1,$60        ;       restore value 
add_3:  ret                     ;else
add_4:  ldi     BCD2,1          ;    set BCD carry
        ret


;***** Subroutine Register Variables

.def    BCDa    =r19            ;BCD input value #1
.def    BCDb    =r18            ;BCD input value #2

;***** Code

BCDsub:
        sub     BCDa,BCDb       ;subtract the numbers binary
        clr     BCDb
        brcc    sub_0           ;if carry not clear
        ldi     BCDb,1          ;    store carry in BCDB1, bit 0
sub_0:  brhc    sub_1           ;if half carry not clear
        subi    BCDa,$06        ;    LSD = LSD - 6
sub_1:  sbrs    BCDb,0          ;if previous carry not set
        ret                     ;    return
        subi    BCDa,$60        ;subtract 6 from MSD
        ldi     BCDb,1          ;set underflow carry
        brcc    sub_2           ;if carry not clear
        ldi     BCDb,1          ;    clear underflow carry      
sub_2:  ret                     



        
.dseg
table:  .byte   12
count:  .byte   2

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.