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