John David Ratliff's Online Resume Site

[ Home | Résumé | Portfolio ]

add32.s

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

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 string

Download

add32.zip (4 KB)

 


E-Mail Me


Copyright © 2004-2012 John David Ratliff
All Rights Reserved

Get Firefox!    Valid HTML 4.01!    Made with jEdit