1 /* bootrom.c: Boot ROM simulator for Motorola processors
2
3 Copyright (c) 2010-2011, William A. Beech
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 WILLIAM A. BEECH 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 William A. Beech 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 William A. Beech.
25
26 These functions support a single simulated 2704 to 2764 EPROM device on
27 an 8-bit computer system.. This device allows the the device buffer to
28 be loaded from a binary file containing the emulated EPROM code.
29
30 These functions support a simulated 2704, 2708, 2716, 2732 or 2764 EPROM
31 device on a CPU board. The byte get and put routines use an offset into
32 the boot EPROM image to locate the proper byte. This allows another device
33 to set the base address for the boot EPROM. The device type is stored as
34 a binary number in the first three unit flag bits.
35
36 This device uses a dynamically allocated buffer to hold the EPROM image.
37 A call to BOOTROM_config will free the current buffer. A call to
38 BOOTROM_reset will allocate a new buffer of BOOTROM_unit.capac bytes. A
39 call to BOOTROM_attach will load the buffer with the EPROM image.
40 */
41
42 #include <stdio.h>
43 #include "swtp_defs.h"
44
45 #define UNIT_V_MSIZE (UNIT_V_UF) /* ROM Size */
46 #define UNIT_MSIZE (0x7 << UNIT_V_MSIZE)
47 #define UNIT_NONE (0 << UNIT_V_MSIZE) /* No EPROM */
48 #define UNIT_2704 (1 << UNIT_V_MSIZE) /* 2704 mode */
49 #define UNIT_2708 (2 << UNIT_V_MSIZE) /* 2708 mode */
50 #define UNIT_2716 (3 << UNIT_V_MSIZE) /* 2716 mode */
51 #define UNIT_2732 (4 << UNIT_V_MSIZE) /* 2732 mode */
52 #define UNIT_2764 (5 << UNIT_V_MSIZE) /* 2764 mode */
53
54 /* function prototypes */
55
56 t_stat BOOTROM_svc (UNIT *uptr);
57 t_stat BOOTROM_config (UNIT *uptr, int32 val, char *cptr, void *desc);
58 t_stat BOOTROM_attach (UNIT *uptr, char *cptr);
59 t_stat BOOTROM_reset (DEVICE *dptr);
60 int32 BOOTROM_get_mbyte(int32 offset);
61
62 /* SIMH Standard I/O Data Structures */
63
64 UNIT BOOTROM_unit = { UDATA (NULL,
65 UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),
66 KBD_POLL_WAIT };
67
68 MTAB BOOTROM_mod[] = {
69 { UNIT_MSIZE, UNIT_NONE, "None", "NONE", &BOOTROM_config },
70 { UNIT_MSIZE, UNIT_2704, "2704", "2704", &BOOTROM_config },
71 { UNIT_MSIZE, UNIT_2708, "2708", "2708", &BOOTROM_config },
72 { UNIT_MSIZE, UNIT_2716, "2716", "2716", &BOOTROM_config },
73 { UNIT_MSIZE, UNIT_2732, "2732", "2732", &BOOTROM_config },
74 { UNIT_MSIZE, UNIT_2764, "2764", "2764", &BOOTROM_config },
75 { 0 }
76 };
77
78 DEBTAB BOOTROM_debug[] = {
79 { "ALL", DEBUG_all },
80 { "FLOW", DEBUG_flow },
81 { "READ", DEBUG_read },
82 { "WRITE", DEBUG_write },
83 { "LEV1", DEBUG_level1 },
84 { "LEV2", DEBUG_level2 },
85 { NULL }
86 };
87
88 DEVICE BOOTROM_dev = {
89 "BOOTROM", /* name */
90 &BOOTROM_unit, /* units */
91 NULL, /* registers */
92 BOOTROM_mod, /* modifiers */
93 1, /* numunits */
94 16, /* aradix */
95 32, /* awidth */
96 1, /* aincr */
97 16, /* dradix */
98 8, /* dwidth */
99 NULL, /* examine */
100 NULL, /* deposit */
101 &BOOTROM_reset, /* reset */
102 NULL, /* boot */
103 &BOOTROM_attach, /* attach */
104 NULL, /* detach */
105 NULL, /* ctxt */
106 DEV_DEBUG, /* flags */
107 0, /* dctrl */
108 BOOTROM_debug, /* debflags */
109 NULL, /* msize */
110 NULL /* lname */
111 };
112
113 /* global variables */
114
115 /* BOOTROM_attach - attach file to EPROM unit */
116
BOOTROM_attach(UNIT * uptr,char * cptr)117 t_stat BOOTROM_attach (UNIT *uptr, char *cptr)
118 {
119 t_stat r;
120
121 if (BOOTROM_dev.dctrl & DEBUG_flow)
122 printf("BOOTROM_attach: cptr=%s\n", cptr);
123 if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
124 if (BOOTROM_dev.dctrl & DEBUG_flow)
125 printf("BOOTROM_attach: Error\n");
126 return r;
127 }
128 if (BOOTROM_dev.dctrl & DEBUG_flow)
129 printf("BOOTROM_attach: Done\n");
130 return (BOOTROM_reset (NULL));
131 }
132
133 /* BOOTROM_config = None, 2704, 2708, 2716, 2732 or 2764 */
134
BOOTROM_config(UNIT * uptr,int32 val,char * cptr,void * desc)135 t_stat BOOTROM_config (UNIT *uptr, int32 val, char *cptr, void *desc)
136 {
137 if (BOOTROM_dev.dctrl & DEBUG_flow) /* entry message */
138 printf("BOOTROM_config: val=%d\n", val);
139 if ((val < UNIT_NONE) || (val > UNIT_2764)) { /* valid param? */
140 if (BOOTROM_dev.dctrl & DEBUG_flow) /* No */
141 printf("BOOTROM_config: Parameter error\n");
142 return SCPE_ARG;
143 }
144 if (val == UNIT_NONE)
145 BOOTROM_unit.capac = 0; /* set EPROM size */
146 else
147 BOOTROM_unit.capac = 0x200 << ((val >> UNIT_V_MSIZE) - 1); /* set EPROM size */
148 if (BOOTROM_unit.filebuf) { /* free buffer */
149 free (BOOTROM_unit.filebuf);
150 BOOTROM_unit.filebuf = NULL;
151 }
152 if (BOOTROM_dev.dctrl & DEBUG_flow) /* status message */
153 printf("BOOTROM_config: BOOTROM_unit.capac=%d\n",
154 BOOTROM_unit.capac);
155 if (BOOTROM_dev.dctrl & DEBUG_flow) /* exit message */
156 printf("BOOTROM_config: Done\n");
157 return SCPE_OK;
158 }
159
160 /* EPROM reset */
161
BOOTROM_reset(DEVICE * dptr)162 t_stat BOOTROM_reset (DEVICE *dptr)
163 {
164 int j, c;
165 FILE *fp;
166 t_stat r;
167
168 if (BOOTROM_dev.dctrl & DEBUG_flow)
169 printf("BOOTROM_reset: \n");
170 if ((BOOTROM_unit.flags & UNIT_MSIZE) == 0) { /* if none selected */
171 // printf(" EPROM: Defaulted to None\n");
172 // printf(" \"set eprom NONE | 2704 | 2708 | 2716 | 2732 | 2764\"\n");
173 // printf(" \"att eprom <filename>\"\n");
174 BOOTROM_unit.capac = 0; /* set EPROM size to 0 */
175 if (BOOTROM_dev.dctrl & DEBUG_flow)
176 printf("BOOTROM_reset: Done1\n");
177 return SCPE_OK;
178 } /* if attached */
179 // printf(" EPROM: Initializing [%04X-%04XH]\n",
180 // 0xE000, 0xE000 + BOOTROM_unit.capac - 1);
181 if (BOOTROM_unit.filebuf == NULL) { /* no buffer allocated */
182 BOOTROM_unit.filebuf = malloc(BOOTROM_unit.capac); /* allocate EPROM buffer */
183 if (BOOTROM_unit.filebuf == NULL) {
184 if (BOOTROM_dev.dctrl & DEBUG_flow)
185 printf("BOOTROM_reset: Malloc error\n");
186 return SCPE_MEM;
187 }
188 }
189 fp = fopen(BOOTROM_unit.filename, "rb"); /* open EPROM file */
190 if (fp == NULL) {
191 printf("\tUnable to open ROM file %s\n",BOOTROM_unit.filename);
192 printf("\tNo ROM image loaded!!!\n");
193 return SCPE_OK;
194 }
195 j = 0; /* load EPROM file */
196 c = fgetc(fp);
197 while (c != EOF) {
198 *(uint8 *)(BOOTROM_unit.filebuf + j++) = c & 0xFF;
199 c = fgetc(fp);
200 if (j > BOOTROM_unit.capac) {
201 printf("\tImage is too large - Load truncated!!!\n");
202 break;
203 }
204 }
205 fclose(fp);
206 // printf("\t%d bytes of ROM image %s loaded\n", j, BOOTROM_unit.filename);
207 if (BOOTROM_dev.dctrl & DEBUG_flow)
208 printf("BOOTROM_reset: Done2\n");
209 return SCPE_OK;
210 }
211
212 /* get a byte from memory - byte offset of image */
213
BOOTROM_get_mbyte(int32 offset)214 int32 BOOTROM_get_mbyte(int32 offset)
215 {
216 int32 val;
217
218 if (BOOTROM_unit.filebuf == NULL) {
219 if (BOOTROM_dev.dctrl & DEBUG_read)
220 printf("BOOTROM_get_mbyte: EPROM not configured\n");
221 return 0xFF;
222 }
223 if (BOOTROM_dev.dctrl & DEBUG_read)
224 printf("BOOTROM_get_mbyte: offset=%04X\n", offset);
225 val = *(uint8 *)(BOOTROM_unit.filebuf + offset) & 0xFF;
226 if (BOOTROM_dev.dctrl & DEBUG_read)
227 printf("BOOTROM_get_mbyte: Normal val=%02X\n", val);
228 return val;
229 }
230
231 /* end of bootrom.c */
232