Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;Patrick Huie
- ;11/9/2019
- ;Assignment #3 - Calculator
- base !10
- pagewidth 127
- ;
- MAX_DIGITS EQU $14
- org $90
- ;
- ;Variables
- ;
- in_1: rmb max_digits
- in_2: rmb max_digits
- sum: rmb max_digits
- temp: rmb 1 ;parameter for nibble_shift, instruction, and find_msd
- display_pointer: rmb 1
- digit_pointer: rmb 1
- msd: rmb 1 ;address of most significant digit in sum that is not 0
- org $fffe
- fdb start
- include "ioJK3.asm"
- ;
- ;This program functions as a calculator by inputting
- ;max_digits number of digits into two variables in_1
- ;and in_2 and then outputs the sum to another variable
- ;sum on the 7 segment display.
- ;
- start: mov #%00010000,ptb
- mov #%00111110,ddrb
- bset 0,config1
- rsp
- clra
- jsr digit
- ldx #in_1
- bsr var_init
- bra collect_input_1
- var_init: clr {max_digits + max_digits},x ;Clear sum
- clr max_digits,x ;Clear in_2
- clr ,x ;Clear in_1
- incx ;Move to next
- ;byte for these
- ;3 values
- cpx #{in_1 + max_digits}
- bcs var_init
- clr temp ;Clear temp
- var_end: rts
- ;This portion of the program takes in the input
- ;from the keyboard in the BCD form -- 1 digit per nibble
- ;for in_1, in_2, and sum
- ;
- ;Input for first number
- collect_input_1: mov #in_1,display_pointer ;Pass the address of in_1 to eight_digits
- lsl display_pointer
- bclr 0,display_pointer
- jsr eight_digits ;to display it to the 7-segment display
- jsr new_key
- mov #in_1,temp ;Pass in_1 as a parameter
- bsr instruction ;If not 0-9 process the proper function
- ;of the inputted key
- psha
- ldhx #{in_1 + max_digits - 2}
- mov #{in_1 - 1},temp ;Pass in_1 as a parameter
- ;by setting temp to its value
- bsr nibble_shift
- pula
- ora in_1
- sta in_1
- bra collect_input_1
- ;Input for second number
- collect_input_2: mov #in_2,display_pointer ;Pass the address of in_2 to eight_digits
- lsl display_pointer
- bclr 0,display_pointer
- jsr eight_digits ;to display it to the 7-segment display
- jsr new_key
- mov #in_2,temp ;Pass in_2 as a parameter
- bsr instruction ;If not 0-9 process the proper function
- ;of the inputted key
- psha
- ldhx #{in_2 + max_digits - 2}
- mov #{in_2 - 1},temp ;Pass in_2 as a parameter
- ;by setting temp to its value
- bsr nibble_shift
- pula
- ora in_2
- sta in_2
- bra collect_input_2
- ;Shifts each digit up a nibble
- nibble_shift: lda 1,x
- nsa ;Swap nibbles and set lower nibble
- and #$F0 ;to 0
- sta 1,x
- cpx temp ;If at the LSD then do not or with
- beq nibble_end ;upper nibble of next lowest byte
- lda ,x ;or the lower nibble with the
- nsa ;upper nibble of the next lowest byte
- and #$0F
- ora 1,x
- sta 1,x
- decx
- bra nibble_shift
- nibble_end: rts
- ;If the input entered is not a number this subroutine performs the proper
- ;function depending on the value. Takes temp as param
- instruction:
- clear: cmp #$C ;If "C" pressed clear all vars
- bne add_key ;by calling var_init
- ldx #in_1
- jsr var_init
- rsp
- bra collect_input_1
- add_key: cmp #$A
- bcs instr_end
- rsp
- psha
- lda temp
- cmp #in_2
- beq add_key_2
- pula
- add_key_1: cmp #$A
- bhi collect_input_1
- beq collect_input_2 ;If "A" pressed then branch to input
- ;second number -- end of input
- add_key_2: pula
- cmp #$B
- bhi collect_input_2
- beq addition ;If "A" pressed then branch to perform
- ;calculator operation -- end of input
- instr_end: rts
- ;Different calculator operations -- for now just add
- ;Later -- possibly -- add functionality for sub, mul,
- ;and div
- addition: mov #sum,display_pointer ;After the operation is applied
- lsl display_pointer ;display_pointer will have to
- bclr 0,display_pointer ;point to sum -- display_pointer
- ;is not needed for the rest
- ;of operation
- clc ;Clear carry for first digit
- ldx #in_1
- add_loop: lda ,x
- adc max_digits,x ;Add the first 2 numbers together
- ;which are spaced apart by max_digits
- daa
- sta {max_digits + max_digits},x ;Sum is spaced 2*max_digits
- ;away from in_1
- incx
- cbeqx #{in_1 + max_digits},display
- bra add_loop
- ;Display the passed parameter pointed to by the
- ;display_pointer to the 7-segment display
- display: ldhx #{sum + max_digits}
- mov #sum,temp
- bsr find_msd
- scroll_display: bsr eight_digits
- invalid_key: jsr new_key
- disp_right: cmp #$F ;If "F" pressed scroll right
- bne disp_left
- psha
- lda display_pointer
- cmp #{msd-7} ;If the display_pointer is higher
- bcc invalid_key ;than msd-7 wait for another input
- inc display_pointer ;otherwise scroll right and display
- ;with eight_digits
- pula
- bra scroll_display
- disp_left: cmp #$E ;If "E" pressed scroll left
- bne clear_2
- psha
- lda display_pointer
- cmp #sum ;If the display_pointer is equal
- beq invalid_key ;to #sum wait for another input
- dec display_pointer ;otherwise scroll left and display
- ;with eight_digits
- pula
- bra scroll_display
- clear_2: cmp #$C ;If "C" pressed clear all vars
- bne invalid_key
- ldx #in_1
- jsr var_init
- jmp collect_input_1
- ;This subroutine finds the MSD of the param (temp).
- find_msd: decx ;Move to next byte
- cpx temp ;If at last byte
- beq found_msd ;then set msd to #sum
- lda ,x
- and #$F0 ;Check if upper nibble 0
- sec ;Set C to indicate upper nibble
- tsta
- bne found_msd
- lda ,x
- and #$0F ;Check if lower nibble 0
- clc ;Clear C to indicate lower nibble
- tsta
- beq find_msd ;If 0's in both nibbles
- ;move to next byte
- found_msd: stx msd ;Store the address of first
- rol msd ;non-zero value with bit 0
- rts ;indicating upper or lower nibble
- ;Takes the parameter pointed to by the display_pointer
- ;and puts it into digits0-7
- eight_digits: mov #digit0,digit_pointer ;Start digit_pointer at digit0
- eight_loop: lda display_pointer ;Load LSD
- sec
- rora ;Convert to actual mem address
- tax ;and load into h:x register
- clrh
- lda ,x ;to get data at display_pointer
- bcc isolate_nibble ;If accessing lower nibble don't nsa
- nsa
- isolate_nibble: and #$0F
- jsr ascii_7seg ;Convert to ASCII
- ldx digit_pointer ;Load the digit pointer
- sta ,x ;and store ASCII value
- ;at where x points to
- inc display_pointer
- inc digit_pointer
- lda digit_pointer
- cmp #{digit7 + 1} ;Check to see if all eight
- bne eight_loop ;digits have been filled
- rts
- ;Old scroll_display:
- ;lda display_pointer
- ;psha
- ;sec
- ;rora
- ;tax
- ;clrh
- ;pula
- ;sta display_pointer
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement