1238106Sdes/*	$NetBSD: gsp_out.c,v 1.9 2006/08/26 18:15:37 christos Exp $	*/
2238106Sdes/*
3238106Sdes * GSP assembler - binary & listing output
4238106Sdes *
5238106Sdes * Copyright (c) 1993 Paul Mackerras.
6238106Sdes * All rights reserved.
7238106Sdes *
8238106Sdes * Redistribution and use in source and binary forms, with or without
9238106Sdes * modification, are permitted provided that the following conditions
10238106Sdes * are met:
11238106Sdes * 1. Redistributions of source code must retain the above copyright
12238106Sdes *    notice, this list of conditions and the following disclaimer.
13238106Sdes * 2. Redistributions in binary form must reproduce the above copyright
14238106Sdes *    notice, this list of conditions and the following disclaimer in the
15238106Sdes *    documentation and/or other materials provided with the distribution.
16238106Sdes * 3. All advertising materials mentioning features or use of this software
17238106Sdes *    must display the following acknowledgement:
18238106Sdes *      This product includes software developed by Paul Mackerras.
19238106Sdes * 4. The name of the author may not be used to endorse or promote products
20238106Sdes *    derived from this software without specific prior written permission
21238106Sdes *
22238106Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23238106Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24269257Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25269257Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26269257Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27269257Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28269257Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29269257Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30269257Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31269257Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32269257Sdes */
33269257Sdes
34238106Sdes#include <sys/cdefs.h>
35238106Sdes#ifndef lint
36238106Sdes__RCSID("$NetBSD: gsp_out.c,v 1.9 2006/08/26 18:15:37 christos Exp $");
37238106Sdes#endif
38238106Sdes
39238106Sdes#include <stdio.h>
40238106Sdes#include <stdlib.h>
41238106Sdes#include <string.h>
42238106Sdes#include <util.h>
43238106Sdes#include "gsp_ass.h"
44238106Sdes
45238106Sdesu_int16_t codes[5];
46238106Sdesunsigned ncode;
47238106Sdesunsigned code_idx;
48238106Sdesshort show_pc;
49238106Sdesshort show_val;
50238106Sdesint32_t val_to_show;
51238106Sdesextern unsigned line_pc;
52238106Sdes
53238106Sdesunsigned obj_addr = 0;
54238106Sdes
55238106Sdesextern FILE *objfile, *listfile;
56238106Sdesextern char line[];
57238106Sdes
58249141Sdesextern char *c_name;
59269257Sdesu_int16_t c_buf[4096];
60269257Sdesu_int32_t c_bufptr, c_binads;
61269257Sdes
62269257Sdesvoid c_checkbuf(void);
63269257Sdesvoid c_dumpbuf(void);
64249141Sdes
65249141Sdesstruct error {
66249141Sdes	struct error *next;
67249141Sdes	char	string[1];
68249141Sdes};
69238106Sdes
70238106Sdesstruct error *error_list, *error_last;
71238106Sdes
72238106Sdesvoid do_list_pc(void);
73238106Sdesvoid do_show_val(int32_t);
74238106Sdesvoid listing_line(void);
75238106Sdesvoid put1code(u_int16_t);
76238106Sdesvoid show_errors(void);
77238106Sdes
78238106Sdesvoid
79238106Sdesputcode(u_int16_t *v, int n)
80238106Sdes{
81238106Sdes	for( ; n > 0; --n )
82238106Sdes		put1code(*v++);
83238106Sdes}
84238106Sdes
85238106Sdesvoid
86249141Sdesput1code(u_int16_t v)
87269257Sdes{
88238106Sdes	if( code_idx >= 3 )
89238106Sdes		listing_line();
90238106Sdes	codes[code_idx] = v;
91238106Sdes	if( objfile != NULL ){
92238106Sdes		if( pc != obj_addr ){
93238106Sdes			if (c_name) {
94238106Sdes				if (c_bufptr > 0)
95238106Sdes					c_dumpbuf();
96238106Sdes				c_binads = pc;
97238106Sdes				c_bufptr = 0;
98238106Sdes			} else {
99238106Sdes				/* expect this only when ncode == 0 */
100238106Sdes				if (ncode % 8 != 0)
101238106Sdes					fprintf(objfile, "\n");
102238106Sdes				fprintf(objfile, "@%x\n", pc);
103238106Sdes			}
104238106Sdes			obj_addr = pc;
105238106Sdes		} else {
106238106Sdes			if((ncode % 8 != 0) && !c_name)
107238106Sdes				fprintf(objfile, " ");
108238106Sdes		}
109238106Sdes		if (c_name) {
110238106Sdes			c_checkbuf();
111238106Sdes			c_buf[c_bufptr++] = v;
112238106Sdes		} else
113238106Sdes			fprintf(objfile, "%.4X", v & 0xFFFF);
114238106Sdes		obj_addr += 0x10;
115238106Sdes		if((ncode % 8 == 7) && !c_name)
116238106Sdes			fprintf(objfile, "\n");
117238106Sdes	}
118238106Sdes	++ncode;
119238106Sdes	++code_idx;
120238106Sdes	pc += 0x10;
121238106Sdes	show_pc = TRUE;
122238106Sdes}
123238106Sdes
124238106Sdesvoid
125238106Sdesc_checkbuf()
126238106Sdes{
127238106Sdes	if (c_bufptr > (sizeof(c_buf)/sizeof(*c_buf)))
128238106Sdes		c_dumpbuf();
129238106Sdes}
130238106Sdes
131238106Sdesvoid
132238106Sdesc_dumpbuf()
133238106Sdes{
134238106Sdes	uint32_t i;
135238106Sdes
136238106Sdes	fprintf(objfile, "\n\n\t%d, 0x%04x, 0x%04x, /* new block */",
137238106Sdes	    c_bufptr, (int)(c_binads >> 16), (int)(c_binads & 0xffff));
138238106Sdes
139238106Sdes	for (i=0; i < c_bufptr; ++i) {
140238106Sdes		if (i%8 == 0)
141238106Sdes			fprintf(objfile, "\n\t");
142238106Sdes		fprintf(objfile, "0x%04x, ", c_buf[i]);
143238106Sdes	}
144238106Sdes	c_binads += c_bufptr;
145238106Sdes	c_bufptr = 0;
146238106Sdes}
147238106Sdes
148238106Sdesvoid
149238106Sdesstart_at(u_int32_t val)
150238106Sdes{
151238106Sdes	if( objfile != NULL ) {
152238106Sdes		if (c_name) {
153238106Sdes			c_checkbuf();
154238106Sdes			fprintf(objfile,
155238106Sdes			    "\n\n\t2, 0xffff, 0xfee0, 0x%04x, 0x%04x,"
156238106Sdes			      "\n\t2, 0xffff, 0xffe0, 0x%04x, 0x%04x,\n",
157238106Sdes			    val & 0xffff, val >> 16, val & 0xffff, val >> 16);
158238106Sdes		} else
159238106Sdes			fprintf(objfile, ":%lX\n", (long)val);
160238106Sdes	}
161238106Sdes}
162238106Sdes
163238106Sdesvoid
164238106Sdesdo_list_pc()
165238106Sdes{
166238106Sdes	if( pass2 )
167238106Sdes		show_pc = TRUE;
168238106Sdes}
169238106Sdes
170238106Sdesvoid
171238106Sdesdo_show_val(int32_t v)
172238106Sdes{
173238106Sdes	if( ncode == 0 ){
174238106Sdes		val_to_show = v;
175238106Sdes		show_val = TRUE;
176238106Sdes		show_pc = FALSE;
177238106Sdes	}
178238106Sdes}
179238106Sdes
180238106Sdesvoid
181238106Sdeslist_error(char *string)
182238106Sdes{
183238106Sdes	struct error *p;
184238106Sdes	int l;
185238106Sdes
186238106Sdes	if( listfile == NULL )
187238106Sdes		return;
188238106Sdes	l = strlen(string);
189238106Sdes	p = emalloc(sizeof(struct error) + l);
190238106Sdes	strcpy(p->string, string);
191238106Sdes	p->next = NULL;
192238106Sdes	if( error_list == NULL )
193238106Sdes		error_list = p;
194238106Sdes	else
195238106Sdes		error_last->next = p;
196238106Sdes	error_last = p;
197238106Sdes}
198238106Sdes
199238106Sdesvoid
200238106Sdesshow_errors()
201238106Sdes{
202238106Sdes	struct error *p, *q;
203238106Sdes
204249141Sdes	for( p = error_list; p != NULL; p = q ){
205238106Sdes		if( listfile != NULL )
206238106Sdes			fprintf(listfile, "\t\t\t%s\n", p->string);
207249141Sdes		q = p->next;
208238106Sdes		free(p);
209249141Sdes	}
210249141Sdes	error_list = error_last = NULL;
211269257Sdes}
212249141Sdes
213238106Sdesvoid
214249141Sdeslisting()
215238106Sdes{
216238106Sdes	if( objfile != NULL && ncode % 8 != 0 && !c_name)
217249141Sdes		fprintf(objfile, "\n");
218238106Sdes	listing_line();
219249141Sdes	show_errors();
220249141Sdes	ncode = 0;
221249141Sdes	show_pc = FALSE;
222249141Sdes}
223249141Sdes
224249141Sdesvoid
225249141Sdeslisting_line()
226249141Sdes{
227238106Sdes	unsigned i;
228238106Sdes
229238106Sdes	if( listfile == NULL ){
230238106Sdes		code_idx = 0;
231238106Sdes		return;
232238106Sdes	}
233238106Sdes	if( show_pc )
234238106Sdes		fprintf(listfile, "%.8X", line_pc);
235238106Sdes	else
236238106Sdes		fprintf(listfile, "        ");
237238106Sdes	if( show_val ){
238238106Sdes		fprintf(listfile, "  %.8X", val_to_show);
239238106Sdes		i = 2;
240238106Sdes	} else {
241238106Sdes		for( i = 0; i < code_idx; ++i )
242238106Sdes			fprintf(listfile, " %.4X", codes[i]);
243238106Sdes	}
244238106Sdes	if( ncode <= 3 ){
245238106Sdes		for( ; i < 3; ++i )
246238106Sdes			fprintf(listfile, "     ");
247238106Sdes		fprintf(listfile, " %s", line);
248238106Sdes	} else
249238106Sdes		fprintf(listfile, "\n");
250238106Sdes	line_pc += code_idx << 4;
251238106Sdes	code_idx = 0;
252238106Sdes	show_val = FALSE;
253238106Sdes}
254238106Sdes