1 /* i7094_binloader.c: IBM 7094 simulator interface
2 
3    Copyright (c) 2008, David G. Pitts
4 
5    Permission is hereby granted, free of charge, to any person obtaining a
6    copy of this software and associated documentation files (the "Software"),
7    to deal in the Software without restriction, including without limitation
8    the rights to use, copy, modify, merge, publish, distribute, sublicense,
9    and/or sell copies of the Software, and to permit persons to whom the
10    Software is furnished to do so, subject to the following conditions:
11 
12    The above copyright notice and this permission notice shall be included in
13    all copies or substantial portions of the Software.
14 
15    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18    THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22    Except as contained in this notice, the name of the author shall not be
23    used in advertising or otherwise to promote the sale, use or other dealings
24    in this Software without prior written authorization from the author.
25 */
26 /***********************************************************************
27 *
28 * binloader.h - IBM 7090 emulator binary loader header.
29 *
30 * Changes:
31 *   10/20/03   DGP   Original.
32 *   12/28/04   DGP   Changed for new object formats.
33 *
34 ***********************************************************************/
35 
36 #define IBSYSSYM	'$'		/* Marks end of object file */
37 #define WORDPERREC	5		/* Object words per record */
38 #define LOADADDR	0200		/* Default load address */
39 #define OBJRECLEN	80		/* Object record length */
40 #define CHARWORD	12		/* Characters per word */
41 
42 /*
43 ** Object tags
44 */
45 
46 #define IDT_TAG		'0'		/* 0SSSSSS0LLLLL */
47 #define ABSENTRY_TAG	'1'		/* 10000000AAAAA */
48 #define RELENTRY_TAG	'2'		/* 20000000RRRRR */
49 #define ABSEXTRN_TAG	'3'		/* 3SSSSSS0AAAAA */
50 #define RELEXTRN_TAG	'4'		/* 4SSSSSS0RRRRR */
51 #define ABSGLOBAL_TAG	'5'		/* 5SSSSSS0AAAAA */
52 #define RELGLOBAL_TAG	'6'		/* 6SSSSSS0RRRRR */
53 #define ABSORG_TAG	'7'		/* 70000000AAAAA */
54 #define RELORG_TAG	'8'		/* 80000000RRRRR */
55 #define ABSDATA_TAG	'9'		/* 9AAAAAAAAAAAA */
56 #define RELADDR_TAG 	'A'		/* AAAAAAAARRRRR */
57 #define RELDECR_TAG 	'B'		/* BARRRRRAAAAAA */
58 #define RELBOTH_TAG 	'C'		/* CARRRRRARRRRR */
59 #define BSS_TAG		'D'    		/* D0000000PPPPP */
60 #define ABSXFER_TAG	'E'		/* E0000000RRRRR */
61 #define RELXFER_TAG	'F'		/* F0000000RRRRR */
62 #define EVEN_TAG	'G'		/* G0000000RRRRR */
63 #define FAPCOMMON_TAG	'H'		/* H0000000AAAAA */
64 
65 /* Where:
66  *    SSSSSS - Symbol
67  *    LLLLLL - Length of module
68  *    AAAAAA - Absolute field
69  *    RRRRRR - Relocatable field
70  *    PPPPPP - PC offset field
71 */
72 
73 /***********************************************************************
74 *
75 * binloader.c - IBM 7090 emulator binary loader routines for ASM7090
76 *            and LNK7090 object files.
77 *
78 * Changes:
79 *   10/20/03   DGP   Original.
80 *   12/28/04   DGP   Changed for new object formats.
81 *   02/14/05   DGP   Detect IBSYSSYM for EOF.
82 *   06/09/06   DGP   Make simh callable.
83 *
84 ***********************************************************************/
85 
86 #include "i7094_defs.h"
87 
88 extern t_uint64 *M;
89 extern uint32 PC;
90 
91 t_stat
binloader(FILE * fd,char * file,int loadpt)92 binloader (FILE *fd, char *file, int loadpt)
93 {
94 #ifdef DEBUGLOADER
95    FILE *lfd;
96 #endif
97    int transfer = FALSE;
98    int loadaddr = LOADADDR;
99    int curraddr = LOADADDR;
100    char inbuf[OBJRECLEN+2];
101 
102 #ifdef DEBUGLOADER
103    lfd = fopen ("load.log", "w");
104    fprintf (lfd, "binloader: file = '%s', loadpt = %d\n", file, loadpt);
105 #endif
106 
107    if (loadpt > 0)
108    {
109       loadaddr = loadpt;
110       curraddr = loadpt;
111    }
112 
113    while (fgets (inbuf, sizeof(inbuf), fd))
114    {
115       char *op = inbuf;
116       int i;
117 
118       if (*op == IBSYSSYM)	                            /* End of object marker */
119          break;
120 
121       for (i = 0; i < WORDPERREC; i++)
122       {
123 	char otag;
124 	char item[16];
125 	t_uint64 ldata;
126 
127 	otag = *op++;
128 	if (otag == ' ')
129         break;
130 	strncpy (item, op, CHARWORD);
131 	item[CHARWORD] = '\0';
132 #ifdef WIN32
133 	sscanf (item, "%I64o", &ldata);
134 #else
135 	sscanf (item, "%llo", &ldata);
136 #endif
137 
138 #ifdef DEBUGLOADER
139 	fprintf (lfd, "loadaddr = %05o, curraddr = %05o\n",
140 		  loadaddr, curraddr);
141 	fprintf (lfd, "   otag = %c, item = %s\n", otag, item);
142 	fprintf (lfd, "   ldata = %12.12o\n", ldata);
143 #endif
144 
145          switch (otag)
146 	{
147 	case IDT_TAG:
148 	    break;
149 
150 	case ABSORG_TAG:
151 	    curraddr = loadaddr = (int32) ldata & AMASK;
152 	    break;
153 
154 	case RELORG_TAG:
155 	    curraddr = (int32) (ldata + loadaddr) & AMASK;
156 	    break;
157 
158 	case BSS_TAG:
159 	    curraddr = (int32) (curraddr + ldata) & AMASK;
160 	    break;
161 
162 	case RELBOTH_TAG:
163 	    ldata = ldata + loadaddr + (loadaddr << INST_V_DEC);
164 	    goto STORE;
165 
166 	case RELDECR_TAG:
167 	    ldata = ldata + (loadaddr << INST_V_DEC);
168 	    goto STORE;
169 
170 	case RELADDR_TAG:
171 	    ldata = ldata + loadaddr;
172 
173 	case ABSDATA_TAG:
174 	STORE:
175 #ifdef DEBUGLOADER
176 	    fprintf (lfd, "   M[%05o] = %12.12o\n", curraddr, ldata);
177 #endif
178 	    M[curraddr] = ldata & DMASK;
179 	    curraddr++;
180 	    break;
181 
182 	case ABSXFER_TAG:
183 	    transfer = TRUE;
184 	case ABSENTRY_TAG:
185 	    PC = (uint32) ldata & AMASK;
186 #ifdef DEBUGLOADER
187 	    fprintf (lfd, "   PC = %05o\n", PC);
188 #endif
189 	    if (transfer)
190             goto GOSTART;
191 	    break;
192 
193 	case RELXFER_TAG:
194 	    transfer = TRUE;
195 	case RELENTRY_TAG:
196 	    ldata = (ldata + loadaddr) & AMASK;
197 	    PC = (uint32) ldata & AMASK;
198 #ifdef DEBUGLOADER
199 	    fprintf (lfd, "   PC = %05o\n", PC);
200 #endif
201 	    if (transfer)
202             goto GOSTART;
203 	    break;
204 
205 	default: ;
206 	}
207 	op += CHARWORD;
208       }
209    }
210 
211 GOSTART:
212 #ifdef DEBUGLOADER
213    fclose (lfd);
214 #endif
215 
216    return SCPE_OK;
217 }
218