Overview
This is a small program I wrote to add two 32-digit hex numbers together. It only runs on proprietary machines built by Indiana University, though I had some designs to convert it to a TI-89/92+ program so it might be of more use.
Features
- Adds two 32-digit hex numbers together.
- Source code available.
- Supports editing facilities (backspace).
- Source is fully commented.
License
All Rights Reserved.
Color Coded Source
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; add32.s ; ; Copyright © 2001 John David Ratliff ; All Rights Reserved ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; begin code section here SECTION code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; get character from user with trap #15 (no echo) ; input - none ; output - d0.b - character pressed by the user getch: moveq.l #2,d1 ; set trap 15 for single character input trap #15 ; call trap #15 rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; output the character in d0 to the screen using trap #15 ; input: d0.b - character to print ; output: none putch: moveq.l #1,d1 ; set trap 15 for single character output trap #15 ; call trap #15 rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; output a newline to the terminal ; input - none ; output - none newLine: move.b #'\r',d0 ; print the carriage return bsr putch ; print the character move.b #'\n',d0 ; print the newline bsr putch ; print the character rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; convert (uppercase) hex char to hex digit if char is hex digit ; input: d0.b - character to test and convert ; output: d2.b - 1 if char is hex, 0 otherwise ; d0.b - converted hex digit (if d2.b == 1) isHex: cmp.b #'A',d0 ; check for uppercase hex digits bge isHex_upper ; we found one. branch cmp.b #'9',d0 ; check for the characters between '9' and 'A' bgt isHex_notHex ; if we found one, it's not hex sub.b #'0',d0 ; we found a 0-9, subtract '0' from it isHex_finalTest: bclr.b #7,d0 ; clear the sign bit cmp.b #0xF,d0 ; test for numbers > 15 bgt isHex_notHex ; if test == true, then it's not hex moveq.l #1,d2 ; set return value to true rts ; return from subroutine isHex_upper: sub.b #'A'-10,d0 ; adjust value to offset of 10 bra isHex_finalTest ; goto the final test isHex_notHex: clr.b d2 ; set return value to false rts ; goto end of subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; convert hex digit to hex character ; input: d2.b = hex digit ; output d2.b = hex character toHex: cmp.b #9,d2 ; is our number > 9? bgt toHex_upper ; if so, then we need to adjust. goto hex16 add.b #'0',d2 ; add '0' ASCII value for small numbers rts ; return from subroutine toHex_upper: add.b #'A'-10,d2 ; add 'A' ASCII valid for numbers > 10 rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; converts a lowercase character to a uppercase character ; input: d0.b - the lowercase character ; output: d0.b - the uppercase character toUpper: cmp.b #'a',d0 ; is our value less than a lowercase letter? blt toUpper_eos ; if yes, then goto end of subroutine cmp.b #'z',d0 ; is our value higher than a lowercase letter? bgt toUpper_eos ; if yes, then goto end of subroutine sub.b #'a'-'A',d0 ; we have lowercase. Adjust value to uppercase toUpper_eos: rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; prints a string ; input: a0.l - string to display, 0 terminated ; output: none print: move.l a0,-(sp) ; save a0 on the stack P_loop: move.b (a0)+,d0 ; get the character into d0 beq eosPrint ; if we found the terminator, goto eos bsr putch ; otherwise, print the character bra P_loop ; loop eosPrint: move.l (sp)+,a0 ; restore a0 from the stack rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; prints a string followed by a new line ; input: a0.l - string to display, 0 terminated ; output: none println: bsr print ; print the string bsr newLine ; print the new line rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; inputs a numeric (hex) string ; input: d4.w - length of string to input - 1 ; a0.l - string to store the input at ; output: a1.l - string variable inputNumberString: move.l a1,-(sp) ; save the input string on the stack INS_loop: bsr getch ; get a character bsr toUpper ; convert to uppercase move.b d0,d3 ; save the character in d3 bsr isHex ; test if the character is a valid hex digit beq INS_loop ; if not hex, loop move.b d3,(a1)+ ; add the digit to the string move.b d3,d0 ; copy the character back into d0 bsr putch ; display the character dbra.w d4,INS_loop ; loop until finished bsr newLine ; goto the next line INS_wait: bsr getch ; get character cmp.b #'\r',d0 ; was it enter? bne INS_wait ; wait for ENTER move.l (sp)+,a1 ; restore string pointer from the stack rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; takes a string of 8 hex characters and converts it to a number ; input: a0.l - string of hex digits (pointing to the end of the string) ; output: d1.l - number converted from the hex string in a0 get8DigitNumber: clr.l d1 ; clear value moveq.l #7,d3 ; set counter to 8 G8DN_loop: move.b -(a0),d0 ; get character bsr isHex ; convert to digit add.b d0,d1 ; add the digit to the whole number ror.l #4,d1 ; shift left to get the correct place dbra.w d3,G8DN_loop ; loop until we get 8 digits rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; appends a number backwards onto a string ; input: d0.l = number to append ; a3.l = string to append (pointing at the end) ; output: a3.l = string with number (d0.l) appended appendString: moveq.l #7,d1 ; set the counter to 8 AS_loop: move.b d0,d2 ; move the byte from d0 into d2 and.b #0xF,d2 ; make out the high digit bsr toHex ; convert to hex character move.b d2,-(a3) ; append to string (backwards) ror.l #4,d0 ; shift digit locations dbra.w d1,AS_loop ; loop rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; concatenates two strings ; input: d0.w - length of the input string ; a1.l - address of input string ; a3.l - address of output string (at starting position of concatenation) ; output: a3.l - string with a0.l string appended concatenate: move.b (a1)+,(a3)+ ; concatenate input char to output char dbra.w d0,concatenate ; loop until all of string is appended rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; append a character to the result string ; input: a3.l - the result string ; d0.b - the character to append ; d1.w - how many of d0.b to append to the string a3.l ; output: a3.l - the string with the appended characters appendChar: move.b d0,(a3)+ ; append char to result string dbra.w d1,appendChar ; loop until number of chars are appended rts ; return from subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; program start START: lea clear,a0 ; load the clear screen string into a0 bsr print ; clear the screen S_begin: lea result,a3 ; load the result string move.b #' ',d0 ; set character to space moveq.l #1,d1 ; set counter to 2 bsr appendChar ; append space to result string lea prompt,a0 ; load the prompt bsr print ; print the string move.w #31,d4 ; set counter to 32 lea n1,a1 ; load number string into a1 bsr inputNumberString ; input the number move.w #31,d0 ; set length of input string to 32 bsr concatenate ; concatenate the string to the result string move.b #'\r',(a3)+ ; append carriage return move.b #'\n',(a3)+ ; append new line move.b #'+',(a3)+ ; append the plus sign move.b #' ',(a3)+ ; append a space bsr print ; print the input number string adda.l #37,a0 ; move to the next prompt move.w #31,d4 ; set counter to 32 lea n2,a1 ; load number string into a1 bsr inputNumberString ; input the number move.w #31,d0 ; set length of input string to 32 bsr concatenate ; concatenate the string to the result string move.b #'\r',(a3)+ ; append the carriage return move.b #'\n',(a3)+ ; append new line move.b #33,d1 ; set counter to 34 move.b #'-',d0 ; set character to dash bsr appendChar ; append result string move.b #'\r',(a3)+ ; append the carriage return move.b #'\n',(a3)+ ; append new line moveq.l #1,d1 ; set counter to 2 move.b #' ',d0 ; set character to space bsr appendChar ; append spaces to result string bsr print ; print the next prompt adda.l #37,a0 ; move to the next string offset S_waitPlus: bsr getch ; get a character cmp.b #'+',d0 ; did we get a plus sign? bne S_waitPlus ; if not, then loop until we do bsr putch ; print the + sign moveq.l #1,d2 ; set counter to 2 S_waitEnter: bsr getch ; get a character? cmp.b #'\r',d0 ; did we get ENTER? bne S_waitEnter ; if not, loop dbra.w d2,S_waitEnter ; wait for two enters pending the plus move.b d0,(a3)+ ; append the plus sign move.b #' ',(a3)+ ; append a space move.b #' ',(a3)+ ; append space in case sum uses only 32 digits bsr newLine ; skip next 2 lines bsr newLine ; makes output look better bsr println ; print the result message lea n1+32,a1 ; load first number into a1 lea n2+32,a2 ; load second number into a2 lea result+143,a3 ; load result string into a3 move.b #0,-(a3) ; append the terminator move.w CCR,d6 ; save the CCR for future use moveq.l #3,d7 ; set counter to 4 S_loop: move.l a1,a0 ; function requires address be in a0 bsr get8DigitNumber ; get the number segment move.l a0,a1 ; save the string address move.l d1,d5 ; save the result of the conversion move.l a2,a0 ; function requires address be in a0 bsr get8DigitNumber ; get the number segment move.l a0,a2 ; save the string address move.w d6,CCR ; restore the condition codes addx.l d1,d5 ; add the numbers together move.w CCR,d6 ; save the condition codes in d6 move.l d5,d0 ; function requires number be in d0 register bsr appendString ; append the number dbra.w d7,S_loop ; loop over the 4 8-byte segments btst.b #0,d6 ; test for final carry bit (CCR saved in d6) bne S_addCarry ; if we have a carry, add it move.b #' ',-(a3) ; otherwise, append the carry S_result: lea result,a0 ; reload the result string at the beginning bsr println ; print the result lea exit,a0 ; load the exit message bsr println ; print the exit message bsr getch ; get a character bsr toUpper ; convert to uppercase cmp.b #'Q',d0 ; did the user press 'Q'? bne S_begin ; if we didn't press 'Quit', then loop clr.b d1 ; set d1=0 (exit code) trap #15 ; call trap #15 (exit trap) S_addCarry: move.b #'1',-(a3) ; put the carry in front bra S_result ; goto result ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; begin data section here SECTION data ; standard messages prompt: dc.b "Please Enter a 32-digit Hex Number: ",0 dc.b " Please Enter the + Sign: ",0 dc.b "The Result Is:\r\n",0 exit: dc.b "\r\nPress 'Q' to exit, or any other key to start over.\r\n",0 ; number strings n1: ds.b 32 n2: ds.b 32 ; result string result: ds.b 143 ; clear screen string clear: dc.b "\x1b[2J\x1b[1;1f",0 ; clear screen stringDownload
add32.zip (4 KB)