First Commit of my working state
[simh.git] / AltairZ80 / n8vem.c
1 /*************************************************************************
2 * *
3 * $Id: n8vem.c 1902 2008-05-11 02:40:41Z hharte $ *
4 * *
5 * Copyright (c) 2007-2008 Howard M. Harte. *
6 * http://www.hartetec.com *
7 * *
8 * Permission is hereby granted, free of charge, to any person obtaining *
9 * a copy of this software and associated documentation files (the *
10 * "Software"), to deal in the Software without restriction, including *
11 * without limitation the rights to use, copy, modify, merge, publish, *
12 * distribute, sublicense, and/or sell copies of the Software, and to *
13 * permit persons to whom the Software is furnished to do so, subject to *
14 * the following conditions: *
15 * *
16 * The above copyright notice and this permission notice shall be *
17 * included in all copies or substantial portions of the Software. *
18 * *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
22 * NONINFRINGEMENT. IN NO EVENT SHALL HOWARD M. HARTE BE LIABLE FOR ANY *
23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE *
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
26 * *
27 * Except as contained in this notice, the name of Howard M. Harte shall *
28 * not be used in advertising or otherwise to promote the sale, use or *
29 * other dealings in this Software without prior written authorization *
30 * Howard M. Harte. *
31 * *
32 * SIMH Interface based on altairz80_hdsk.c, by Peter Schorn. *
33 * *
34 * Module Description: *
35 * N8VEM Single-Board Computer I/O module for SIMH. *
36 * http://groups.google.com/group/n8vem/web/n8vem-single-board-computer-home-page *
37 * *
38 * Environment: *
39 * User mode only *
40 * *
41 *************************************************************************/
42
43 /* #define DBG_MSG */
44
45 #include "altairz80_defs.h"
46
47 #if defined (_WIN32)
48 #include <windows.h>
49 #endif
50
51 #ifdef DBG_MSG
52 #define DBG_PRINT(args) printf args
53 #else
54 #define DBG_PRINT(args)
55 #endif
56
57 #define PIO_MSG 0x01
58 #define UART_MSG 0x02
59 #define RTC_MSG 0x04
60 #define MPCL_MSG 0x08
61 #define ROM_MSG 0x10
62 #define TRACE_MSG 0x80
63
64 #define N8VEM_MAX_DRIVES 2
65
66 #define UNIT_V_N8VEM_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
67 #define UNIT_N8VEM_VERBOSE (1 << UNIT_V_N8VEM_VERBOSE)
68
69 typedef struct {
70 PNP_INFO pnp; /* Plug and Play */
71 uint8 *ram;
72 uint8 *rom;
73 uint8 rom_attached;
74 uint8 uart_scr;
75 uint8 uart_lcr;
76 uint8 mpcl_ram;
77 uint8 mpcl_rom;
78 } N8VEM_INFO;
79
80 static N8VEM_INFO n8vem_info_data = { { 0x0, 0x8000, 0x60, 32 } };
81 static N8VEM_INFO *n8vem_info = &n8vem_info_data;
82
83 extern t_stat set_membase(UNIT *uptr, int32 val, char *cptr, void *desc);
84 extern t_stat show_membase(FILE *st, UNIT *uptr, int32 val, void *desc);
85 extern t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc);
86 extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc);
87 extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type,
88 int32 (*routine)(const int32, const int32, const int32), uint8 unmap);
89 extern uint32 PCX;
90 extern REG *sim_PC;
91 extern int32 find_unit_index (UNIT *uptr);
92
93 static t_stat n8vem_reset(DEVICE *n8vem_dev);
94 static t_stat n8vem_boot(int32 unitno, DEVICE *dptr);
95 static t_stat n8vem_attach(UNIT *uptr, char *cptr);
96 static t_stat n8vem_detach(UNIT *uptr);
97
98 static uint8 N8VEM_Read(const uint32 Addr);
99 static uint8 N8VEM_Write(const uint32 Addr, uint8 cData);
100
101 static int32 n8vemdev(const int32 port, const int32 io, const int32 data);
102 static int32 n8vem_mem(const int32 port, const int32 io, const int32 data);
103
104 static int32 trace_level = 0x00; /* Disable all tracing by default */
105 static int32 save_rom = 0x00; /* When set to 1, saves ROM back to file on disk at detach time */
106 static int32 save_ram = 0x00; /* When set to 1, saves RAM back to file on disk at detach time */
107 static int32 n8vem_pio1a = 0x00; /* 8255 PIO1A IN Port */
108 static int32 n8vem_pio1b = 0x00; /* 8255 PIO1B OUT Port */
109 static int32 n8vem_pio1c = 0x00; /* 8255 PIO1C IN Port */
110 static int32 n8vem_pio1ctrl = 0x00; /* 8255 PIO1 Control Port */
111
112 #define N8VEM_ROM_SIZE (1024 * 1024)
113 #define N8VEM_RAM_SIZE (512 * 1024)
114
115 #define N8VEM_RAM_SELECT (1 << 7)
116 #define N8VEM_RAM_MASK 0x0F
117 #define N8VEM_ROM_MASK 0x1F
118 #define N8VEM_ADDR_MASK 0x7FFF
119
120 static UNIT n8vem_unit[] = {
121 { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, N8VEM_ROM_SIZE) },
122 { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, N8VEM_RAM_SIZE) }
123 };
124
125 static REG n8vem_reg[] = {
126 { HRDATA (TRACELEVEL, trace_level, 16), },
127 { HRDATA (SAVEROM, save_rom, 1), },
128 { HRDATA (SAVERAM, save_ram, 1), },
129 { HRDATA (PIO1A, n8vem_pio1a, 8), },
130 { HRDATA (PIO1B, n8vem_pio1b, 8), },
131 { HRDATA (PIO1C, n8vem_pio1c, 8), },
132 { HRDATA (PIO1CTRL, n8vem_pio1ctrl, 8), },
133 { NULL }
134 };
135
136 static MTAB n8vem_mod[] = {
137 { MTAB_XTD|MTAB_VDV, 0, "MEMBASE", "MEMBASE", &set_membase, &show_membase, NULL },
138 { MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE", &set_iobase, &show_iobase, NULL },
139 /* quiet, no warning messages */
140 { UNIT_N8VEM_VERBOSE, 0, "QUIET", "QUIET", NULL },
141 /* verbose, show warning messages */
142 { UNIT_N8VEM_VERBOSE, UNIT_N8VEM_VERBOSE, "VERBOSE", "VERBOSE", NULL },
143 { 0 }
144 };
145
146 DEVICE n8vem_dev = {
147 "N8VEM", n8vem_unit, n8vem_reg, n8vem_mod,
148 N8VEM_MAX_DRIVES, 10, 31, 1, N8VEM_MAX_DRIVES, N8VEM_MAX_DRIVES,
149 NULL, NULL, &n8vem_reset,
150 &n8vem_boot, &n8vem_attach, &n8vem_detach,
151 &n8vem_info_data, (DEV_DISABLE | DEV_DIS), 0,
152 NULL, NULL, NULL
153 };
154
155 /* Reset routine */
156 static t_stat n8vem_reset(DEVICE *dptr)
157 {
158 PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt;
159
160 TRACE_PRINT(TRACE_MSG, ("N8VEM: Reset." NLP));
161
162 if(dptr->flags & DEV_DIS) { /* Disconnect I/O Ports */
163 sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &n8vemdev, TRUE);
164 sim_map_resource(pnp->mem_base, pnp->mem_size, RESOURCE_TYPE_MEMORY, &n8vem_mem, TRUE);
165 free(n8vem_info->ram);
166 free(n8vem_info->rom);
167 } else {
168 /* Connect N8VEM at base address */
169 if(sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &n8vemdev, FALSE) != 0) {
170 printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->io_base);
171 return SCPE_ARG;
172 }
173 /* Connect N8VEM Memory (512K RAM, 1MB FLASH) */
174 if(sim_map_resource(pnp->mem_base, pnp->mem_size, RESOURCE_TYPE_MEMORY, &n8vem_mem, FALSE) != 0) {
175 printf("%s: error mapping MEM resource at 0x%04x\n", __FUNCTION__, pnp->mem_base);
176 return SCPE_ARG;
177 }
178
179 n8vem_info->ram = calloc(1, (N8VEM_RAM_SIZE));
180 n8vem_info->rom = calloc(1, (N8VEM_ROM_SIZE));
181
182 /* Clear the RAM and ROM mapping registers */
183 n8vem_info->mpcl_ram = 0;
184 n8vem_info->mpcl_rom = 0;
185 }
186 return SCPE_OK;
187 }
188
189 static t_stat n8vem_boot(int32 unitno, DEVICE *dptr)
190 {
191 TRACE_PRINT(TRACE_MSG, ("N8VEM: Boot." NLP));
192
193 /* Clear the RAM and ROM mapping registers */
194 n8vem_info->mpcl_ram = 0;
195 n8vem_info->mpcl_rom = 0;
196
197 /* Set the PC to 0, and go. */
198 *((int32 *) sim_PC->loc) = 0;
199 return SCPE_OK;
200 }
201
202 /* Attach routine */
203 static t_stat n8vem_attach(UNIT *uptr, char *cptr)
204 {
205 t_stat r;
206 int32 i = 0;
207
208 i = find_unit_index(uptr);
209
210 if (i == -1) {
211 return (SCPE_IERR);
212 }
213
214 r = attach_unit(uptr, cptr); /* attach unit */
215 if ( r != SCPE_OK) /* error? */
216 return r;
217
218 /* Determine length of this disk */
219 uptr->capac = sim_fsize(uptr->fileref);
220
221 TRACE_PRINT(TRACE_MSG, ("N8VEM: Attach %s." NLP, i == 0 ? "ROM" : "RAM"));
222
223 if(i == 0) { /* Attaching ROM */
224 n8vem_info->rom_attached = TRUE;
225
226 /* Erase ROM */
227 memset(n8vem_info->rom, 0xFF, N8VEM_ROM_SIZE);
228
229 if(uptr->capac > 0) {
230 /* Only read in enough of the file to fill the ROM. */
231 if(uptr->capac > N8VEM_ROM_SIZE) uptr->capac = N8VEM_ROM_SIZE;
232
233 printf("Reading %d bytes into ROM.\n", uptr->capac);
234 fread((void *)(n8vem_info->rom), uptr->capac, 1, uptr->fileref);
235 }
236 } else { /* attaching RAM */
237 /* Erase RAM */
238 memset(n8vem_info->ram, 0x00, N8VEM_RAM_SIZE);
239
240 if(uptr->capac > 0) {
241 /* Only read in enough of the file to fill the RAM. */
242 if(uptr->capac > N8VEM_RAM_SIZE) uptr->capac = N8VEM_RAM_SIZE;
243
244 printf("Reading %d bytes into RAM.\n", uptr->capac);
245 fread((void *)(n8vem_info->ram), uptr->capac, 1, uptr->fileref);
246 }
247 }
248 return r;
249 }
250
251 /* Detach routine */
252 static t_stat n8vem_detach(UNIT *uptr)
253 {
254 t_stat r;
255 int32 i = 0;
256
257 i = find_unit_index(uptr);
258
259 if (i == -1) {
260 return (SCPE_IERR);
261 }
262
263 TRACE_PRINT(TRACE_MSG, ("N8VEM: Detach %s." NLP, i == 0 ? "ROM" : "RAM"));
264
265 /* rewind to the beginning of the file. */
266 fseek(uptr->fileref, 0, SEEK_SET);
267
268 if(i == 0) { /* ROM */
269 /* Save the ROM back to disk if SAVEROM is set. */
270 if(save_rom == 1) {
271 printf("Writing %d bytes into ROM image.\n", N8VEM_ROM_SIZE);
272 fwrite((void *)(n8vem_info->rom), N8VEM_ROM_SIZE, 1, uptr->fileref);
273 }
274 } else { /* RAM */
275 /* Save the RAM back to disk if SAVERAM is set. */
276 if(save_ram == 1) {
277 printf("Writing %d bytes into RAM image.\n", N8VEM_RAM_SIZE);
278 fwrite((void *)(n8vem_info->ram), N8VEM_RAM_SIZE, 1, uptr->fileref);
279 }
280 }
281 r = detach_unit(uptr); /* detach unit */
282
283 return r;
284 }
285
286 /* RAM MEMORY PAGE CONFIGURATION LATCH CONTROL PORT ( IO_Y3 ) INFORMATION
287 *
288 * 7 6 5 4 3 2 1 0 ONLY APPLICABLE TO THE LOWER MEMORY PAGE $0000-$7FFF
289 * ^ ^ ^ ^ ^ ^ ^ ^
290 * : : : : : : : :--0 = A15 RAM ADDRESS LINE DEFAULT IS 0
291 * : : : : : : :----0 = A16 RAM ADDRESS LINE DEFAULT IS 0
292 * : : : : : :------0 = A17 RAM ADDRESS LINE DEFAULT IS 0
293 * : : : : :--------0 = A18 RAM ADDRESS LINE DEFAULT IS 0
294 * : : : :-----------0 =
295 * : : :-------------0 =
296 * : :---------------0 =
297 * :-----------------0 =
298 *
299 * ROM MEMORY PAGE CONFIGURATION LATCH CONTROL PORT ( IO_Y3+$04 ) INFORMATION
300 *
301 * 7 6 5 4 3 2 1 0 ONLY APPLICABLE TO THE LOWER MEMORY PAGE $0000-$7FFF
302 * ^ ^ ^ ^ ^ ^ ^ ^
303 * : : : : : : : :--0 = A15 ROM ADDRESS LINE DEFAULT IS 0
304 * : : : : : : :----0 = A16 ROM ADDRESS LINE DEFAULT IS 0
305 * : : : : : :------0 = A17 ROM ADDRESS LINE DEFAULT IS 0
306 * : : : : :--------0 = A18 ROM ADDRESS LINE DEFAULT IS 0
307 * : : : :-----------0 = A19 ROM ONLY ADDRESS LINE DEFAULT IS 0
308 * : : :-------------0 =
309 * : :---------------0 =
310 * :-----------------0 = ROM SELECT (0=ROM, 1=RAM) DEFAULT IS 0
311 */
312 static int32 n8vem_mem(const int32 Addr, const int32 write, const int32 data)
313 {
314 /* DBG_PRINT(("N8VEM: ROM %s, Addr %04x" NLP, write ? "WR" : "RD", Addr)); */
315 if(write) {
316 if(n8vem_info->mpcl_rom & N8VEM_RAM_SELECT)
317 {
318 n8vem_info->ram[((n8vem_info->mpcl_ram & N8VEM_RAM_MASK) << 15) | (Addr & N8VEM_ADDR_MASK)] = data;
319 } else {
320 if(save_rom == 1) {
321 n8vem_info->rom[((n8vem_info->mpcl_rom & N8VEM_ROM_MASK) << 15) | (Addr & N8VEM_ADDR_MASK)] = data;
322 } else {
323 TRACE_PRINT(ROM_MSG, ("N8VEM: " ADDRESS_FORMAT " WR ROM[0x%05x]: Cannot write to ROM." NLP, PCX, ((n8vem_info->mpcl_rom & N8VEM_ROM_MASK) << 15) | (Addr & N8VEM_ADDR_MASK)));
324 }
325 }
326 return 0;
327 } else {
328 if(n8vem_info->mpcl_rom & N8VEM_RAM_SELECT)
329 {
330 return n8vem_info->ram[((n8vem_info->mpcl_ram & N8VEM_RAM_MASK) << 15) | (Addr & N8VEM_ADDR_MASK)];
331 } else {
332 return n8vem_info->rom[((n8vem_info->mpcl_rom & N8VEM_ROM_MASK) << 15) | (Addr & N8VEM_ADDR_MASK)];
333 }
334 }
335 }
336
337 static int32 n8vemdev(const int32 port, const int32 io, const int32 data)
338 {
339 /* DBG_PRINT(("N8VEM: IO %s, Port %02x\n", io ? "WR" : "RD", port)); */
340 if(io) {
341 N8VEM_Write(port, data);
342 return 0;
343 } else {
344 return(N8VEM_Read(port));
345 }
346 }
347
348 #define N8VEM_PIO1A 0x00 /* (INPUT) IN 1-8 */
349 #define N8VEM_PIO1B 0x01 /* (OUTPUT) OUT TO LEDS */
350 #define N8VEM_PIO1C 0x02 /* (INPUT) */
351 #define N8VEM_PIO1CONT 0x03 /* CONTROL BYTE PIO 82C55 */
352
353 #define N8VEM_UART_DATA 0x08
354 #define N8VEM_UART_RSR 0x09
355 #define N8VEM_UART_INTR 0x0A
356 #define N8VEM_UART_LCR 0x0B
357 #define N8VEM_UART_MCR 0x0C
358 #define N8VEM_UART_LSR 0x0D
359 #define N8VEM_UART_MSR 0x0E
360 #define N8VEM_UART_SCR 0x0F
361
362 #define N8VEM_MPCL_RAM 0x18 /* RAM Address control port */
363 #define N8VEM_MPCL_RAM1 0x19 /* RAM Address control port */
364 #define N8VEM_MPCL_RAM2 0x1A /* RAM Address control port */
365 #define N8VEM_MPCL_RAM3 0x1B /* RAM Address control port */
366 #define N8VEM_MPCL_ROM 0x1C /* ROM Address control port */
367 #define N8VEM_MPCL_ROM1 0x1D /* ROM Address control port */
368 #define N8VEM_MPCL_ROM2 0x1E /* ROM Address control port */
369 #define N8VEM_MPCL_ROM3 0x1F /* ROM Address control port */
370
371 extern int32 sio0d(const int32 port, const int32 io, const int32 data);
372 extern int32 sio0s(const int32 port, const int32 io, const int32 data);
373
374 static uint8 N8VEM_Read(const uint32 Addr)
375 {
376 uint8 cData = 0xFF;
377
378 switch(Addr & 0x1F) {
379 case N8VEM_PIO1A:
380 TRACE_PRINT(PIO_MSG, ("N8VEM: " ADDRESS_FORMAT " RD: PIO1A" NLP, PCX));
381 cData = n8vem_pio1a;
382 break;
383 case N8VEM_PIO1B:
384 TRACE_PRINT(PIO_MSG, ("N8VEM: " ADDRESS_FORMAT " RD: PIO1B" NLP, PCX));
385 cData = n8vem_pio1b;
386 break;
387 case N8VEM_PIO1C:
388 TRACE_PRINT(PIO_MSG, ("N8VEM: " ADDRESS_FORMAT " RD: PIO1C" NLP, PCX));
389 cData = n8vem_pio1c;
390 break;
391 case N8VEM_PIO1CONT:
392 TRACE_PRINT(PIO_MSG, ("N8VEM: " ADDRESS_FORMAT " RD: PIO1CTRL" NLP, PCX));
393 cData = n8vem_pio1ctrl;
394 break;
395 case N8VEM_UART_LCR:
396 cData = n8vem_info->uart_lcr;
397 break;
398 case N8VEM_UART_DATA:
399 case N8VEM_UART_RSR:
400 case N8VEM_UART_LSR:
401 case N8VEM_UART_INTR:
402 case N8VEM_UART_MCR:
403 case N8VEM_UART_MSR:
404 TRACE_PRINT(UART_MSG, ("N8VEM: " ADDRESS_FORMAT " RD[%02x]: UART not Implemented." NLP, PCX, Addr));
405 break;
406 case N8VEM_UART_SCR: /* 16550 Scratchpad, implemented so software can detect UART is present */
407 cData = n8vem_info->uart_scr;
408 break;
409 case N8VEM_MPCL_RAM:
410 case N8VEM_MPCL_RAM1:
411 case N8VEM_MPCL_RAM2:
412 case N8VEM_MPCL_RAM3:
413 TRACE_PRINT(MPCL_MSG, ("N8VEM: " ADDRESS_FORMAT " RD: MPCL_RAM not Implemented." NLP, PCX));
414 break;
415 case N8VEM_MPCL_ROM:
416 case N8VEM_MPCL_ROM1:
417 case N8VEM_MPCL_ROM2:
418 case N8VEM_MPCL_ROM3:
419 TRACE_PRINT(MPCL_MSG, ("N8VEM: " ADDRESS_FORMAT " RD: MPCL_ROM not Implemented." NLP, PCX));
420 break;
421 default:
422 TRACE_PRINT(TRACE_MSG, ("N8VEM: " ADDRESS_FORMAT " RD[%02x]: not Implemented." NLP, PCX, Addr));
423 break;
424 }
425
426 return (cData);
427
428 }
429
430 static uint8 N8VEM_Write(const uint32 Addr, uint8 cData)
431 {
432
433 switch(Addr & 0x1F) {
434 case N8VEM_PIO1A:
435 TRACE_PRINT(PIO_MSG, ("N8VEM: " ADDRESS_FORMAT " WR: PIO1A=0x%02x" NLP, PCX, cData));
436 n8vem_pio1a = cData;
437 break;
438 case N8VEM_PIO1B:
439 TRACE_PRINT(PIO_MSG, ("N8VEM: " ADDRESS_FORMAT " WR: PIO1B=0x%02x" NLP, PCX, cData));
440 n8vem_pio1b = cData;
441 break;
442 case N8VEM_PIO1C:
443 TRACE_PRINT(PIO_MSG, ("N8VEM: " ADDRESS_FORMAT " WR: PIO1C=0x%02x" NLP, PCX, cData));
444 n8vem_pio1c = cData;
445 break;
446 case N8VEM_PIO1CONT:
447 TRACE_PRINT(PIO_MSG, ("N8VEM: " ADDRESS_FORMAT " WR: PIO1_CTRL=0x%02x" NLP, PCX, cData));
448 n8vem_pio1ctrl = cData;
449 break;
450 case N8VEM_UART_LCR:
451 TRACE_PRINT(UART_MSG, ("N8VEM: " ADDRESS_FORMAT " WR: UART LCR=%02x." NLP, PCX, cData));
452 n8vem_info->uart_lcr = cData;
453 break;
454 case N8VEM_UART_DATA:
455 case N8VEM_UART_RSR:
456 case N8VEM_UART_INTR:
457 case N8VEM_UART_MCR:
458 case N8VEM_UART_LSR:
459 case N8VEM_UART_MSR:
460 TRACE_PRINT(UART_MSG, ("N8VEM: " ADDRESS_FORMAT " WR[%02x]: UART not Implemented." NLP, PCX, Addr));
461 break;
462 case N8VEM_UART_SCR: /* 16550 Scratchpad, implemented so software can detect UART is present */
463 n8vem_info->uart_scr = cData;
464 break;
465 case N8VEM_MPCL_RAM:
466 case N8VEM_MPCL_RAM1:
467 case N8VEM_MPCL_RAM2:
468 case N8VEM_MPCL_RAM3:
469 TRACE_PRINT(MPCL_MSG, ("N8VEM: " ADDRESS_FORMAT " WR: MPCL_RAM=0x%02x" NLP, PCX, cData));
470 n8vem_info->mpcl_ram = cData;
471 break;
472 case N8VEM_MPCL_ROM:
473 case N8VEM_MPCL_ROM1:
474 case N8VEM_MPCL_ROM2:
475 case N8VEM_MPCL_ROM3:
476 TRACE_PRINT(MPCL_MSG, ("N8VEM: " ADDRESS_FORMAT " WR: MPCL_ROM=0x%02x" NLP, PCX, cData));
477 n8vem_info->mpcl_rom = cData;
478 break;
479 default:
480 TRACE_PRINT(TRACE_MSG, ("N8VEM: " ADDRESS_FORMAT " WR[0x%02x]=0x%02x: not Implemented." NLP, PCX, Addr, cData));
481 break;
482 }
483
484 return(0);
485 }
486