Home | History | Annotate | Line # | Download | only in libdos
makedoscalls.awk revision 1.1
      1 #! /usr/bin/awk -f
      2 #
      3 #	create DOS call interface from dos.h
      4 #
      5 #	written by Yasha (ITOH Yasufumi)
      6 #	public domain
      7 #
      8 #	$NetBSD: makedoscalls.awk,v 1.1 1998/09/01 19:53:26 itohy Exp $
      9 
     10 BEGIN {
     11 	errno_nomem = 8		# errno for "Cannot allocate memory"
     12 	argsiz["l"] = 4; argsiz["w"] = 2
     13 	argsiz["lb31"] = 4; argsiz["wb8"] = 2; argsiz["wb15"] = 2
     14 }
     15 
     16 $1 == "/*" && $2 ~ /^ff[0-9a-f][0-9a-f]$/ {
     17 	funcnam=""
     18 	dosno=$2
     19 	narg=0
     20 	ncarg=0		# number of 32bit C function argument
     21 	argbyte=0
     22 	opt_e=0
     23 	e_strict=0
     24 	e_alloc=0
     25 	e_proc=0
     26 	svreg=0
     27 	noret=0
     28 	super=0
     29 	super_jsr=0
     30 	alias=""
     31 	for (i = 3; i <= NF && $i != "*/" && $i != ";"; i++) {
     32 		arg[narg] = $i
     33 		narg++
     34 		if (argsiz[$i])
     35 			ncarg++
     36 	}
     37 	if ($i == ";") {
     38 		# process opts
     39 		for (i++; i <= NF && $i != "*/"; i++) {
     40 			if ($i == "e")
     41 				opt_e = 1
     42 			else if ($i == "estrct") {
     43 				opt_e = 1
     44 				e_strict = 1
     45 			} else if ($i == "ep") {
     46 				opt_e = 1
     47 				e_proc = 1
     48 			} else if ($i == "ealloc") {
     49 				opt_e = 1
     50 				e_alloc = 1
     51 			} else if ($i == "sv")
     52 				svreg = 1
     53 			else if ($i == "noret")
     54 				noret = 1
     55 			else if ($i == "alias") {
     56 				i++
     57 				alias = $i
     58 			} else if ($i == "super")
     59 				super = 1
     60 			else if ($i == "super_jsr")
     61 				super_jsr = 1
     62 			else {
     63 				print FILENAME ":" NR ": unknown opt", $i
     64 				exit(1)
     65 			}
     66 		}
     67 	}
     68 	if ($i != "*/") {
     69 		print FILENAME ":" NR ": malformed input line:" $0
     70 		exit(1)
     71 	}
     72 	# find out func name
     73 	printf "|"
     74 	for (i++; i <= NF; i++) {
     75 		printf " %s", $i
     76 		if ($i ~ /^\**DOS_[A-Z0-9_]*$/) {
     77 			funcnam = $i
     78 			while (funcnam ~ /^\*/)
     79 				funcnam = substr(funcnam, 2, length(funcnam) -1)
     80 		}
     81 	}
     82 	print ""
     83 	if (!funcnam) {
     84 		print FILENAME ":" NR ": can't find function name"
     85 		exit(1)
     86 	}
     87 
     88 	# output assembly code
     89 	print "\t.text\n\t.even"
     90 	print "\t.globl\t_" funcnam
     91 	if (alias) {
     92 		print "\t.globl\t_" alias
     93 	}
     94 	print "_" funcnam ":"
     95 	if (alias)	print "_" alias ":"
     96 
     97 	if (svreg)	print "\tmoveml\td2-d7/a2-a6,sp@-"
     98 
     99 	# PUSH ARGS
    100 	argoff = ncarg * 4
    101 	if (svreg)
    102 		argoff += 4 * 11
    103 	for (i = narg - 1; i >= 0; i--) {
    104 		a = arg[i]
    105 		asz = argsiz[a]
    106 		if (asz) {
    107 			if (a == "l") {
    108 				# optimize with movem
    109 				if (arg[i-1] == "l" && arg[i-2] == "l") {
    110 					if (arg[i-3] == "l") {
    111 						print "\tmoveml\tsp@(" argoff - 12 "),d0-d1/a0-a1"
    112 						print "\tmoveml\td0-d1/a0-a1,sp@-"
    113 						asz = 16
    114 						i -= 3
    115 					} else if (arg[i-3] == "w") {
    116 						print "\tmoveml\tsp@(" argoff - 12 "),d0-d1/a0-a1"
    117 						print "\tmoveml\td1/a0-a1,sp@-"
    118 						print "\tmovew\td0,sp@-"
    119 						asz = 14
    120 						i -= 3
    121 					} else {
    122 						print "\tmoveml\tsp@(" argoff - 8 "),d0-d1/a0"
    123 						print "\tmoveml\td0-d1/a0,sp@-"
    124 						asz = 12
    125 						i -= 2
    126 					}
    127 				} else {
    128 					print "\tmovel\tsp@(" argoff "),sp@-"
    129 				}
    130 			} else if (a == "w")
    131 				print "\tmovew\tsp@(" argoff + 2 "),sp@-"
    132 			else if (a == "lb31") {
    133 				print "\tmovel\tsp@(" argoff "),d0"
    134 				print "\tbset\t#31,d0"
    135 				print "\tmovel\td0,sp@-"
    136 			} else if (a == "wb8") {
    137 				print "\tmovew\tsp@(" argoff + 2 "),d0"
    138 				print "\torw\t#0x100,d0"
    139 				print "\tmovew\td0,sp@-"
    140 			} else if (a == "wb15") {
    141 				print "\tmovew\tsp@(" argoff + 2 "),d0"
    142 				print "\torw\t#0x8000,d0"
    143 				print "\tmovew\td0,sp@-"
    144 			} else {
    145 				print "??? unknown type"
    146 				exit(1)
    147 			}
    148 
    149 			if (asz == 2)
    150 				argoff -= 2
    151 		} else if (a ~ /^[0-9][0-9]*\.w$/) {
    152 			asz = 2
    153 			argoff += 2
    154 			val = substr(a, 1, length(a) - 2)
    155 			if (val == 0)
    156 				print "\tclrw\tsp@-"
    157 			else
    158 				print "\tmovew\t#" val ",sp@-"
    159 		} else if (a ~ /^[0-9][0-9]*\.l$/) {
    160 			asz = 4;
    161 			argoff += 4
    162 			val = substr(a, 1, length(a) - 2)
    163 			if (val == 0)
    164 				print "\tclrl\tsp@-"
    165 			else if (val <= 32767)
    166 				print "\tpea\t" val ":w"
    167 			else
    168 				print "\tmovel\t#" val ",sp@-"
    169 		} else if (a == "drvctrl" && narg == 1) {
    170 			# only for DOS_DRVCTRL
    171 			asz = 2
    172 			print "\tmoveb\tsp@(7),d0"
    173 			print "\tlslw\t#8,d0"
    174 			print "\tmoveb\tsp@(11),d0"
    175 			print "\tmovew\td0,sp@-"
    176 		} else if (a == "super" && narg == 1) {
    177 			# only for DOS_SUPER
    178 			print "\tmoveal\tsp@+,a1"
    179 		} else {
    180 			print FILENAME ":" NR ": unknown arg type:", a
    181 			exit(1)
    182 		}
    183 		argbyte += asz
    184 	}
    185 
    186 	if (super_jsr) {
    187 		print "\tmoveal\tsp@(" argoff + 8 "),a0	| inregs"
    188 		print "\tmoveml\ta0@,d0-d7/a0-a6"
    189 	}
    190 
    191 	if (dosno ~ /^ff[8a]./) {
    192 		if (dosno ~ /^..8./)
    193 			v2dosno = "ff5" substr(dosno, 4, 1)
    194 		else
    195 			v2dosno = "ff7" substr(dosno, 4, 1)
    196 		print "\tcmpiw	#0x200+14,__vernum+2	| 2.14"
    197 #		print "\tbcss\tLv2doscall"
    198 		print "\tbcss\t2f"
    199 		print "\t.word\t0x" dosno
    200 		if (!noret)
    201 #			print "\tbras\tLedoscall"
    202 			print "\tbras\t3f"
    203 #		print "Lv2doscall:"
    204 		print "2:"
    205 		print "\t.word\t0x" v2dosno
    206 		if (!noret)
    207 #			print "Ledoscall:"
    208 			print "3:"
    209 	} else {
    210 		print "\t.word\t0x" dosno
    211 	}
    212 
    213 	# no postprocess needed for dead calls
    214 	if (noret)
    215 		next
    216 
    217 	if (super_jsr) {
    218 		print "\tmovel\ta6,sp@"
    219 		print "\tmoveal\tsp@(" argoff + 12 "),a6	| outregs"
    220 		print "\tmovel\tsp@+,a6@(" 4 * 14 ")"
    221 		print "\tmoveml\td0-d7/a0-a5,a6@"
    222 	} else if (argbyte > 0) {
    223 		# POP ARGS
    224 		if (argbyte <= 8)
    225 			print "\taddql\t#" argbyte ",sp"
    226 		else
    227 			print "\tlea\tsp@(" argbyte "),sp"
    228 	}
    229 
    230 	if (svreg)	print "\tmoveml\tsp@+,d2-d7/a2-a6"
    231 	if (opt_e) {
    232 		if (e_strict) {
    233 			print "\tcmpil\t#0xffffff00,d0"
    234 			print "\tbcc\tDOS_CERROR"
    235 		} else  {
    236 			print "\ttstl\td0"
    237 			if (super) {
    238 #				print "\tbpls\tLnoerr"
    239 				print "\tbpls\t5f"
    240 				print "\tnegl\td0"
    241 				print "\tmovel\td0,_dos_errno"
    242 				print "\tnegl\td0"
    243 #				print "Lnoerr:"
    244 				print "5:"
    245 			} else if (e_alloc) {
    246 #				print "\tbpls\tLnoerr"
    247 				print "\tbpls\t5f"
    248 				print "\tmovel\t#" errno_nomem ",_dos_errno"
    249 #				print "Lnoerr:"
    250 				print "5:"
    251 			} else if (e_proc) {
    252 				print "\tbmi\tDOS_PRCERROR"
    253 			} else
    254 				print "\tbmi\tDOS_CERROR"
    255 		}
    256 	}
    257 	if (super)
    258 		print "\tjmp\ta1@"
    259 	else
    260 		print "\trts"
    261 }
    262