#!/bin/sh
#
# mitToMot - convert mit format assembler to motorola format
#
# modification history
# --------------------
# 01e,15mar88,dnw  changed to output comments immediately without further
#		     transformations
#		   changed to delete spaces and tabs anywhere in operand field
#		     otherwise Mot assemblers can't handle operands like "x + 8"
# 01d,13feb88,dnw  changed conversion of "a0@(<n>) -> <n>(a0)" to use [^\/,]*
#		     instead of [^ 	,]* to indentify the original <n>
#		     because the latter got fooled by #define constants that
#		     had tabs in them (i.e. STATEFRAME in fppALib.s).
#		   changed to delete spaces and tabs after a '#' because
#		     Intermetrics assembler chokes on them.
# 01c,05nov87,jlf  documentation
# 01b,18mar87,dnw  added conversion of condition code register from cc to ccr.
#
# SYNOPSIS: mitToMot [files...]
#
# DESCRIPTION
# This script reads the specified files (or standard input if no files
# are specified) as MIT format assembly language and writes to standard output
# the corresponding Motorola format assembly language.
#
# The following transformations are made:
#
#    Op-code:
#	<op>[bwl] -> <op>.[bwl]
#	dbra      -> dbf
#
#    Operand:
#	0x<n>    -> $<n>
#	a0@(<n>) -> <n>(a0)
#	a0@+     -> (a0)+
#	a0@-     -> -(a0)
#	a0@      -> (a0)
#	cc       -> ccr
#	all spaces are removed from operand field
#
#    Assembler directives:
#	.byte    -> dc.b
#	.word    -> dc.w
#	.int     -> dc.l
#	.long    -> dc.l
#	.asciz   -> dc.b
#	.text    -> section 9
#	.bss     -> section 13
#	.data    -> section 14
#	.align   ->
#	.even    ->
#
#*/

cat <<'EOF' >mitToMot_sed.tmp

# turn comments from "#" to "*", output them and delete them from current line

/^[ 	]*\#/{
s/\#/*/
P
D
}

# put labels on their own line

/^[a-zA-Z0-9_\$\.]*[ 	]*:.*[^ 	].*/s/:/:\
/
# output labels and delete them from current line
/^[a-zA-Z0-9_\$\.]*[ 	]*:/{
P
D
}

# transform operation field:
#   <op>[bwl] -> <op>.[bwl]
#   dbra      -> dbf

s/^[ 	]*\([a-zA-Z][a-zA-Z][a-zA-Z]*\)\([bBwWlL]\)[ 	]/	\1.\2	/
s/^[ 	]*dbra/	dbf/

# transform operand field:
#   0x<n>    -> $<n>
#   a0@(<n>) -> <n>(a0)
#   a0@+     -> (a0)+
#   a0@-     -> -(a0)
#   a0@      -> (a0)

s/\([^0-9a-zA-Z]\)0x\([0-9a-zA-Z][0-9a-zA-Z]*\)/\1$\2/g
s/\([aAdDsS][0-7pP]\)@(\([^\/,]*\))/\2(\1)/g
s/\([aAdDsS][0-7pP]\)@+/(\1)+/g
s/\([aAdDsS][0-7pP]\)@-/-(\1)/g
s/\([aAdDsS][0-7pP]\)@/(\1)/g

# operand field must not contain any spaces

s/\([#0-9+-,@\$()]\)[ 	]*/\1/g
s/[ 	]*\([+-,]\)/\1/g

# change condition code register operand:
#   cc -> ccr

s/,cc\([ 	]\)/,ccr\1/

# transform assembler directives

s/^[ 	]*\.byte/	dc.b/
s/^[ 	]*\.word/	dc.w/
s/^[ 	]*\.int/	dc.l/
s/^[ 	]*\.long/	dc.l/
s/^[ 	]*\.asciz[ 	]*"\(.*\)"/	dc.b	'\1',0/
s/^[ 	]*\.text/	section	9/
s/^[ 	]*\.bss/	section	13/
s/^[ 	]*\.data/	section	14/

/^[ 	]*\.align/d
/^[ 	]*\.even/d
EOF

cat <<'EOF' >mitToMot_awk.tmp

# turn ".globl" to "xdef" or "xref"

/\.globl/	{
		# save global reference
		g[$2] = $2
		next
		}

/^[ 	]*[a-zA-Z0-9_\.\$]+[ 	]*:/	{

		# got a label; see if it should be external

		ic = index ($1, ":")
		if (ic == 0)
		    lbl = $1
		else
		    lbl = substr ($1, 1, ic - 1)
		
		if (g[lbl])
		    {
		    # got a label that needs to be an "external definition";

		    print "	xdef	" lbl	# add "xdef" line before label
		    g[lbl] = ""			# remove from ".globl" list
		    }
		}

		{ print }	# pass all lines through untouched

END		{
		# output all remaining ".globl" that were not defined locally,
		# as "external reference"

		for (lbl in g)
		    if (g[lbl] != "")
			print "	xref	" lbl

		# add 'end' to end of file

		print "	end"
		}
EOF

sed -f mitToMot_sed.tmp $* | awk -f mitToMot_awk.tmp

rm mitToMot_sed.tmp mitToMot_awk.tmp
