src/mess/video/crt9007.c
| r7571 | r7572 | |
| 1 | | /**********************************************************************
|
| 2 | | |
| 3 | | SMC CRT9007 CRT Video Processor and Controller (VPAC) emulation
|
| 4 | | |
| 5 | | Copyright MESS Team.
|
| 6 | | Visit http://mamedev.org for licensing and usage restrictions.
|
| 7 | | |
| 8 | | **********************************************************************/
|
| 9 | | |
| 10 | | /*
|
| 11 | | |
| 12 | | TODO:
|
| 13 | | |
| 14 | | - interrupts
|
| 15 | | - status register
|
| 16 | | - reset
|
| 17 | | - DMA mode (currently forcing to non-DMA mode)
|
| 18 | | - cursor/blank skew
|
| 19 | | - sequential breaks
|
| 20 | | - interlaced mode
|
| 21 | | - smooth scroll
|
| 22 | | - page blank
|
| 23 | | - double height cursor
|
| 24 | | - row attributes
|
| 25 | | - pin configuration
|
| 26 | | - operation modes 0,4,7
|
| 27 | | - address modes 1,2,3
|
| 28 | | - light pen
|
| 29 | | - state saving
|
| 30 | | |
| 31 | | */
|
| 32 | | |
| 33 | | #include "emu.h"
|
| 34 | | #include "crt9007.h"
|
| 35 | | |
| 36 | | /***************************************************************************
|
| 37 | | PARAMETERS
|
| 38 | | ***************************************************************************/
|
| 39 | | |
| 40 | | #define LOG 1
|
| 41 | | |
| 42 | | #define HAS_VALID_PARAMETERS \
|
| 43 | | (crt9007->reg[0x00] && crt9007->reg[0x01] && crt9007->reg[0x07] && crt9007->reg[0x08] && crt9007->reg[0x09])
|
| 44 | | |
| 45 | | #define CHARACTERS_PER_HORIZONTAL_PERIOD \
|
| 46 | | crt9007->reg[0x00]
|
| 47 | | |
| 48 | | #define CHARACTERS_PER_DATA_ROW \
|
| 49 | | (crt9007->reg[0x01] + 1)
|
| 50 | | |
| 51 | | #define HORIZONTAL_DELAY \
|
| 52 | | crt9007->reg[0x02]
|
| 53 | | |
| 54 | | #define HORIZONTAL_SYNC_WIDTH \
|
| 55 | | crt9007->reg[0x03]
|
| 56 | | |
| 57 | | #define VERTICAL_SYNC_WIDTH \
|
| 58 | | crt9007->reg[0x04]
|
| 59 | | |
| 60 | | #define VERTICAL_DELAY \
|
| 61 | | (crt9007->reg[0x05] - 1)
|
| 62 | | |
| 63 | | #define PIN_CONFIGURATION \
|
| 64 | | (crt9007->reg[0x06] >> 6)
|
| 65 | | |
| 66 | | #define CURSOR_SKEW \
|
| 67 | | ((crt9007->reg[0x06] >> 3) & 0x07)
|
| 68 | | |
| 69 | | #define BLANK_SKEW \
|
| 70 | | (crt9007->reg[0x06] & 0x07)
|
| 71 | | |
| 72 | | #define VISIBLE_DATA_ROWS_PER_FRAME \
|
| 73 | | (crt9007->reg[0x07] + 1)
|
| 74 | | |
| 75 | | #define SCAN_LINES_PER_DATA_ROW \
|
| 76 | | ((crt9007->reg[0x08] & 0x1f) + 1)
|
| 77 | | |
| 78 | | #define SCAN_LINES_PER_FRAME \
|
| 79 | | (((crt9007->reg[0x08] << 3) & 0x0700) | crt9007->reg[0x09])
|
| 80 | | |
| 81 | | #define DMA_BURST_COUNT \
|
| 82 | | (crt9007->reg[0x0a] & 0x0f)
|
| 83 | | |
| 84 | | #define DMA_BURST_DELAY \
|
| 85 | | ((crt9007->reg[0x0a] >> 4) & 0x07)
|
| 86 | | |
| 87 | | #define DMA_DISABLE \
|
| 88 | | BIT(crt9007->reg[0x0a], 7)
|
| 89 | | |
| 90 | | #define SINGLE_HEIGHT_CURSOR \
|
| 91 | | BIT(crt9007->reg[0x0b], 0)
|
| 92 | | |
| 93 | | #define OPERATION_MODE \
|
| 94 | | ((crt9007->reg[0x0b] >> 1) & 0x07)
|
| 95 | | |
| 96 | | #define INTERLACE_MODE \
|
| 97 | | ((crt9007->reg[0x0b] >> 4) & 0x03)
|
| 98 | | |
| 99 | | #define PAGE_BLANK \
|
| 100 | | BIT(crt9007->reg[0x0b], 6)
|
| 101 | | |
| 102 | | #define TABLE_START \
|
| 103 | | (((crt9007->reg[0x0d] << 8) & 0x3f00) | crt9007->reg[0x0c])
|
| 104 | | |
| 105 | | #define ADDRESS_MODE \
|
| 106 | | ((crt9007->reg[0x0d] >> 6) & 0x03)
|
| 107 | | |
| 108 | | #define AUXILIARY_ADDRESS_1 \
|
| 109 | | (((crt9007->reg[0x0f] << 8) & 0x3f00) | crt9007->reg[0x0e])
|
| 110 | | |
| 111 | | #define ROW_ATTRIBUTES_1 \
|
| 112 | | ((crt9007->reg[0x0f] >> 6) & 0x03)
|
| 113 | | |
| 114 | | #define SEQUENTIAL_BREAK_1 \
|
| 115 | | crt9007->reg[0x10]
|
| 116 | | |
| 117 | | #define SEQUENTIAL_BREAK_2 \
|
| 118 | | crt9007->reg[0x12]
|
| 119 | | |
| 120 | | #define DATA_ROW_START \
|
| 121 | | crt9007->reg[0x11]
|
| 122 | | |
| 123 | | #define DATA_ROW_END \
|
| 124 | | crt9007->reg[0x12]
|
| 125 | | |
| 126 | | #define AUXILIARY_ADDRESS_2 \
|
| 127 | | (((crt9007->reg[0x14] << 8) & 0x3f00) | crt9007->reg[0x13])
|
| 128 | | |
| 129 | | #define ROW_ATTRIBUTES_2 \
|
| 130 | | ((crt9007->reg[0x14] >> 6) & 0x03)
|
| 131 | | |
| 132 | | #define SMOOTH_SCROLL_OFFSET \
|
| 133 | | ((crt9007->reg[0x17] >> 1) & 0x3f)
|
| 134 | | |
| 135 | | #define SMOOTH_SCROLL_OFFSET_OVERFLOW \
|
| 136 | | BIT(crt9007->reg[0x17], 7)
|
| 137 | | |
| 138 | | #define VERTICAL_CURSOR \
|
| 139 | | crt9007->reg[0x18]
|
| 140 | | |
| 141 | | #define HORIZONTAL_CURSOR \
|
| 142 | | crt9007->reg[0x19]
|
| 143 | | |
| 144 | | #define FRAME_TIMER \
|
| 145 | | BIT(crt9007->reg[0x1a], 0)
|
| 146 | | |
| 147 | | #define LIGHT_PEN_INTERRUPT \
|
| 148 | | BIT(crt9007->reg[0x1a], 5)
|
| 149 | | |
| 150 | | #define VERTICAL_RETRACE_INTERRUPT \
|
| 151 | | BIT(crt9007->reg[0x1a], 6)
|
| 152 | | |
| 153 | | #define VERTICAL_LIGHT_PEN \
|
| 154 | | crt9007->reg[0x3b]
|
| 155 | | |
| 156 | | #define HORIZONTAL_LIGHT_PEN \
|
| 157 | | crt9007->reg[0x3c]
|
| 158 | | |
| 159 | | enum
|
| 160 | | {
|
| 161 | | NON_INTERLACED = 0,
|
| 162 | | ENHANCED_VIDEO_INTERFACE,
|
| 163 | | NORMAL_VIDEO_INTERFACE,
|
| 164 | | };
|
| 165 | | |
| 166 | | enum
|
| 167 | | {
|
| 168 | | OPERATION_MODE_REPETITIVE_MEMORY_ADDRESSING = 0,
|
| 169 | | OPERATION_MODE_DOUBLE_ROW_BUFFER,
|
| 170 | | OPERATION_MODE_SINGLE_ROW_BUFFER = 4,
|
| 171 | | OPERATION_MODE_ATTRIBUTE_ASSEMBLE = 7
|
| 172 | | };
|
| 173 | | |
| 174 | | enum
|
| 175 | | {
|
| 176 | | ADDRESS_MODE_SEQUENTIAL_ADDRESSING = 0,
|
| 177 | | ADDRESS_MODE_SEQUENTIAL_ROLL_ADDRESSING,
|
| 178 | | ADDRESS_MODE_CONTIGUOUS_ROW_TABLE,
|
| 179 | | ADDRESS_MODE_LINKED_LIST_ROW_TABLE
|
| 180 | | };
|
| 181 | | |
| 182 | | #define STATUS_INTERRUPT_PENDING 0x80
|
| 183 | | #define STATUS_VERTICAL_RETRACE 0x40
|
| 184 | | #define STATUS_LIGHT_PEN_UPDATE 0x20
|
| 185 | | #define STATUS_ODD_EVEN 0x04
|
| 186 | | #define STATUS_FRAME_TIMER_OCCURRED 0x01
|
| 187 | | |
| 188 | | /***************************************************************************
|
| 189 | | TYPE DEFINITIONS
|
| 190 | | ***************************************************************************/
|
| 191 | | |
| 192 | | typedef struct _crt9007_t crt9007_t;
|
| 193 | | struct _crt9007_t
|
| 194 | | {
|
| 195 | | devcb_resolved_write_line out_int_func;
|
| 196 | | devcb_resolved_write_line out_dmar_func;
|
| 197 | | devcb_resolved_write_line out_hs_func;
|
| 198 | | devcb_resolved_write_line out_vs_func;
|
| 199 | | devcb_resolved_read8 in_vd_func;
|
| 200 | | |
| 201 | | crt9007_draw_scanline_func draw_scanline_func;
|
| 202 | | |
| 203 | | running_device *screen; /* screen */
|
| 204 | | |
| 205 | | /* registers */
|
| 206 | | UINT8 reg[0x3d];
|
| 207 | | UINT8 status;
|
| 208 | | |
| 209 | | int disp;
|
| 210 | | int hpixels_per_column;
|
| 211 | | |
| 212 | | /* runtime variables, do not state save */
|
| 213 | | int vsync_start;
|
| 214 | | int vsync_end;
|
| 215 | | int vfp;
|
| 216 | | int hsync_start;
|
| 217 | | int hsync_end;
|
| 218 | | int hfp;
|
| 219 | | |
| 220 | | /* timers */
|
| 221 | | emu_timer *vsync_timer; /* vertical sync timer */
|
| 222 | | emu_timer *hsync_timer; /* horizontal sync timer */
|
| 223 | | };
|
| 224 | | |
| 225 | | /***************************************************************************
|
| 226 | | INLINE FUNCTIONS
|
| 227 | | ***************************************************************************/
|
| 228 | | |
| 229 | | INLINE crt9007_t *get_safe_token(running_device *device)
|
| 230 | | {
|
| 231 | | assert(device != NULL);
|
| 232 | | assert(device->token != NULL);
|
| 233 | | return (crt9007_t *)device->token;
|
| 234 | | }
|
| 235 | | |
| 236 | | INLINE const crt9007_interface *get_interface(running_device *device)
|
| 237 | | {
|
| 238 | | assert(device != NULL);
|
| 239 | | assert(device->type == CRT9007);
|
| 240 | | return (const crt9007_interface *) device->baseconfig().static_config;
|
| 241 | | }
|
| 242 | | |
| 243 | | /***************************************************************************
|
| 244 | | IMPLEMENTATION
|
| 245 | | ***************************************************************************/
|
| 246 | | |
| 247 | | /*-------------------------------------------------
|
| 248 | | update_vsync_timer -
|
| 249 | | -------------------------------------------------*/
|
| 250 | | |
| 251 | | static void update_vsync_timer(crt9007_t *crt9007, int state)
|
| 252 | | {
|
| 253 | | int next_y = state ? crt9007->vsync_start : crt9007->vsync_end;
|
| 254 | | |
| 255 | | attotime duration = video_screen_get_time_until_pos(crt9007->screen, next_y, 0);
|
| 256 | | |
| 257 | | timer_adjust_oneshot(crt9007->vsync_timer, duration, !state);
|
| 258 | | }
|
| 259 | | |
| 260 | | /*-------------------------------------------------
|
| 261 | | TIMER_CALLBACK( vsync_tick )
|
| 262 | | -------------------------------------------------*/
|
| 263 | | |
| 264 | | static TIMER_CALLBACK( vsync_tick )
|
| 265 | | {
|
| 266 | | running_device *device = (running_device *)ptr;
|
| 267 | | crt9007_t *crt9007 = get_safe_token(device);
|
| 268 | | |
| 269 | | devcb_call_write_line(&crt9007->out_vs_func, param);
|
| 270 | | |
| 271 | | update_vsync_timer(crt9007, param);
|
| 272 | | }
|
| 273 | | |
| 274 | | /*-------------------------------------------------
|
| 275 | | update_hsync_timer -
|
| 276 | | -------------------------------------------------*/
|
| 277 | | |
| 278 | | static void update_hsync_timer(crt9007_t *crt9007, int state)
|
| 279 | | {
|
| 280 | | int y = video_screen_get_vpos(crt9007->screen);
|
| 281 | | |
| 282 | | int next_x = state ? crt9007->hsync_start : crt9007->hsync_end;
|
| 283 | | int next_y = (y + 1) % SCAN_LINES_PER_FRAME;
|
| 284 | | |
| 285 | | attotime duration = video_screen_get_time_until_pos(crt9007->screen, next_y, next_x);
|
| 286 | | |
| 287 | | timer_adjust_oneshot(crt9007->hsync_timer, duration, !state);
|
| 288 | | }
|
| 289 | | |
| 290 | | /*-------------------------------------------------
|
| 291 | | TIMER_CALLBACK( hsync_tick )
|
| 292 | | -------------------------------------------------*/
|
| 293 | | |
| 294 | | static TIMER_CALLBACK( hsync_tick )
|
| 295 | | {
|
| 296 | | running_device *device = (running_device *)ptr;
|
| 297 | | crt9007_t *crt9007 = get_safe_token(device);
|
| 298 | | |
| 299 | | devcb_call_write_line(&crt9007->out_hs_func, param);
|
| 300 | | |
| 301 | | update_hsync_timer(crt9007, param);
|
| 302 | | }
|
| 303 | | |
| 304 | | /*-------------------------------------------------
|
| 305 | | recompute_parameters -
|
| 306 | | -------------------------------------------------*/
|
| 307 | | |
| 308 | | static void recompute_parameters(running_device *device)
|
| 309 | | {
|
| 310 | | crt9007_t *crt9007 = get_safe_token(device);
|
| 311 | |
|
| 312 | | /* check that necessary registers have been loaded */
|
| 313 | | if (!HAS_VALID_PARAMETERS) return;
|
| 314 | | |
| 315 | | int horiz_pix_total = CHARACTERS_PER_HORIZONTAL_PERIOD * crt9007->hpixels_per_column;
|
| 316 | | int vert_pix_total = SCAN_LINES_PER_FRAME;
|
| 317 | | |
| 318 | | attoseconds_t refresh = HZ_TO_ATTOSECONDS(device->clock) * horiz_pix_total * vert_pix_total;
|
| 319 | | |
| 320 | | crt9007->hsync_start = (CHARACTERS_PER_HORIZONTAL_PERIOD - HORIZONTAL_SYNC_WIDTH) * crt9007->hpixels_per_column;
|
| 321 | | crt9007->hsync_end = 0;
|
| 322 | | crt9007->hfp = (HORIZONTAL_DELAY - HORIZONTAL_SYNC_WIDTH) * crt9007->hpixels_per_column;
|
| 323 | | |
| 324 | | crt9007->vsync_start = SCAN_LINES_PER_FRAME - VERTICAL_SYNC_WIDTH;
|
| 325 | | crt9007->vsync_end = 0;
|
| 326 | | crt9007->vfp = VERTICAL_DELAY - VERTICAL_SYNC_WIDTH;
|
| 327 | | |
| 328 | | rectangle visarea;
|
| 329 | | |
| 330 | | visarea.min_x = crt9007->hsync_end;
|
| 331 | | visarea.max_x = crt9007->hsync_start - 1;
|
| 332 | | |
| 333 | | visarea.min_y = crt9007->vsync_end;
|
| 334 | | visarea.max_y = crt9007->vsync_start - 1;
|
| 335 | | |
| 336 | | if (LOG)
|
| 337 | | {
|
| 338 | | logerror("CRT9007 '%s' Screen: %u x %u @ %f Hz\n", device->tag(), horiz_pix_total, vert_pix_total, 1 / ATTOSECONDS_TO_DOUBLE(refresh));
|
| 339 | | logerror("CRT9007 '%s' Visible Area: (%u, %u) - (%u, %u)\n", device->tag(), visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y);
|
| 340 | | }
|
| 341 | | |
| 342 | | video_screen_configure(crt9007->screen, horiz_pix_total, vert_pix_total, &visarea, refresh);
|
| 343 | | |
| 344 | | update_hsync_timer(crt9007, 1);
|
| 345 | | update_vsync_timer(crt9007, 1);
|
| 346 | | }
|
| 347 | | |
| 348 | | /*-------------------------------------------------
|
| 349 | | crt9007_r - register read
|
| 350 | | -------------------------------------------------*/
|
| 351 | | |
| 352 | | READ8_DEVICE_HANDLER( crt9007_r )
|
| 353 | | {
|
| 354 | | crt9007_t *crt9007 = get_safe_token(device);
|
| 355 | | |
| 356 | | UINT8 data = 0;
|
| 357 | | |
| 358 | | switch (offset)
|
| 359 | | {
|
| 360 | | case 0x15:
|
| 361 | | crt9007->disp = 1;
|
| 362 | | if (LOG) logerror("CRT9007 '%s' Start\n", device->tag());
|
| 363 | | break;
|
| 364 | | |
| 365 | | case 0x16:
|
| 366 | | crt9007->disp = 0;
|
| 367 | | if (LOG) logerror("CRT9007 '%s' Reset\n", device->tag());
|
| 368 | | break;
|
| 369 | | |
| 370 | | case 0x38:
|
| 371 | | data = VERTICAL_CURSOR;
|
| 372 | | break;
|
| 373 | | |
| 374 | | case 0x39:
|
| 375 | | data = HORIZONTAL_CURSOR;
|
| 376 | | break;
|
| 377 | | |
| 378 | | case 0x3a:
|
| 379 | | data = crt9007->status;
|
| 380 | | break;
|
| 381 | | |
| 382 | | case 0x3b:
|
| 383 | | data = VERTICAL_LIGHT_PEN;
|
| 384 | | break;
|
| 385 | | |
| 386 | | case 0x3c:
|
| 387 | | data = HORIZONTAL_LIGHT_PEN;
|
| 388 | | break;
|
| 389 | | |
| 390 | | default:
|
| 391 | | logerror("CRT9007 '%s' Read from Invalid Register: %02x!\n", device->tag(), offset);
|
| 392 | | }
|
| 393 | | |
| 394 | | return data;
|
| 395 | | }
|
| 396 | | |
| 397 | | /*-------------------------------------------------
|
| 398 | | crt9007_w - register write
|
| 399 | | -------------------------------------------------*/
|
| 400 | | |
| 401 | | WRITE8_DEVICE_HANDLER( crt9007_w )
|
| 402 | | {
|
| 403 | | crt9007_t *crt9007 = get_safe_token(device);
|
| 404 | | |
| 405 | | crt9007->reg[offset] = data;
|
| 406 | | |
| 407 | | switch (offset)
|
| 408 | | {
|
| 409 | | case 0x00:
|
| 410 | | recompute_parameters(device);
|
| 411 | | if (LOG) logerror("CRT9007 '%s' Characters per Horizontal Period: %u\n", device->tag(), CHARACTERS_PER_HORIZONTAL_PERIOD);
|
| 412 | | break;
|
| 413 | |
|
| 414 | | case 0x01:
|
| 415 | | recompute_parameters(device);
|
| 416 | | if (LOG) logerror("CRT9007 '%s' Characters per Data Row: %u\n", device->tag(), CHARACTERS_PER_DATA_ROW);
|
| 417 | | break;
|
| 418 | | |
| 419 | | case 0x02:
|
| 420 | | recompute_parameters(device);
|
| 421 | | if (LOG) logerror("CRT9007 '%s' Horizontal Delay: %u\n", device->tag(), HORIZONTAL_DELAY);
|
| 422 | | break;
|
| 423 | | |
| 424 | | case 0x03:
|
| 425 | | recompute_parameters(device);
|
| 426 | | if (LOG) logerror("CRT9007 '%s' Horizontal Sync Width: %u\n", device->tag(), HORIZONTAL_SYNC_WIDTH);
|
| 427 | | break;
|
| 428 | | |
| 429 | | case 0x04:
|
| 430 | | recompute_parameters(device);
|
| 431 | | if (LOG) logerror("CRT9007 '%s' Vertical Sync Width: %u\n", device->tag(), VERTICAL_SYNC_WIDTH);
|
| 432 | | break;
|
| 433 | | |
| 434 | | case 0x05:
|
| 435 | | recompute_parameters(device);
|
| 436 | | if (LOG) logerror("CRT9007 '%s' Vertical Delay: %u\n", device->tag(), VERTICAL_DELAY);
|
| 437 | | break;
|
| 438 | | |
| 439 | | case 0x06:
|
| 440 | | recompute_parameters(device);
|
| 441 | | if (LOG) |
| 442 | | {
|
| 443 | | logerror("CRT9007 '%s' Pin Configuration: %u\n", device->tag(), PIN_CONFIGURATION);
|
| 444 | | logerror("CRT9007 '%s' Cursor Skew: %u\n", device->tag(), CURSOR_SKEW);
|
| 445 | | logerror("CRT9007 '%s' Blank Skew: %u\n", device->tag(), BLANK_SKEW);
|
| 446 | | }
|
| 447 | | break;
|
| 448 | | |
| 449 | | case 0x07:
|
| 450 | | recompute_parameters(device);
|
| 451 | | if (LOG) logerror("CRT9007 '%s' Visible Data Rows per Frame: %u\n", device->tag(), VISIBLE_DATA_ROWS_PER_FRAME);
|
| 452 | | break;
|
| 453 | | |
| 454 | | case 0x08:
|
| 455 | | recompute_parameters(device);
|
| 456 | | if (LOG) logerror("CRT9007 '%s' Scan Lines per Data Row: %u\n", device->tag(), SCAN_LINES_PER_DATA_ROW);
|
| 457 | | break;
|
| 458 | | |
| 459 | | case 0x09:
|
| 460 | | recompute_parameters(device);
|
| 461 | | if (LOG) logerror("CRT9007 '%s' Scan Lines per Frame: %u\n", device->tag(), SCAN_LINES_PER_FRAME);
|
| 462 | | break;
|
| 463 | | |
| 464 | | case 0x0a:
|
| 465 | | if (LOG)
|
| 466 | | {
|
| 467 | | logerror("CRT9007 '%s' DMA Burst Count: %u\n", device->tag(), DMA_BURST_COUNT);
|
| 468 | | logerror("CRT9007 '%s' DMA Burst Delay: %u\n", device->tag(), DMA_BURST_DELAY);
|
| 469 | | logerror("CRT9007 '%s' DMA Disable: %u\n", device->tag(), DMA_DISABLE);
|
| 470 | | }
|
| 471 | | break;
|
| 472 | | |
| 473 | | case 0x0b:
|
| 474 | | if (LOG)
|
| 475 | | {
|
| 476 | | logerror("CRT9007 '%s' %s Height Cursor\n", device->tag(), SINGLE_HEIGHT_CURSOR ? "Single" : "Double");
|
| 477 | | logerror("CRT9007 '%s' Operation Mode: %u\n", device->tag(), OPERATION_MODE);
|
| 478 | | logerror("CRT9007 '%s' Interlace Mode: %u\n", device->tag(), INTERLACE_MODE);
|
| 479 | | logerror("CRT9007 '%s' %s Mechanism\n", device->tag(), PAGE_BLANK ? "Page Blank" : "Smooth Scroll");
|
| 480 | | }
|
| 481 | | break;
|
| 482 | | |
| 483 | | case 0x0c:
|
| 484 | | break;
|
| 485 | | |
| 486 | | case 0x0d:
|
| 487 | | if (LOG)
|
| 488 | | {
|
| 489 | | logerror("CRT9007 '%s' Table Start Register: %04x\n", device->tag(), TABLE_START);
|
| 490 | | logerror("CRT9007 '%s' Address Mode: %u\n", device->tag(), ADDRESS_MODE);
|
| 491 | | }
|
| 492 | | break;
|
| 493 | | |
| 494 | | case 0x0e:
|
| 495 | | break;
|
| 496 | | |
| 497 | | case 0x0f:
|
| 498 | | if (LOG)
|
| 499 | | {
|
| 500 | | logerror("CRT9007 '%s' Auxialiary Address Register 1: %04x\n", device->tag(), AUXILIARY_ADDRESS_1);
|
| 501 | | logerror("CRT9007 '%s' Row Attributes: %u\n", device->tag(), ROW_ATTRIBUTES_1);
|
| 502 | | }
|
| 503 | | break;
|
| 504 | | |
| 505 | | case 0x10:
|
| 506 | | if (LOG) logerror("CRT9007 '%s' Sequential Break Register 1: %u\n", device->tag(), SEQUENTIAL_BREAK_1);
|
| 507 | | break;
|
| 508 | | |
| 509 | | case 0x11:
|
| 510 | | if (LOG) logerror("CRT9007 '%s' Data Row Start Register: %u\n", device->tag(), DATA_ROW_START);
|
| 511 | | break;
|
| 512 | | |
| 513 | | case 0x12:
|
| 514 | | if (LOG) logerror("CRT9007 '%s' Data Row End/Sequential Break Register 2: %u\n", device->tag(), SEQUENTIAL_BREAK_2);
|
| 515 | | break;
|
| 516 | | |
| 517 | | case 0x13:
|
| 518 | | break;
|
| 519 | | |
| 520 | | case 0x14:
|
| 521 | | if (LOG)
|
| 522 | | {
|
| 523 | | logerror("CRT9007 '%s' Auxiliary Address Register 2: %04x\n", device->tag(), AUXILIARY_ADDRESS_2);
|
| 524 | | logerror("CRT9007 '%s' Row Attributes: %u\n", device->tag(), ROW_ATTRIBUTES_2);
|
| 525 | | }
|
| 526 | | break;
|
| 527 | | |
| 528 | | case 0x15:
|
| 529 | | crt9007->disp = 1;
|
| 530 | | if (LOG) logerror("CRT9007 '%s' Start\n", device->tag());
|
| 531 | | break;
|
| 532 | | |
| 533 | | case 0x16:
|
| 534 | | crt9007->disp = 0;
|
| 535 | | if (LOG) logerror("CRT9007 '%s' Reset\n", device->tag());
|
| 536 | | break;
|
| 537 | | |
| 538 | | case 0x17:
|
| 539 | | if (LOG)
|
| 540 | | {
|
| 541 | | logerror("CRT9007 '%s' Smooth Scroll Offset: %u\n", device->tag(), SMOOTH_SCROLL_OFFSET);
|
| 542 | | logerror("CRT9007 '%s' Smooth Scroll Offset Overflow: %u\n", device->tag(), SMOOTH_SCROLL_OFFSET_OVERFLOW);
|
| 543 | | }
|
| 544 | | break;
|
| 545 | | |
| 546 | | case 0x18:
|
| 547 | | if (LOG) logerror("CRT9007 '%s' Vertical Cursor Register: %u\n", device->tag(), VERTICAL_CURSOR);
|
| 548 | | break;
|
| 549 | | |
| 550 | | case 0x19:
|
| 551 | | if (LOG) logerror("CRT9007 '%s' Horizontal Cursor Register: %u\n", device->tag(), HORIZONTAL_CURSOR);
|
| 552 | | break;
|
| 553 | | |
| 554 | | case 0x1a:
|
| 555 | | if (LOG)
|
| 556 | | {
|
| 557 | | logerror("CRT9007 '%s' Frame Timer: %u\n", device->tag(), FRAME_TIMER);
|
| 558 | | logerror("CRT9007 '%s' Light Pen Interrupt: %u\n", device->tag(), LIGHT_PEN_INTERRUPT);
|
| 559 | | logerror("CRT9007 '%s' Vertical Retrace Interrupt: %u\n", device->tag(), VERTICAL_RETRACE_INTERRUPT);
|
| 560 | | }
|
| 561 | | break;
|
| 562 | | |
| 563 | | default:
|
| 564 | | logerror("CRT9007 '%s' Write to Invalid Register: %02x!\n", device->tag(), offset);
|
| 565 | | }
|
| 566 | | }
|
| 567 | | |
| 568 | | /*-------------------------------------------------
|
| 569 | | crt9007_ack_w - DMA acknowledge
|
| 570 | | -------------------------------------------------*/
|
| 571 | | |
| 572 | | WRITE8_DEVICE_HANDLER( crt9007_ack_w )
|
| 573 | | {
|
| 574 | | }
|
| 575 | | |
| 576 | | /*-------------------------------------------------
|
| 577 | | crt9007_lpstb_w - light pen strobe
|
| 578 | | -------------------------------------------------*/
|
| 579 | | |
| 580 | | WRITE_LINE_DEVICE_HANDLER( crt9007_lpstb_w )
|
| 581 | | {
|
| 582 | | }
|
| 583 | | |
| 584 | | /*-------------------------------------------------
|
| 585 | | crt9007_set_clock - set device clock
|
| 586 | | -------------------------------------------------*/
|
| 587 | | |
| 588 | | void crt9007_set_clock(running_device *device, UINT32 clock)
|
| 589 | | {
|
| 590 | | device->set_clock(clock);
|
| 591 | | recompute_parameters(device);
|
| 592 | | }
|
| 593 | | |
| 594 | | /*-------------------------------------------------
|
| 595 | | crt9007_set_hpixels_per_column
|
| 596 | | -------------------------------------------------*/
|
| 597 | | |
| 598 | | void crt9007_set_hpixels_per_column(running_device *device, int hpixels_per_column)
|
| 599 | | {
|
| 600 | | crt9007_t *crt9007 = get_safe_token(device);
|
| 601 | | |
| 602 | | crt9007->hpixels_per_column = hpixels_per_column;
|
| 603 | | recompute_parameters(device);
|
| 604 | | }
|
| 605 | | |
| 606 | | /*-------------------------------------------------
|
| 607 | | crt9007_update - update screen
|
| 608 | | -------------------------------------------------*/
|
| 609 | | |
| 610 | | void crt9007_update(running_device *device, bitmap_t *bitmap, const rectangle *cliprect)
|
| 611 | | {
|
| 612 | | crt9007_t *crt9007 = get_safe_token(device);
|
| 613 | | |
| 614 | | if (crt9007->disp && HAS_VALID_PARAMETERS)
|
| 615 | | {
|
| 616 | | int min_y = crt9007->vfp;
|
| 617 | | int max_y = min_y + (VISIBLE_DATA_ROWS_PER_FRAME * SCAN_LINES_PER_DATA_ROW);
|
| 618 | | |
| 619 | | for (int y = min_y; y < max_y; y++)
|
| 620 | | {
|
| 621 | | int sl = (y - min_y) % SCAN_LINES_PER_DATA_ROW;
|
| 622 | | int sy = (y - min_y) / SCAN_LINES_PER_DATA_ROW;
|
| 623 | | int cursor_x = (sy == VERTICAL_CURSOR) ? HORIZONTAL_CURSOR : -1;
|
| 624 | | UINT16 addr = TABLE_START + (sy * CHARACTERS_PER_DATA_ROW);
|
| 625 | | // UINT8 data = devcb_call_read8(&crt9007->in_vd_func, addr);
|
| 626 | |
|
| 627 | | crt9007->draw_scanline_func(device, bitmap, cliprect, addr, sl, 0, y, crt9007->hfp, CHARACTERS_PER_DATA_ROW, cursor_x);
|
| 628 | | |
| 629 | | addr++;
|
| 630 | | }
|
| 631 | | }
|
| 632 | | else
|
| 633 | | {
|
| 634 | | bitmap_fill(bitmap, cliprect, get_black_pen(device->machine));
|
| 635 | | }
|
| 636 | | }
|
| 637 | | |
| 638 | | /*-------------------------------------------------
|
| 639 | | DEVICE_START( crt9007 )
|
| 640 | | -------------------------------------------------*/
|
| 641 | | |
| 642 | | static DEVICE_START( crt9007 )
|
| 643 | | {
|
| 644 | | crt9007_t *crt9007 = (crt9007_t *)device->token;
|
| 645 | | const crt9007_interface *intf = get_interface(device);
|
| 646 | | |
| 647 | | /* resolve callbacks */
|
| 648 | | devcb_resolve_write_line(&crt9007->out_int_func, &intf->out_int_func, device);
|
| 649 | | devcb_resolve_write_line(&crt9007->out_dmar_func, &intf->out_dmar_func, device);
|
| 650 | | devcb_resolve_write_line(&crt9007->out_hs_func, &intf->out_hs_func, device);
|
| 651 | | devcb_resolve_write_line(&crt9007->out_vs_func, &intf->out_vs_func, device);
|
| 652 | | devcb_resolve_read8(&crt9007->in_vd_func, &intf->in_vd_func, device);
|
| 653 | | |
| 654 | | crt9007->draw_scanline_func = intf->draw_scanline_func;
|
| 655 | | assert(crt9007->draw_scanline_func != NULL);
|
| 656 | | |
| 657 | | /* get the screen device */
|
| 658 | | crt9007->screen = devtag_get_device(device->machine, intf->screen_tag);
|
| 659 | | assert(crt9007->screen != NULL);
|
| 660 | | |
| 661 | | /* set horizontal pixels per column */
|
| 662 | | crt9007->hpixels_per_column = intf->hpixels_per_column;
|
| 663 | | |
| 664 | | /* create the timers */
|
| 665 | | crt9007->vsync_timer = timer_alloc(device->machine, vsync_tick, (void *)device);
|
| 666 | | crt9007->hsync_timer = timer_alloc(device->machine, hsync_tick, (void *)device);
|
| 667 | | |
| 668 | | /* register for state saving */
|
| 669 | | // state_save_register_device_item(device, 0, crt9007->);
|
| 670 | | }
|
| 671 | | |
| 672 | | /*-------------------------------------------------
|
| 673 | | DEVICE_RESET( crt9007 )
|
| 674 | | -------------------------------------------------*/
|
| 675 | | |
| 676 | | static DEVICE_RESET( crt9007 )
|
| 677 | | {
|
| 678 | | // crt9007_t *crt9007 = (crt9007_t *)device->token;
|
| 679 | | }
|
| 680 | | |
| 681 | | /*-------------------------------------------------
|
| 682 | | DEVICE_GET_INFO( crt9007 )
|
| 683 | | -------------------------------------------------*/
|
| 684 | | |
| 685 | | DEVICE_GET_INFO( crt9007 )
|
| 686 | | {
|
| 687 | | switch (state)
|
| 688 | | {
|
| 689 | | /* --- the following bits of info are returned as 64-bit signed integers --- */
|
| 690 | | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
| 691 | | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
|
| 692 | | case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(crt9007_t); break;
|
| 693 | | |
| 694 | | /* --- the following bits of info are returned as pointers to data or functions --- */
|
| 695 | | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(crt9007); break;
|
| 696 | | case DEVINFO_FCT_STOP: /* Nothing */ break;
|
| 697 | | case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(crt9007); break;
|
| 698 | | |
| 699 | | /* --- the following bits of info are returned as NULL-terminated strings --- */
|
| 700 | | case DEVINFO_STR_NAME: strcpy(info->s, "SMC CRT9007"); break;
|
| 701 | | case DEVINFO_STR_FAMILY: strcpy(info->s, "SMC CRT9007"); break;
|
| 702 | | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
|
| 703 | | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
| 704 | | case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MESS Team"); break;
|
| 705 | | }
|
| 706 | | }
|
| 1 | /********************************************************************** |
| 2 | |
| 3 | SMC CRT9007 CRT Video Processor and Controller (VPAC) emulation |
| 4 | |
| 5 | Copyright MESS Team. |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. |
| 7 | |
| 8 | **********************************************************************/ |
| 9 | |
| 10 | /* |
| 11 | |
| 12 | TODO: |
| 13 | |
| 14 | - interrupts |
| 15 | - status register |
| 16 | - reset |
| 17 | - DMA mode (currently forcing to non-DMA mode) |
| 18 | - cursor/blank skew |
| 19 | - sequential breaks |
| 20 | - interlaced mode |
| 21 | - smooth scroll |
| 22 | - page blank |
| 23 | - double height cursor |
| 24 | - row attributes |
| 25 | - pin configuration |
| 26 | - operation modes 0,4,7 |
| 27 | - address modes 1,2,3 |
| 28 | - light pen |
| 29 | - state saving |
| 30 | |
| 31 | */ |
| 32 | |
| 33 | #include "emu.h" |
| 34 | #include "crt9007.h" |
| 35 | |
| 36 | /*************************************************************************** |
| 37 | PARAMETERS |
| 38 | ***************************************************************************/ |
| 39 | |
| 40 | #define LOG 1 |
| 41 | |
| 42 | #define HAS_VALID_PARAMETERS \ |
| 43 | (crt9007->reg[0x00] && crt9007->reg[0x01] && crt9007->reg[0x07] && crt9007->reg[0x08] && crt9007->reg[0x09]) |
| 44 | |
| 45 | #define CHARACTERS_PER_HORIZONTAL_PERIOD \ |
| 46 | crt9007->reg[0x00] |
| 47 | |
| 48 | #define CHARACTERS_PER_DATA_ROW \ |
| 49 | (crt9007->reg[0x01] + 1) |
| 50 | |
| 51 | #define HORIZONTAL_DELAY \ |
| 52 | crt9007->reg[0x02] |
| 53 | |
| 54 | #define HORIZONTAL_SYNC_WIDTH \ |
| 55 | crt9007->reg[0x03] |
| 56 | |
| 57 | #define VERTICAL_SYNC_WIDTH \ |
| 58 | crt9007->reg[0x04] |
| 59 | |
| 60 | #define VERTICAL_DELAY \ |
| 61 | (crt9007->reg[0x05] - 1) |
| 62 | |
| 63 | #define PIN_CONFIGURATION \ |
| 64 | (crt9007->reg[0x06] >> 6) |
| 65 | |
| 66 | #define CURSOR_SKEW \ |
| 67 | ((crt9007->reg[0x06] >> 3) & 0x07) |
| 68 | |
| 69 | #define BLANK_SKEW \ |
| 70 | (crt9007->reg[0x06] & 0x07) |
| 71 | |
| 72 | #define VISIBLE_DATA_ROWS_PER_FRAME \ |
| 73 | (crt9007->reg[0x07] + 1) |
| 74 | |
| 75 | #define SCAN_LINES_PER_DATA_ROW \ |
| 76 | ((crt9007->reg[0x08] & 0x1f) + 1) |
| 77 | |
| 78 | #define SCAN_LINES_PER_FRAME \ |
| 79 | (((crt9007->reg[0x08] << 3) & 0x0700) | crt9007->reg[0x09]) |
| 80 | |
| 81 | #define DMA_BURST_COUNT \ |
| 82 | (crt9007->reg[0x0a] & 0x0f) |
| 83 | |
| 84 | #define DMA_BURST_DELAY \ |
| 85 | ((crt9007->reg[0x0a] >> 4) & 0x07) |
| 86 | |
| 87 | #define DMA_DISABLE \ |
| 88 | BIT(crt9007->reg[0x0a], 7) |
| 89 | |
| 90 | #define SINGLE_HEIGHT_CURSOR \ |
| 91 | BIT(crt9007->reg[0x0b], 0) |
| 92 | |
| 93 | #define OPERATION_MODE \ |
| 94 | ((crt9007->reg[0x0b] >> 1) & 0x07) |
| 95 | |
| 96 | #define INTERLACE_MODE \ |
| 97 | ((crt9007->reg[0x0b] >> 4) & 0x03) |
| 98 | |
| 99 | #define PAGE_BLANK \ |
| 100 | BIT(crt9007->reg[0x0b], 6) |
| 101 | |
| 102 | #define TABLE_START \ |
| 103 | (((crt9007->reg[0x0d] << 8) & 0x3f00) | crt9007->reg[0x0c]) |
| 104 | |
| 105 | #define ADDRESS_MODE \ |
| 106 | ((crt9007->reg[0x0d] >> 6) & 0x03) |
| 107 | |
| 108 | #define AUXILIARY_ADDRESS_1 \ |
| 109 | (((crt9007->reg[0x0f] << 8) & 0x3f00) | crt9007->reg[0x0e]) |
| 110 | |
| 111 | #define ROW_ATTRIBUTES_1 \ |
| 112 | ((crt9007->reg[0x0f] >> 6) & 0x03) |
| 113 | |
| 114 | #define SEQUENTIAL_BREAK_1 \ |
| 115 | crt9007->reg[0x10] |
| 116 | |
| 117 | #define SEQUENTIAL_BREAK_2 \ |
| 118 | crt9007->reg[0x12] |
| 119 | |
| 120 | #define DATA_ROW_START \ |
| 121 | crt9007->reg[0x11] |
| 122 | |
| 123 | #define DATA_ROW_END \ |
| 124 | crt9007->reg[0x12] |
| 125 | |
| 126 | #define AUXILIARY_ADDRESS_2 \ |
| 127 | (((crt9007->reg[0x14] << 8) & 0x3f00) | crt9007->reg[0x13]) |
| 128 | |
| 129 | #define ROW_ATTRIBUTES_2 \ |
| 130 | ((crt9007->reg[0x14] >> 6) & 0x03) |
| 131 | |
| 132 | #define SMOOTH_SCROLL_OFFSET \ |
| 133 | ((crt9007->reg[0x17] >> 1) & 0x3f) |
| 134 | |
| 135 | #define SMOOTH_SCROLL_OFFSET_OVERFLOW \ |
| 136 | BIT(crt9007->reg[0x17], 7) |
| 137 | |
| 138 | #define VERTICAL_CURSOR \ |
| 139 | crt9007->reg[0x18] |
| 140 | |
| 141 | #define HORIZONTAL_CURSOR \ |
| 142 | crt9007->reg[0x19] |
| 143 | |
| 144 | #define FRAME_TIMER \ |
| 145 | BIT(crt9007->reg[0x1a], 0) |
| 146 | |
| 147 | #define LIGHT_PEN_INTERRUPT \ |
| 148 | BIT(crt9007->reg[0x1a], 5) |
| 149 | |
| 150 | #define VERTICAL_RETRACE_INTERRUPT \ |
| 151 | BIT(crt9007->reg[0x1a], 6) |
| 152 | |
| 153 | #define VERTICAL_LIGHT_PEN \ |
| 154 | crt9007->reg[0x3b] |
| 155 | |
| 156 | #define HORIZONTAL_LIGHT_PEN \ |
| 157 | crt9007->reg[0x3c] |
| 158 | |
| 159 | enum |
| 160 | { |
| 161 | NON_INTERLACED = 0, |
| 162 | ENHANCED_VIDEO_INTERFACE, |
| 163 | NORMAL_VIDEO_INTERFACE, |
| 164 | }; |
| 165 | |
| 166 | enum |
| 167 | { |
| 168 | OPERATION_MODE_REPETITIVE_MEMORY_ADDRESSING = 0, |
| 169 | OPERATION_MODE_DOUBLE_ROW_BUFFER, |
| 170 | OPERATION_MODE_SINGLE_ROW_BUFFER = 4, |
| 171 | OPERATION_MODE_ATTRIBUTE_ASSEMBLE = 7 |
| 172 | }; |
| 173 | |
| 174 | enum |
| 175 | { |
| 176 | ADDRESS_MODE_SEQUENTIAL_ADDRESSING = 0, |
| 177 | ADDRESS_MODE_SEQUENTIAL_ROLL_ADDRESSING, |
| 178 | ADDRESS_MODE_CONTIGUOUS_ROW_TABLE, |
| 179 | ADDRESS_MODE_LINKED_LIST_ROW_TABLE |
| 180 | }; |
| 181 | |
| 182 | #define STATUS_INTERRUPT_PENDING 0x80 |
| 183 | #define STATUS_VERTICAL_RETRACE 0x40 |
| 184 | #define STATUS_LIGHT_PEN_UPDATE 0x20 |
| 185 | #define STATUS_ODD_EVEN 0x04 |
| 186 | #define STATUS_FRAME_TIMER_OCCURRED 0x01 |
| 187 | |
| 188 | /*************************************************************************** |
| 189 | TYPE DEFINITIONS |
| 190 | ***************************************************************************/ |
| 191 | |
| 192 | typedef struct _crt9007_t crt9007_t; |
| 193 | struct _crt9007_t |
| 194 | { |
| 195 | devcb_resolved_write_line out_int_func; |
| 196 | devcb_resolved_write_line out_dmar_func; |
| 197 | devcb_resolved_write_line out_hs_func; |
| 198 | devcb_resolved_write_line out_vs_func; |
| 199 | devcb_resolved_read8 in_vd_func; |
| 200 | |
| 201 | crt9007_draw_scanline_func draw_scanline_func; |
| 202 | |
| 203 | running_device *screen; /* screen */ |
| 204 | |
| 205 | /* registers */ |
| 206 | UINT8 reg[0x3d]; |
| 207 | UINT8 status; |
| 208 | |
| 209 | int disp; |
| 210 | int hpixels_per_column; |
| 211 | |
| 212 | /* runtime variables, do not state save */ |
| 213 | int vsync_start; |
| 214 | int vsync_end; |
| 215 | int vfp; |
| 216 | int hsync_start; |
| 217 | int hsync_end; |
| 218 | int hfp; |
| 219 | |
| 220 | /* timers */ |
| 221 | emu_timer *vsync_timer; /* vertical sync timer */ |
| 222 | emu_timer *hsync_timer; /* horizontal sync timer */ |
| 223 | }; |
| 224 | |
| 225 | /*************************************************************************** |
| 226 | INLINE FUNCTIONS |
| 227 | ***************************************************************************/ |
| 228 | |
| 229 | INLINE crt9007_t *get_safe_token(running_device *device) |
| 230 | { |
| 231 | assert(device != NULL); |
| 232 | assert(device->token != NULL); |
| 233 | return (crt9007_t *)device->token; |
| 234 | } |
| 235 | |
| 236 | INLINE const crt9007_interface *get_interface(running_device *device) |
| 237 | { |
| 238 | assert(device != NULL); |
| 239 | assert(device->type == CRT9007); |
| 240 | return (const crt9007_interface *) device->baseconfig().static_config; |
| 241 | } |
| 242 | |
| 243 | /*************************************************************************** |
| 244 | IMPLEMENTATION |
| 245 | ***************************************************************************/ |
| 246 | |
| 247 | /*------------------------------------------------- |
| 248 | update_vsync_timer - |
| 249 | -------------------------------------------------*/ |
| 250 | |
| 251 | static void update_vsync_timer(crt9007_t *crt9007, int state) |
| 252 | { |
| 253 | int next_y = state ? crt9007->vsync_start : crt9007->vsync_end; |
| 254 | |
| 255 | attotime duration = video_screen_get_time_until_pos(crt9007->screen, next_y, 0); |
| 256 | |
| 257 | timer_adjust_oneshot(crt9007->vsync_timer, duration, !state); |
| 258 | } |
| 259 | |
| 260 | /*------------------------------------------------- |
| 261 | TIMER_CALLBACK( vsync_tick ) |
| 262 | -------------------------------------------------*/ |
| 263 | |
| 264 | static TIMER_CALLBACK( vsync_tick ) |
| 265 | { |
| 266 | running_device *device = (running_device *)ptr; |
| 267 | crt9007_t *crt9007 = get_safe_token(device); |
| 268 | |
| 269 | devcb_call_write_line(&crt9007->out_vs_func, param); |
| 270 | |
| 271 | update_vsync_timer(crt9007, param); |
| 272 | } |
| 273 | |
| 274 | /*------------------------------------------------- |
| 275 | update_hsync_timer - |
| 276 | -------------------------------------------------*/ |
| 277 | |
| 278 | static void update_hsync_timer(crt9007_t *crt9007, int state) |
| 279 | { |
| 280 | int y = video_screen_get_vpos(crt9007->screen); |
| 281 | |
| 282 | int next_x = state ? crt9007->hsync_start : crt9007->hsync_end; |
| 283 | int next_y = (y + 1) % SCAN_LINES_PER_FRAME; |
| 284 | |
| 285 | attotime duration = video_screen_get_time_until_pos(crt9007->screen, next_y, next_x); |
| 286 | |
| 287 | timer_adjust_oneshot(crt9007->hsync_timer, duration, !state); |
| 288 | } |
| 289 | |
| 290 | /*------------------------------------------------- |
| 291 | TIMER_CALLBACK( hsync_tick ) |
| 292 | -------------------------------------------------*/ |
| 293 | |
| 294 | static TIMER_CALLBACK( hsync_tick ) |
| 295 | { |
| 296 | running_device *device = (running_device *)ptr; |
| 297 | crt9007_t *crt9007 = get_safe_token(device); |
| 298 | |
| 299 | devcb_call_write_line(&crt9007->out_hs_func, param); |
| 300 | |
| 301 | update_hsync_timer(crt9007, param); |
| 302 | } |
| 303 | |
| 304 | /*------------------------------------------------- |
| 305 | recompute_parameters - |
| 306 | -------------------------------------------------*/ |
| 307 | |
| 308 | static void recompute_parameters(running_device *device) |
| 309 | { |
| 310 | crt9007_t *crt9007 = get_safe_token(device); |
| 311 | |
| 312 | /* check that necessary registers have been loaded */ |
| 313 | if (!HAS_VALID_PARAMETERS) return; |
| 314 | |
| 315 | int horiz_pix_total = CHARACTERS_PER_HORIZONTAL_PERIOD * crt9007->hpixels_per_column; |
| 316 | int vert_pix_total = SCAN_LINES_PER_FRAME; |
| 317 | |
| 318 | attoseconds_t refresh = HZ_TO_ATTOSECONDS(device->clock) * horiz_pix_total * vert_pix_total; |
| 319 | |
| 320 | crt9007->hsync_start = (CHARACTERS_PER_HORIZONTAL_PERIOD - HORIZONTAL_SYNC_WIDTH) * crt9007->hpixels_per_column; |
| 321 | crt9007->hsync_end = 0; |
| 322 | crt9007->hfp = (HORIZONTAL_DELAY - HORIZONTAL_SYNC_WIDTH) * crt9007->hpixels_per_column; |
| 323 | |
| 324 | crt9007->vsync_start = SCAN_LINES_PER_FRAME - VERTICAL_SYNC_WIDTH; |
| 325 | crt9007->vsync_end = 0; |
| 326 | crt9007->vfp = VERTICAL_DELAY - VERTICAL_SYNC_WIDTH; |
| 327 | |
| 328 | rectangle visarea; |
| 329 | |
| 330 | visarea.min_x = crt9007->hsync_end; |
| 331 | visarea.max_x = crt9007->hsync_start - 1; |
| 332 | |
| 333 | visarea.min_y = crt9007->vsync_end; |
| 334 | visarea.max_y = crt9007->vsync_start - 1; |
| 335 | |
| 336 | if (LOG) |
| 337 | { |
| 338 | logerror("CRT9007 '%s' Screen: %u x %u @ %f Hz\n", device->tag(), horiz_pix_total, vert_pix_total, 1 / ATTOSECONDS_TO_DOUBLE(refresh)); |
| 339 | logerror("CRT9007 '%s' Visible Area: (%u, %u) - (%u, %u)\n", device->tag(), visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y); |
| 340 | } |
| 341 | |
| 342 | video_screen_configure(crt9007->screen, horiz_pix_total, vert_pix_total, &visarea, refresh); |
| 343 | |
| 344 | update_hsync_timer(crt9007, 1); |
| 345 | update_vsync_timer(crt9007, 1); |
| 346 | } |
| 347 | |
| 348 | /*------------------------------------------------- |
| 349 | crt9007_r - register read |
| 350 | -------------------------------------------------*/ |
| 351 | |
| 352 | READ8_DEVICE_HANDLER( crt9007_r ) |
| 353 | { |
| 354 | crt9007_t *crt9007 = get_safe_token(device); |
| 355 | |
| 356 | UINT8 data = 0; |
| 357 | |
| 358 | switch (offset) |
| 359 | { |
| 360 | case 0x15: |
| 361 | crt9007->disp = 1; |
| 362 | if (LOG) logerror("CRT9007 '%s' Start\n", device->tag()); |
| 363 | break; |
| 364 | |
| 365 | case 0x16: |
| 366 | crt9007->disp = 0; |
| 367 | if (LOG) logerror("CRT9007 '%s' Reset\n", device->tag()); |
| 368 | break; |
| 369 | |
| 370 | case 0x38: |
| 371 | data = VERTICAL_CURSOR; |
| 372 | break; |
| 373 | |
| 374 | case 0x39: |
| 375 | data = HORIZONTAL_CURSOR; |
| 376 | break; |
| 377 | |
| 378 | case 0x3a: |
| 379 | data = crt9007->status; |
| 380 | break; |
| 381 | |
| 382 | case 0x3b: |
| 383 | data = VERTICAL_LIGHT_PEN; |
| 384 | break; |
| 385 | |
| 386 | case 0x3c: |
| 387 | data = HORIZONTAL_LIGHT_PEN; |
| 388 | break; |
| 389 | |
| 390 | default: |
| 391 | logerror("CRT9007 '%s' Read from Invalid Register: %02x!\n", device->tag(), offset); |
| 392 | } |
| 393 | |
| 394 | return data; |
| 395 | } |
| 396 | |
| 397 | /*------------------------------------------------- |
| 398 | crt9007_w - register write |
| 399 | -------------------------------------------------*/ |
| 400 | |
| 401 | WRITE8_DEVICE_HANDLER( crt9007_w ) |
| 402 | { |
| 403 | crt9007_t *crt9007 = get_safe_token(device); |
| 404 | |
| 405 | crt9007->reg[offset] = data; |
| 406 | |
| 407 | switch (offset) |
| 408 | { |
| 409 | case 0x00: |
| 410 | recompute_parameters(device); |
| 411 | if (LOG) logerror("CRT9007 '%s' Characters per Horizontal Period: %u\n", device->tag(), CHARACTERS_PER_HORIZONTAL_PERIOD); |
| 412 | break; |
| 413 | |
| 414 | case 0x01: |
| 415 | recompute_parameters(device); |
| 416 | if (LOG) logerror("CRT9007 '%s' Characters per Data Row: %u\n", device->tag(), CHARACTERS_PER_DATA_ROW); |
| 417 | break; |
| 418 | |
| 419 | case 0x02: |
| 420 | recompute_parameters(device); |
| 421 | if (LOG) logerror("CRT9007 '%s' Horizontal Delay: %u\n", device->tag(), HORIZONTAL_DELAY); |
| 422 | break; |
| 423 | |
| 424 | case 0x03: |
| 425 | recompute_parameters(device); |
| 426 | if (LOG) logerror("CRT9007 '%s' Horizontal Sync Width: %u\n", device->tag(), HORIZONTAL_SYNC_WIDTH); |
| 427 | break; |
| 428 | |
| 429 | case 0x04: |
| 430 | recompute_parameters(device); |
| 431 | if (LOG) logerror("CRT9007 '%s' Vertical Sync Width: %u\n", device->tag(), VERTICAL_SYNC_WIDTH); |
| 432 | break; |
| 433 | |
| 434 | case 0x05: |
| 435 | recompute_parameters(device); |
| 436 | if (LOG) logerror("CRT9007 '%s' Vertical Delay: %u\n", device->tag(), VERTICAL_DELAY); |
| 437 | break; |
| 438 | |
| 439 | case 0x06: |
| 440 | recompute_parameters(device); |
| 441 | if (LOG) |
| 442 | { |
| 443 | logerror("CRT9007 '%s' Pin Configuration: %u\n", device->tag(), PIN_CONFIGURATION); |
| 444 | logerror("CRT9007 '%s' Cursor Skew: %u\n", device->tag(), CURSOR_SKEW); |
| 445 | logerror("CRT9007 '%s' Blank Skew: %u\n", device->tag(), BLANK_SKEW); |
| 446 | } |
| 447 | break; |
| 448 | |
| 449 | case 0x07: |
| 450 | recompute_parameters(device); |
| 451 | if (LOG) logerror("CRT9007 '%s' Visible Data Rows per Frame: %u\n", device->tag(), VISIBLE_DATA_ROWS_PER_FRAME); |
| 452 | break; |
| 453 | |
| 454 | case 0x08: |
| 455 | recompute_parameters(device); |
| 456 | if (LOG) logerror("CRT9007 '%s' Scan Lines per Data Row: %u\n", device->tag(), SCAN_LINES_PER_DATA_ROW); |
| 457 | break; |
| 458 | |
| 459 | case 0x09: |
| 460 | recompute_parameters(device); |
| 461 | if (LOG) logerror("CRT9007 '%s' Scan Lines per Frame: %u\n", device->tag(), SCAN_LINES_PER_FRAME); |
| 462 | break; |
| 463 | |
| 464 | case 0x0a: |
| 465 | if (LOG) |
| 466 | { |
| 467 | logerror("CRT9007 '%s' DMA Burst Count: %u\n", device->tag(), DMA_BURST_COUNT); |
| 468 | logerror("CRT9007 '%s' DMA Burst Delay: %u\n", device->tag(), DMA_BURST_DELAY); |
| 469 | logerror("CRT9007 '%s' DMA Disable: %u\n", device->tag(), DMA_DISABLE); |
| 470 | } |
| 471 | break; |
| 472 | |
| 473 | case 0x0b: |
| 474 | if (LOG) |
| 475 | { |
| 476 | logerror("CRT9007 '%s' %s Height Cursor\n", device->tag(), SINGLE_HEIGHT_CURSOR ? "Single" : "Double"); |
| 477 | logerror("CRT9007 '%s' Operation Mode: %u\n", device->tag(), OPERATION_MODE); |
| 478 | logerror("CRT9007 '%s' Interlace Mode: %u\n", device->tag(), INTERLACE_MODE); |
| 479 | logerror("CRT9007 '%s' %s Mechanism\n", device->tag(), PAGE_BLANK ? "Page Blank" : "Smooth Scroll"); |
| 480 | } |
| 481 | break; |
| 482 | |
| 483 | case 0x0c: |
| 484 | break; |
| 485 | |
| 486 | case 0x0d: |
| 487 | if (LOG) |
| 488 | { |
| 489 | logerror("CRT9007 '%s' Table Start Register: %04x\n", device->tag(), TABLE_START); |
| 490 | logerror("CRT9007 '%s' Address Mode: %u\n", device->tag(), ADDRESS_MODE); |
| 491 | } |
| 492 | break; |
| 493 | |
| 494 | case 0x0e: |
| 495 | break; |
| 496 | |
| 497 | case 0x0f: |
| 498 | if (LOG) |
| 499 | { |
| 500 | logerror("CRT9007 '%s' Auxialiary Address Register 1: %04x\n", device->tag(), AUXILIARY_ADDRESS_1); |
| 501 | logerror("CRT9007 '%s' Row Attributes: %u\n", device->tag(), ROW_ATTRIBUTES_1); |
| 502 | } |
| 503 | break; |
| 504 | |
| 505 | case 0x10: |
| 506 | if (LOG) logerror("CRT9007 '%s' Sequential Break Register 1: %u\n", device->tag(), SEQUENTIAL_BREAK_1); |
| 507 | break; |
| 508 | |
| 509 | case 0x11: |
| 510 | if (LOG) logerror("CRT9007 '%s' Data Row Start Register: %u\n", device->tag(), DATA_ROW_START); |
| 511 | break; |
| 512 | |
| 513 | case 0x12: |
| 514 | if (LOG) logerror("CRT9007 '%s' Data Row End/Sequential Break Register 2: %u\n", device->tag(), SEQUENTIAL_BREAK_2); |
| 515 | break; |
| 516 | |
| 517 | case 0x13: |
| 518 | break; |
| 519 | |
| 520 | case 0x14: |
| 521 | if (LOG) |
| 522 | { |
| 523 | logerror("CRT9007 '%s' Auxiliary Address Register 2: %04x\n", device->tag(), AUXILIARY_ADDRESS_2); |
| 524 | logerror("CRT9007 '%s' Row Attributes: %u\n", device->tag(), ROW_ATTRIBUTES_2); |
| 525 | } |
| 526 | break; |
| 527 | |
| 528 | case 0x15: |
| 529 | crt9007->disp = 1; |
| 530 | if (LOG) logerror("CRT9007 '%s' Start\n", device->tag()); |
| 531 | break; |
| 532 | |
| 533 | case 0x16: |
| 534 | crt9007->disp = 0; |
| 535 | if (LOG) logerror("CRT9007 '%s' Reset\n", device->tag()); |
| 536 | break; |
| 537 | |
| 538 | case 0x17: |
| 539 | if (LOG) |
| 540 | { |
| 541 | logerror("CRT9007 '%s' Smooth Scroll Offset: %u\n", device->tag(), SMOOTH_SCROLL_OFFSET); |
| 542 | logerror("CRT9007 '%s' Smooth Scroll Offset Overflow: %u\n", device->tag(), SMOOTH_SCROLL_OFFSET_OVERFLOW); |
| 543 | } |
| 544 | break; |
| 545 | |
| 546 | case 0x18: |
| 547 | if (LOG) logerror("CRT9007 '%s' Vertical Cursor Register: %u\n", device->tag(), VERTICAL_CURSOR); |
| 548 | break; |
| 549 | |
| 550 | case 0x19: |
| 551 | if (LOG) logerror("CRT9007 '%s' Horizontal Cursor Register: %u\n", device->tag(), HORIZONTAL_CURSOR); |
| 552 | break; |
| 553 | |
| 554 | case 0x1a: |
| 555 | if (LOG) |
| 556 | { |
| 557 | logerror("CRT9007 '%s' Frame Timer: %u\n", device->tag(), FRAME_TIMER); |
| 558 | logerror("CRT9007 '%s' Light Pen Interrupt: %u\n", device->tag(), LIGHT_PEN_INTERRUPT); |
| 559 | logerror("CRT9007 '%s' Vertical Retrace Interrupt: %u\n", device->tag(), VERTICAL_RETRACE_INTERRUPT); |
| 560 | } |
| 561 | break; |
| 562 | |
| 563 | default: |
| 564 | logerror("CRT9007 '%s' Write to Invalid Register: %02x!\n", device->tag(), offset); |
| 565 | } |
| 566 | } |
| 567 | |
| 568 | /*------------------------------------------------- |
| 569 | crt9007_ack_w - DMA acknowledge |
| 570 | -------------------------------------------------*/ |
| 571 | |
| 572 | WRITE8_DEVICE_HANDLER( crt9007_ack_w ) |
| 573 | { |
| 574 | } |
| 575 | |
| 576 | /*------------------------------------------------- |
| 577 | crt9007_lpstb_w - light pen strobe |
| 578 | -------------------------------------------------*/ |
| 579 | |
| 580 | WRITE_LINE_DEVICE_HANDLER( crt9007_lpstb_w ) |
| 581 | { |
| 582 | } |
| 583 | |
| 584 | /*------------------------------------------------- |
| 585 | crt9007_set_clock - set device clock |
| 586 | -------------------------------------------------*/ |
| 587 | |
| 588 | void crt9007_set_clock(running_device *device, UINT32 clock) |
| 589 | { |
| 590 | device->set_clock(clock); |
| 591 | recompute_parameters(device); |
| 592 | } |
| 593 | |
| 594 | /*------------------------------------------------- |
| 595 | crt9007_set_hpixels_per_column |
| 596 | -------------------------------------------------*/ |
| 597 | |
| 598 | void crt9007_set_hpixels_per_column(running_device *device, int hpixels_per_column) |
| 599 | { |
| 600 | crt9007_t *crt9007 = get_safe_token(device); |
| 601 | |
| 602 | crt9007->hpixels_per_column = hpixels_per_column; |
| 603 | recompute_parameters(device); |
| 604 | } |
| 605 | |
| 606 | /*------------------------------------------------- |
| 607 | crt9007_update - update screen |
| 608 | -------------------------------------------------*/ |
| 609 | |
| 610 | void crt9007_update(running_device *device, bitmap_t *bitmap, const rectangle *cliprect) |
| 611 | { |
| 612 | crt9007_t *crt9007 = get_safe_token(device); |
| 613 | |
| 614 | if (crt9007->disp && HAS_VALID_PARAMETERS) |
| 615 | { |
| 616 | int min_y = crt9007->vfp; |
| 617 | int max_y = min_y + (VISIBLE_DATA_ROWS_PER_FRAME * SCAN_LINES_PER_DATA_ROW); |
| 618 | |
| 619 | for (int y = min_y; y < max_y; y++) |
| 620 | { |
| 621 | int sl = (y - min_y) % SCAN_LINES_PER_DATA_ROW; |
| 622 | int sy = (y - min_y) / SCAN_LINES_PER_DATA_ROW; |
| 623 | int cursor_x = (sy == VERTICAL_CURSOR) ? HORIZONTAL_CURSOR : -1; |
| 624 | UINT16 addr = TABLE_START + (sy * CHARACTERS_PER_DATA_ROW); |
| 625 | // UINT8 data = devcb_call_read8(&crt9007->in_vd_func, addr); |
| 626 | |
| 627 | crt9007->draw_scanline_func(device, bitmap, cliprect, addr, sl, 0, y, crt9007->hfp, CHARACTERS_PER_DATA_ROW, cursor_x); |
| 628 | |
| 629 | addr++; |
| 630 | } |
| 631 | } |
| 632 | else |
| 633 | { |
| 634 | bitmap_fill(bitmap, cliprect, get_black_pen(device->machine)); |
| 635 | } |
| 636 | } |
| 637 | |
| 638 | /*------------------------------------------------- |
| 639 | DEVICE_START( crt9007 ) |
| 640 | -------------------------------------------------*/ |
| 641 | |
| 642 | static DEVICE_START( crt9007 ) |
| 643 | { |
| 644 | crt9007_t *crt9007 = (crt9007_t *)device->token; |
| 645 | const crt9007_interface *intf = get_interface(device); |
| 646 | |
| 647 | /* resolve callbacks */ |
| 648 | devcb_resolve_write_line(&crt9007->out_int_func, &intf->out_int_func, device); |
| 649 | devcb_resolve_write_line(&crt9007->out_dmar_func, &intf->out_dmar_func, device); |
| 650 | devcb_resolve_write_line(&crt9007->out_hs_func, &intf->out_hs_func, device); |
| 651 | devcb_resolve_write_line(&crt9007->out_vs_func, &intf->out_vs_func, device); |
| 652 | devcb_resolve_read8(&crt9007->in_vd_func, &intf->in_vd_func, device); |
| 653 | |
| 654 | crt9007->draw_scanline_func = intf->draw_scanline_func; |
| 655 | assert(crt9007->draw_scanline_func != NULL); |
| 656 | |
| 657 | /* get the screen device */ |
| 658 | crt9007->screen = devtag_get_device(device->machine, intf->screen_tag); |
| 659 | assert(crt9007->screen != NULL); |
| 660 | |
| 661 | /* set horizontal pixels per column */ |
| 662 | crt9007->hpixels_per_column = intf->hpixels_per_column; |
| 663 | |
| 664 | /* create the timers */ |
| 665 | crt9007->vsync_timer = timer_alloc(device->machine, vsync_tick, (void *)device); |
| 666 | crt9007->hsync_timer = timer_alloc(device->machine, hsync_tick, (void *)device); |
| 667 | |
| 668 | /* register for state saving */ |
| 669 | // state_save_register_device_item(device, 0, crt9007->); |
| 670 | } |
| 671 | |
| 672 | /*------------------------------------------------- |
| 673 | DEVICE_RESET( crt9007 ) |
| 674 | -------------------------------------------------*/ |
| 675 | |
| 676 | static DEVICE_RESET( crt9007 ) |
| 677 | { |
| 678 | // crt9007_t *crt9007 = (crt9007_t *)device->token; |
| 679 | } |
| 680 | |
| 681 | /*------------------------------------------------- |
| 682 | DEVICE_GET_INFO( crt9007 ) |
| 683 | -------------------------------------------------*/ |
| 684 | |
| 685 | DEVICE_GET_INFO( crt9007 ) |
| 686 | { |
| 687 | switch (state) |
| 688 | { |
| 689 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 690 | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break; |
| 691 | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break; |
| 692 | case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(crt9007_t); break; |
| 693 | |
| 694 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 695 | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(crt9007); break; |
| 696 | case DEVINFO_FCT_STOP: /* Nothing */ break; |
| 697 | case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(crt9007); break; |
| 698 | |
| 699 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 700 | case DEVINFO_STR_NAME: strcpy(info->s, "SMC CRT9007"); break; |
| 701 | case DEVINFO_STR_FAMILY: strcpy(info->s, "SMC CRT9007"); break; |
| 702 | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; |
| 703 | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; |
| 704 | case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MESS Team"); break; |
| 705 | } |
| 706 | } |
src/mess/software/gx4000_cart.c
| r7571 | r7572 | |
| 1 | | /***************************************************************************
|
| 2 | | |
| 3 | | Amstrad GX4000 cartridges
|
| 4 | | |
| 5 | | ***************************************************************************/
|
| 6 | | |
| 7 | | #include "emu.h"
|
| 8 | | #include "softlist.h"
|
| 9 | | #include "devices/cartslot.h"
|
| 10 | | |
| 11 | | SOFTWARE_START( barb2 )
|
| 12 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 13 | | ROM_LOAD( "barb2.bin", 0x00000, 0x20000, CRC(8d5d8466) SHA1(8b8c966cf70bea3ef8264d3420fbf1ae13aad096) )
|
| 14 | | SOFTWARE_END
|
| 15 | | |
| 16 | | SOFTWARE_START( batman )
|
| 17 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 18 | | ROM_LOAD( "batman.bin", 0x00000, 0x20000, CRC(fed2468e) SHA1(644b7671a06a37a8d0aa49a3c2e4cfca30e3c9c1) )
|
| 19 | | SOFTWARE_END
|
| 20 | | |
| 21 | | SOFTWARE_START( brubber )
|
| 22 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 23 | | ROM_LOAD( "brubber.bin", 0x00000, 0x20000, CRC(bb0752e7) SHA1(a05975ebdba4845bb8c5097958f27a3428728f8d) )
|
| 24 | | SOFTWARE_END
|
| 25 | | |
| 26 | | SOFTWARE_START( cptr271 )
|
| 27 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 28 | | ROM_LOAD( "cptr271.bin", 0x00000, 0x20000, CRC(3f9d0682) SHA1(4b0a80aa83eaa89f109bad55ae4b067f698faaeb) )
|
| 29 | | SOFTWARE_END
|
| 30 | | |
| 31 | | SOFTWARE_START( crzycrs2 )
|
| 32 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 33 | | ROM_LOAD( "crzycrs2.bin", 0x00000, 0x20000, CRC(4bf81a5e) SHA1(8f48816b69c00a3c07a8ddae1f5de2d36a11e966) )
|
| 34 | | SOFTWARE_END
|
| 35 | | |
| 36 | | SOFTWARE_START( dicktrcy )
|
| 37 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 38 | | ROM_LOAD( "dicktrcy.bin", 0x00000, 0x20000, CRC(b5c29fd0) SHA1(2cf3f0140990548b2b3e7f5f7eaf9d7b6ae678af) )
|
| 39 | | SOFTWARE_END
|
| 40 | | |
| 41 | | SOFTWARE_START( fandf2 )
|
| 42 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 43 | | ROM_LOAD( "fandf2.bin", 0x00000, 0x20000, CRC(5a6329eb) SHA1(3bcd8fe1f519cb8b453d2957f844e84b1e4f28d4) )
|
| 44 | | SOFTWARE_END
|
| 45 | | |
| 46 | | SOFTWARE_START( klax )
|
| 47 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 48 | | ROM_LOAD( "klax.bin", 0x00000, 0x20000, CRC(94356097) SHA1(49b8a6cf1af1f801fb6109f65674427332005d30) )
|
| 49 | | SOFTWARE_END
|
| 50 | | |
| 51 | | SOFTWARE_START( mystical )
|
| 52 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 53 | | ROM_LOAD( "mystical.bin", 0x00000, 0x20000, CRC(b98b11f5) SHA1(9609c1948dfa84bc51f56d94f9667e6fefdfe145) )
|
| 54 | | SOFTWARE_END
|
| 55 | | |
| 56 | | SOFTWARE_START( nvyseals )
|
| 57 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 58 | | ROM_LOAD( "nvyseals.bin", 0x00000, 0x20000, CRC(92b77f03) SHA1(6aab7380067ad224c804793f4e575718ff582042) )
|
| 59 | | SOFTWARE_END
|
| 60 | | |
| 61 | | SOFTWARE_START( noexit )
|
| 62 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 63 | | ROM_LOAD( "noexit.bin", 0x00000, 0x20000, CRC(28f64ce1) SHA1(270844966810b91529d70f3c68f41e3986646659) )
|
| 64 | | SOFTWARE_END
|
| 65 | | |
| 66 | | SOFTWARE_START( optndblt )
|
| 67 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 68 | | ROM_LOAD( "optndblt.bin", 0x00000, 0x20000, CRC(9d5a4f42) SHA1(567a15d8a892a20ba3c0d3184a0b381b58f0c34c) )
|
| 69 | | SOFTWARE_END
|
| 70 | | |
| 71 | | SOFTWARE_START( pang )
|
| 72 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 73 | | ROM_LOAD( "pang.bin", 0x00000, 0x20000, CRC(b6a33a07) SHA1(128094fa2999d61466761232b25215e594ad509a) )
|
| 74 | | SOFTWARE_END
|
| 75 | | |
| 76 | | SOFTWARE_START( pkckbox )
|
| 77 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 78 | | ROM_LOAD( "pkckbox.bin", 0x00000, 0x20000, CRC(996c30ce) SHA1(1e1c65e075c8f3e73d83d42ffe81f1311748432c) )
|
| 79 | | SOFTWARE_END
|
| 80 | | |
| 81 | | SOFTWARE_START( pbmagic )
|
| 82 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 83 | | ROM_LOAD( "pbmagic.bin", 0x00000, 0x20000, CRC(e7500c93) SHA1(120f6b670682cedb0ca6cc8c25ad410423a3563f) )
|
| 84 | | SOFTWARE_END
|
| 85 | | |
| 86 | | SOFTWARE_START( pltting )
|
| 87 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 88 | | ROM_LOAD( "pltting.bin", 0x00000, 0x20000, CRC(f7a73aaa) SHA1(7163872123d61bf575d8a766d9b55ecca0901447) )
|
| 89 | | SOFTWARE_END
|
| 90 | | |
| 91 | | SOFTWARE_START( prtnnstr )
|
| 92 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 93 | | ROM_LOAD( "prtnnstr.bin", 0x00000, 0x20000, CRC(64d996f7) SHA1(1f9faefca86ed8089fe28f4a1836df106dbf4d12) )
|
| 94 | | SOFTWARE_END
|
| 95 | | |
| 96 | | SOFTWARE_START( robocop2 )
|
| 97 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 98 | | ROM_LOAD( "robocop2.bin", 0x00000, 0x20000, CRC(426bfabc) SHA1(5eb7e056a19cb69c45c3bc575c5ed196e7fbd1f5) )
|
| 99 | | SOFTWARE_END
|
| 100 | | |
| 101 | | SOFTWARE_START( sktshoot )
|
| 102 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 103 | | ROM_LOAD( "sktshoot.bin", 0x00000, 0x20000, CRC(24e7334d) SHA1(360f2a0538bdaf15c3a69bf8eb82dcb358fbe1d5) )
|
| 104 | | SOFTWARE_END
|
| 105 | | |
| 106 | | SOFTWARE_START( swtchbld )
|
| 107 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 108 | | ROM_LOAD( "swtchbld.bin", 0x00000, 0x20000, CRC(32ea852d) SHA1(ce7ab55a83a6003fe3e2b2a3a6f5b318da6f721d) )
|
| 109 | | SOFTWARE_END
|
| 110 | | |
| 111 | | SOFTWARE_START( tnnscup2 )
|
| 112 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 113 | | ROM_LOAD( "tnnscup2.bin", 0x00000, 0x20000, CRC(10e9d90f) SHA1(9fb694a09a09f84a6519c9e074ff49504a424ccb) )
|
| 114 | | SOFTWARE_END
|
| 115 | | |
| 116 | | SOFTWARE_START( enforcer )
|
| 117 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 118 | | ROM_LOAD( "enforcer.bin", 0x00000, 0x20000, CRC(69f813a7) SHA1(f188716e69c54c8ffed3b56f12aec3bcdb6eabce) )
|
| 119 | | SOFTWARE_END
|
| 120 | | |
| 121 | | SOFTWARE_START( tintin )
|
| 122 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 123 | | ROM_LOAD( "tintin.bin", 0x00000, 0x20000, CRC(72320df4) SHA1(3b3a1f870dff22fa0952f2da93e3dc90daef90cc) )
|
| 124 | | SOFTWARE_END
|
| 125 | | |
| 126 | | SOFTWARE_START( wildstrt )
|
| 127 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 128 | | ROM_LOAD( "wildstrt.bin", 0x00000, 0x20000, CRC(bcbae03b) SHA1(3ff09f19471d8bcd878583f74a553048068b6dff) )
|
| 129 | | SOFTWARE_END
|
| 130 | | |
| 131 | | SOFTWARE_START( wrldsprt )
|
| 132 | | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 )
|
| 133 | | ROM_LOAD( "wrldsprt.bin", 0x00000, 0x20000, CRC(5cecc439) SHA1(6bc5271370eb1ee92f809874f7ef346c2117f9cd) )
|
| 134 | | SOFTWARE_END
|
| 135 | | |
| 136 | | |
| 137 | | SOFTWARE_LIST_START( gx4000_cart )
|
| 138 | | SOFTWARE( barb2, 0, 1989, "Palace Software", "Barbarian II", 0, 0 )
|
| 139 | | SOFTWARE( batman, 0, 1989, "Ocean Software", "Batman", 0, 0 ) /* no controls */
|
| 140 | | SOFTWARE( brubber, 0, 1990, "Ocean Software", "Burnin' Rubber", 0, 0 )
|
| 141 | | SOFTWARE( cptr271, 0, 1991, "Loriciel Software", "Copter 271", 0, 0 )
|
| 142 | | SOFTWARE( crzycrs2, 0, 1990, "Titus Software", "Crazy Cars II", 0, 0 )
|
| 143 | | /* Chase HQ II */
|
| 144 | | SOFTWARE( dicktrcy, 0, 1990, "Titus Software", "Dick Tracy", 0, 0 )
|
| 145 | | /* Duck Tales */
|
| 146 | | SOFTWARE( fandf2, 0, 1990, "Titus Software", "Fire & Forget II", 0, 0 )
|
| 147 | | SOFTWARE( klax, 0, 1990, "Domark", "Klax", 0, 0 )
|
| 148 | | SOFTWARE( mystical, 0, 1990, "Infogrames", "Mystical", 0, 0 )
|
| 149 | | SOFTWARE( nvyseals, 0, 1990, "Ocean Software", "Navy Seals", 0, 0 )
|
| 150 | | SOFTWARE( noexit, 0, 1990, "CVS", "No Exit", 0, 0 ) /* doesn't boot */
|
| 151 | | SOFTWARE( optndblt, 0, 1990, "Ocean Software", "Operation Thunderbolt", 0, 0 ) /* doesn't boot */
|
| 152 | | SOFTWARE( pang, 0, 1990, "Ocean Software", "Pang", 0, 0 ) /* minor gfx glitch */
|
| 153 | | SOFTWARE( pkckbox, 0, 1991, "Loriciel Software", "Panza Kick Boxing", 0, 0 )
|
| 154 | | SOFTWARE( pbmagic, 0, 1991, "Loriciel Software", "Pinball Magic", 0, 0 ) /* glitched title screen */
|
| 155 | | SOFTWARE( pltting, 0, 1990, "Ocean Software", "Plotting", 0, 0 )
|
| 156 | | SOFTWARE( prtnnstr, 0, 1989, "Ubisoft", "Pro Tennis Tour", 0, 0 )
|
| 157 | | SOFTWARE( robocop2, 0, 1990, "Ocean Software", "Robocop 2", 0, 0 ) /* doesn't boot */
|
| 158 | | SOFTWARE( sktshoot, 0, 1990, "Trojan", "Skeet Shoot", 0, 0 ) /* needs light phazer */
|
| 159 | | SOFTWARE( swtchbld, 0, 1990, "Gremlin Graphics", "Switchblade", 0, 0 )
|
| 160 | | SOFTWARE( tnnscup2, 0, 1990, "Loriciel Software", "Tennis Cup II", 0, 0 )
|
| 161 | | SOFTWARE( enforcer, 0, 1990, "Trojan", "The Enforcer", 0, 0 ) /* needs light phazer */
|
| 162 | | SOFTWARE( tintin, 0, 1990, "Infogrames", "Tintin On The Moon", 0, 0 ) /* crashes at language select */
|
| 163 | | SOFTWARE( wildstrt, 0, 1990, "Titus Software", "Wild Streets", 0, 0 )
|
| 164 | | SOFTWARE( wrldsprt, 0, 1990, "EPYX", "World of Sports", 0, 0 ) /* glitched title screen */
|
| 165 | | SOFTWARE_LIST_END
|
| 166 | | |
| 167 | | |
| 168 | | SOFTWARE_LIST( gx4000_cart, "Amstrad GX4000 cartridges" )
|
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Amstrad GX4000 cartridges |
| 4 | |
| 5 | ***************************************************************************/ |
| 6 | |
| 7 | #include "emu.h" |
| 8 | #include "softlist.h" |
| 9 | #include "devices/cartslot.h" |
| 10 | |
| 11 | SOFTWARE_START( barb2 ) |
| 12 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 13 | ROM_LOAD( "barb2.bin", 0x00000, 0x20000, CRC(8d5d8466) SHA1(8b8c966cf70bea3ef8264d3420fbf1ae13aad096) ) |
| 14 | SOFTWARE_END |
| 15 | |
| 16 | SOFTWARE_START( batman ) |
| 17 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 18 | ROM_LOAD( "batman.bin", 0x00000, 0x20000, CRC(fed2468e) SHA1(644b7671a06a37a8d0aa49a3c2e4cfca30e3c9c1) ) |
| 19 | SOFTWARE_END |
| 20 | |
| 21 | SOFTWARE_START( brubber ) |
| 22 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 23 | ROM_LOAD( "brubber.bin", 0x00000, 0x20000, CRC(bb0752e7) SHA1(a05975ebdba4845bb8c5097958f27a3428728f8d) ) |
| 24 | SOFTWARE_END |
| 25 | |
| 26 | SOFTWARE_START( cptr271 ) |
| 27 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 28 | ROM_LOAD( "cptr271.bin", 0x00000, 0x20000, CRC(3f9d0682) SHA1(4b0a80aa83eaa89f109bad55ae4b067f698faaeb) ) |
| 29 | SOFTWARE_END |
| 30 | |
| 31 | SOFTWARE_START( crzycrs2 ) |
| 32 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 33 | ROM_LOAD( "crzycrs2.bin", 0x00000, 0x20000, CRC(4bf81a5e) SHA1(8f48816b69c00a3c07a8ddae1f5de2d36a11e966) ) |
| 34 | SOFTWARE_END |
| 35 | |
| 36 | SOFTWARE_START( dicktrcy ) |
| 37 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 38 | ROM_LOAD( "dicktrcy.bin", 0x00000, 0x20000, CRC(b5c29fd0) SHA1(2cf3f0140990548b2b3e7f5f7eaf9d7b6ae678af) ) |
| 39 | SOFTWARE_END |
| 40 | |
| 41 | SOFTWARE_START( fandf2 ) |
| 42 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 43 | ROM_LOAD( "fandf2.bin", 0x00000, 0x20000, CRC(5a6329eb) SHA1(3bcd8fe1f519cb8b453d2957f844e84b1e4f28d4) ) |
| 44 | SOFTWARE_END |
| 45 | |
| 46 | SOFTWARE_START( klax ) |
| 47 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 48 | ROM_LOAD( "klax.bin", 0x00000, 0x20000, CRC(94356097) SHA1(49b8a6cf1af1f801fb6109f65674427332005d30) ) |
| 49 | SOFTWARE_END |
| 50 | |
| 51 | SOFTWARE_START( mystical ) |
| 52 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 53 | ROM_LOAD( "mystical.bin", 0x00000, 0x20000, CRC(b98b11f5) SHA1(9609c1948dfa84bc51f56d94f9667e6fefdfe145) ) |
| 54 | SOFTWARE_END |
| 55 | |
| 56 | SOFTWARE_START( nvyseals ) |
| 57 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 58 | ROM_LOAD( "nvyseals.bin", 0x00000, 0x20000, CRC(92b77f03) SHA1(6aab7380067ad224c804793f4e575718ff582042) ) |
| 59 | SOFTWARE_END |
| 60 | |
| 61 | SOFTWARE_START( noexit ) |
| 62 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 63 | ROM_LOAD( "noexit.bin", 0x00000, 0x20000, CRC(28f64ce1) SHA1(270844966810b91529d70f3c68f41e3986646659) ) |
| 64 | SOFTWARE_END |
| 65 | |
| 66 | SOFTWARE_START( optndblt ) |
| 67 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 68 | ROM_LOAD( "optndblt.bin", 0x00000, 0x20000, CRC(9d5a4f42) SHA1(567a15d8a892a20ba3c0d3184a0b381b58f0c34c) ) |
| 69 | SOFTWARE_END |
| 70 | |
| 71 | SOFTWARE_START( pang ) |
| 72 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 73 | ROM_LOAD( "pang.bin", 0x00000, 0x20000, CRC(b6a33a07) SHA1(128094fa2999d61466761232b25215e594ad509a) ) |
| 74 | SOFTWARE_END |
| 75 | |
| 76 | SOFTWARE_START( pkckbox ) |
| 77 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 78 | ROM_LOAD( "pkckbox.bin", 0x00000, 0x20000, CRC(996c30ce) SHA1(1e1c65e075c8f3e73d83d42ffe81f1311748432c) ) |
| 79 | SOFTWARE_END |
| 80 | |
| 81 | SOFTWARE_START( pbmagic ) |
| 82 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 83 | ROM_LOAD( "pbmagic.bin", 0x00000, 0x20000, CRC(e7500c93) SHA1(120f6b670682cedb0ca6cc8c25ad410423a3563f) ) |
| 84 | SOFTWARE_END |
| 85 | |
| 86 | SOFTWARE_START( pltting ) |
| 87 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 88 | ROM_LOAD( "pltting.bin", 0x00000, 0x20000, CRC(f7a73aaa) SHA1(7163872123d61bf575d8a766d9b55ecca0901447) ) |
| 89 | SOFTWARE_END |
| 90 | |
| 91 | SOFTWARE_START( prtnnstr ) |
| 92 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 93 | ROM_LOAD( "prtnnstr.bin", 0x00000, 0x20000, CRC(64d996f7) SHA1(1f9faefca86ed8089fe28f4a1836df106dbf4d12) ) |
| 94 | SOFTWARE_END |
| 95 | |
| 96 | SOFTWARE_START( robocop2 ) |
| 97 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 98 | ROM_LOAD( "robocop2.bin", 0x00000, 0x20000, CRC(426bfabc) SHA1(5eb7e056a19cb69c45c3bc575c5ed196e7fbd1f5) ) |
| 99 | SOFTWARE_END |
| 100 | |
| 101 | SOFTWARE_START( sktshoot ) |
| 102 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 103 | ROM_LOAD( "sktshoot.bin", 0x00000, 0x20000, CRC(24e7334d) SHA1(360f2a0538bdaf15c3a69bf8eb82dcb358fbe1d5) ) |
| 104 | SOFTWARE_END |
| 105 | |
| 106 | SOFTWARE_START( swtchbld ) |
| 107 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 108 | ROM_LOAD( "swtchbld.bin", 0x00000, 0x20000, CRC(32ea852d) SHA1(ce7ab55a83a6003fe3e2b2a3a6f5b318da6f721d) ) |
| 109 | SOFTWARE_END |
| 110 | |
| 111 | SOFTWARE_START( tnnscup2 ) |
| 112 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 113 | ROM_LOAD( "tnnscup2.bin", 0x00000, 0x20000, CRC(10e9d90f) SHA1(9fb694a09a09f84a6519c9e074ff49504a424ccb) ) |
| 114 | SOFTWARE_END |
| 115 | |
| 116 | SOFTWARE_START( enforcer ) |
| 117 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 118 | ROM_LOAD( "enforcer.bin", 0x00000, 0x20000, CRC(69f813a7) SHA1(f188716e69c54c8ffed3b56f12aec3bcdb6eabce) ) |
| 119 | SOFTWARE_END |
| 120 | |
| 121 | SOFTWARE_START( tintin ) |
| 122 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 123 | ROM_LOAD( "tintin.bin", 0x00000, 0x20000, CRC(72320df4) SHA1(3b3a1f870dff22fa0952f2da93e3dc90daef90cc) ) |
| 124 | SOFTWARE_END |
| 125 | |
| 126 | SOFTWARE_START( wildstrt ) |
| 127 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 128 | ROM_LOAD( "wildstrt.bin", 0x00000, 0x20000, CRC(bcbae03b) SHA1(3ff09f19471d8bcd878583f74a553048068b6dff) ) |
| 129 | SOFTWARE_END |
| 130 | |
| 131 | SOFTWARE_START( wrldsprt ) |
| 132 | ROM_REGION( 0x20000, CARTRIDGE_REGION_ROM, 0 ) |
| 133 | ROM_LOAD( "wrldsprt.bin", 0x00000, 0x20000, CRC(5cecc439) SHA1(6bc5271370eb1ee92f809874f7ef346c2117f9cd) ) |
| 134 | SOFTWARE_END |
| 135 | |
| 136 | |
| 137 | SOFTWARE_LIST_START( gx4000_cart ) |
| 138 | SOFTWARE( barb2, 0, 1989, "Palace Software", "Barbarian II", 0, 0 ) |
| 139 | SOFTWARE( batman, 0, 1989, "Ocean Software", "Batman", 0, 0 ) /* no controls */ |
| 140 | SOFTWARE( brubber, 0, 1990, "Ocean Software", "Burnin' Rubber", 0, 0 ) |
| 141 | SOFTWARE( cptr271, 0, 1991, "Loriciel Software", "Copter 271", 0, 0 ) |
| 142 | SOFTWARE( crzycrs2, 0, 1990, "Titus Software", "Crazy Cars II", 0, 0 ) |
| 143 | /* Chase HQ II */ |
| 144 | SOFTWARE( dicktrcy, 0, 1990, "Titus Software", "Dick Tracy", 0, 0 ) |
| 145 | /* Duck Tales */ |
| 146 | SOFTWARE( fandf2, 0, 1990, "Titus Software", "Fire & Forget II", 0, 0 ) |
| 147 | SOFTWARE( klax, 0, 1990, "Domark", "Klax", 0, 0 ) |
| 148 | SOFTWARE( mystical, 0, 1990, "Infogrames", "Mystical", 0, 0 ) |
| 149 | SOFTWARE( nvyseals, 0, 1990, "Ocean Software", "Navy Seals", 0, 0 ) |
| 150 | SOFTWARE( noexit, 0, 1990, "CVS", "No Exit", 0, 0 ) /* doesn't boot */ |
| 151 | SOFTWARE( optndblt, 0, 1990, "Ocean Software", "Operation Thunderbolt", 0, 0 ) /* doesn't boot */ |
| 152 | SOFTWARE( pang, 0, 1990, "Ocean Software", "Pang", 0, 0 ) /* minor gfx glitch */ |
| 153 | SOFTWARE( pkckbox, 0, 1991, "Loriciel Software", "Panza Kick Boxing", 0, 0 ) |
| 154 | SOFTWARE( pbmagic, 0, 1991, "Loriciel Software", "Pinball Magic", 0, 0 ) /* glitched title screen */ |
| 155 | SOFTWARE( pltting, 0, 1990, "Ocean Software", "Plotting", 0, 0 ) |
| 156 | SOFTWARE( prtnnstr, 0, 1989, "Ubisoft", "Pro Tennis Tour", 0, 0 ) |
| 157 | SOFTWARE( robocop2, 0, 1990, "Ocean Software", "Robocop 2", 0, 0 ) /* doesn't boot */ |
| 158 | SOFTWARE( sktshoot, 0, 1990, "Trojan", "Skeet Shoot", 0, 0 ) /* needs light phazer */ |
| 159 | SOFTWARE( swtchbld, 0, 1990, "Gremlin Graphics", "Switchblade", 0, 0 ) |
| 160 | SOFTWARE( tnnscup2, 0, 1990, "Loriciel Software", "Tennis Cup II", 0, 0 ) |
| 161 | SOFTWARE( enforcer, 0, 1990, "Trojan", "The Enforcer", 0, 0 ) /* needs light phazer */ |
| 162 | SOFTWARE( tintin, 0, 1990, "Infogrames", "Tintin On The Moon", 0, 0 ) /* crashes at language select */ |
| 163 | SOFTWARE( wildstrt, 0, 1990, "Titus Software", "Wild Streets", 0, 0 ) |
| 164 | SOFTWARE( wrldsprt, 0, 1990, "EPYX", "World of Sports", 0, 0 ) /* glitched title screen */ |
| 165 | SOFTWARE_LIST_END |
| 166 | |
| 167 | |
| 168 | SOFTWARE_LIST( gx4000_cart, "Amstrad GX4000 cartridges" ) |
src/mess/software/arcadia_cart.c
| r7571 | r7572 | |
| 1 | | /***************************************************************************
|
| 2 | | |
| 3 | | Emerson Arcadia 2001 cartridges
|
| 4 | | |
| 5 | | ***************************************************************************/
|
| 6 | | |
| 7 | | #include "emu.h"
|
| 8 | | #include "softlist.h"
|
| 9 | | #include "devices/cartslot.h"
|
| 10 | | |
| 11 | | |
| 12 | | SOFTWARE_START( 3dbwling )
|
| 13 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 14 | | ROM_LOAD( "3dbwling.bin", 0x0000, 0x1000, CRC(f3c08e19) SHA1(edd33cabd3d600e9e3d3c22f326a065ea6ebe32c) )
|
| 15 | | SOFTWARE_END
|
| 16 | | |
| 17 | | SOFTWARE_START( 3dsoccer )
|
| 18 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 19 | | ROM_LOAD( "3dsoccer.bin", 0x0000, 0x2000, CRC(4da68df8) SHA1(50e799c96be3613f937825c6c722521bc6df0162) )
|
| 20 | | SOFTWARE_END
|
| 21 | | |
| 22 | | SOFTWARE_START( 3dsccera )
|
| 23 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 24 | | ROM_LOAD( "3dsccera.bin", 0x0000, 0x2000, CRC(1b5be22a) SHA1(d3df9ed4e09bacacde47fa4f1128383fd62ffd6e) )
|
| 25 | | SOFTWARE_END
|
| 26 | | |
| 27 | | SOFTWARE_START( alieninv )
|
| 28 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 29 | | ROM_LOAD( "alieninv.bin", 0x0000, 0x1000, CRC(1f65b21e) SHA1(8d17de81fbf70db8fe32830763c6a940aa9124c3) )
|
| 30 | | SOFTWARE_END
|
| 31 | | |
| 32 | | SOFTWARE_START( astroinv )
|
| 33 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 34 | | ROM_LOAD( "astroinv.bin", 0x0000, 0x1000, CRC(ddcf5b2c) SHA1(b6f693e3333607181fbe3a43dffa9f30f9656998) )
|
| 35 | | SOFTWARE_END
|
| 36 | | |
| 37 | | SOFTWARE_START( autorace )
|
| 38 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 39 | | ROM_LOAD( "autorace.bin", 0x0000, 0x1000, CRC(99ac48ca) SHA1(6182219b2b8c8747f67d627a056ac947754f0978) )
|
| 40 | | SOFTWARE_END
|
| 41 | | |
| 42 | | SOFTWARE_START( baseball )
|
| 43 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 44 | | ROM_LOAD( "baseball.bin", 0x0000, 0x1000, CRC(1cf08155) SHA1(f4d39aaab61e6b01c673166ae54841d450860b31) )
|
| 45 | | SOFTWARE_END
|
| 46 | | |
| 47 | | SOFTWARE_START( bsktball )
|
| 48 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 49 | | ROM_LOAD( "bsktball.bin", 0x0000, 0x1000, CRC(e93938f6) SHA1(c6e3f963ea9db520bcd682a3206cc291504c9e3d) )
|
| 50 | | SOFTWARE_END
|
| 51 | | |
| 52 | | SOFTWARE_START( battle )
|
| 53 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 54 | | ROM_LOAD( "battle.bin", 0x0000, 0x1000, CRC(6818c8bd) SHA1(21eadc7841e0a59671aacca93d28d81c580f16f2) )
|
| 55 | | SOFTWARE_END
|
| 56 | | |
| 57 | | SOFTWARE_START( blckjack )
|
| 58 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 59 | | ROM_LOAD( "blckjack.bin", 0x0000, 0x1000, CRC(0930ce04) SHA1(a8afadfcaea847c2e998005652ace36803d6601b) )
|
| 60 | | SOFTWARE_END
|
| 61 | | |
| 62 | | SOFTWARE_START( boxing )
|
| 63 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 64 | | ROM_LOAD( "boxing.bin", 0x0000, 0x1000, CRC(9240891b) SHA1(0fc3a8a33f2e89b2b32ea0a962effcf3ee430d34) )
|
| 65 | | SOFTWARE_END
|
| 66 | | |
| 67 | | SOFTWARE_START( brainqz )
|
| 68 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 69 | | ROM_LOAD( "brainqz.bin", 0x0000, 0x1000, CRC(ca58b3f8) SHA1(e9560e064043946b6bc0a88087d4164adf62e773) )
|
| 70 | | SOFTWARE_END
|
| 71 | | |
| 72 | | SOFTWARE_START( breakawy )
|
| 73 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 74 | | ROM_LOAD( "breakawy.bin", 0x0000, 0x1000, CRC(33c348c1) SHA1(396fe12bd34cc7cd555ad3b9b66f20e56e862385) )
|
| 75 | | SOFTWARE_END
|
| 76 | | |
| 77 | | SOFTWARE_START( capture )
|
| 78 | | ROM_REGION( 0x800, CARTRIDGE_REGION_ROM, 0 )
|
| 79 | | ROM_LOAD( "capture.bin", 0x000, 0x800, CRC(aeb803e4) SHA1(107c864252647a4f3569ff501c8a9a3c7dd6067f) )
|
| 80 | | SOFTWARE_END
|
| 81 | | |
| 82 | | SOFTWARE_START( cattrax )
|
| 83 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 84 | | ROM_LOAD( "cattrax.bin", 0x0000, 0x1000, CRC(fd2cf496) SHA1(b0982ed95d92a4d97a5451acbee36af10ff99a3f) )
|
| 85 | | SOFTWARE_END
|
| 86 | | |
| 87 | | SOFTWARE_START( circus )
|
| 88 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 89 | | ROM_LOAD( "circus.bin", 0x0000, 0x1000, CRC(086ebc8c) SHA1(e8abeb702d9a7b7e12e1cea02946dae267b23041) )
|
| 90 | | SOFTWARE_END
|
| 91 | | |
| 92 | | SOFTWARE_START( combat )
|
| 93 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 94 | | ROM_LOAD( "combat.bin", 0x0000, 0x1000, CRC(a6bffa9e) SHA1(87addcdd0fccb5f36066f21938458235d5a37bd0) )
|
| 95 | | SOFTWARE_END
|
| 96 | | |
| 97 | | SOFTWARE_START( crzycmbr )
|
| 98 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 99 | | ROM_LOAD( "crzycmbr.bin", 0x0000, 0x1000, CRC(76e773fa) SHA1(0c6ce7577a121e7810ec54c5dd180a55dd0ace17) )
|
| 100 | | SOFTWARE_END
|
| 101 | | |
| 102 | | SOFTWARE_START( crzygblr )
|
| 103 | | ROM_REGION( 0x800, CARTRIDGE_REGION_ROM, 0 )
|
| 104 | | ROM_LOAD( "crzygblr.bin", 0x000, 0x800, CRC(e84df2ef) SHA1(021e78bbc1f2c4ee2e7ca2fa560dd448bdd39798) )
|
| 105 | | SOFTWARE_END
|
| 106 | | |
| 107 | | SOFTWARE_START( doraemon )
|
| 108 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 109 | | ROM_LOAD( "doraemon.bin", 0x0000, 0x2000, CRC(62c45881) SHA1(a16fda96d00c8b08bb362f2573a45939aa6be051) )
|
| 110 | | SOFTWARE_END
|
| 111 | | |
| 112 | | SOFTWARE_START( drslump )
|
| 113 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 114 | | ROM_LOAD( "drslump.bin", 0x0000, 0x2000, CRC(927c375a) SHA1(389259f1505deef5c0fb83f9cf8b0f7fa4ed5d04) )
|
| 115 | | SOFTWARE_END
|
| 116 | | |
| 117 | | SOFTWARE_START( escape )
|
| 118 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 119 | | ROM_LOAD( "escape.bin", 0x0000, 0x1000, CRC(fc7eba76) SHA1(87f81511ea5b7a9671fb945cb22bb578bedb47c9) )
|
| 120 | | SOFTWARE_END
|
| 121 | | |
| 122 | | SOFTWARE_START( football )
|
| 123 | | ROM_REGION( 0x1800, CARTRIDGE_REGION_ROM, 0 )
|
| 124 | | ROM_LOAD( "football.bin", 0x0000, 0x1800, CRC(22624414) SHA1(359e938391b72742643c81228713fac804ff8244) )
|
| 125 | | SOFTWARE_END
|
| 126 | | |
| 127 | | SOFTWARE_START( funkyfsh )
|
| 128 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 129 | | ROM_LOAD( "funkyfsh.bin", 0x0000, 0x2000, CRC(77c19320) SHA1(e56be2ecd8284cd43a44620d56d6615766f45451) )
|
| 130 | | SOFTWARE_END
|
| 131 | | |
| 132 | | SOFTWARE_START( golf )
|
| 133 | | ROM_REGION( 0x1800, CARTRIDGE_REGION_ROM, 0 )
|
| 134 | | ROM_LOAD( "golf.bin", 0x0000, 0x1800, CRC(a23c7a01) SHA1(7c9251e42fd03b9c26a13d0e25cdf9a838319a39) )
|
| 135 | | SOFTWARE_END
|
| 136 | | |
| 137 | | SOFTWARE_START( gstennis )
|
| 138 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 139 | | ROM_LOAD( "gstennis.bin", 0x0000, 0x2000, CRC(8bf2dfa9) SHA1(03cedd5fd67ff11a4ac74d513f03a2266af89446) )
|
| 140 | | SOFTWARE_END
|
| 141 | | |
| 142 | | SOFTWARE_START( gpmonaco )
|
| 143 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 144 | | ROM_LOAD( "gpmonaco.bin", 0x0000, 0x1000, CRC(5e033f9c) SHA1(7dcc1387892fa7275514c91ce584f83a5d3e14d6) )
|
| 145 | | SOFTWARE_END
|
| 146 | | |
| 147 | | SOFTWARE_START( hobo )
|
| 148 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 149 | | ROM_LOAD( "hobo.bin", 0x0000, 0x2000, CRC(1cec4b21) SHA1(cebb340cb0a50b2815dafc6df8f46d814015a49f) )
|
| 150 | | SOFTWARE_END
|
| 151 | | |
| 152 | | SOFTWARE_START( horserac )
|
| 153 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 154 | | ROM_LOAD( "horserac.bin", 0x0000, 0x1000, CRC(560daa7f) SHA1(72dd8dea83bf9ab7d486931516e99b2209ca0a1d) )
|
| 155 | | SOFTWARE_END
|
| 156 | | |
| 157 | | SOFTWARE_START( jumpbug )
|
| 158 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 159 | | ROM_LOAD( "jumpbug.bin", 0x0000, 0x2000, CRC(97060a54) SHA1(d0ace24fd1f3805e46b077e8a4770f922157c8c4) )
|
| 160 | | SOFTWARE_END
|
| 161 | | |
| 162 | | SOFTWARE_START( jumpbuga )
|
| 163 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 164 | | ROM_LOAD( "jumpbuga.bin", 0x0000, 0x2000, CRC(dc0264b8) SHA1(bf3ccf7a54409f22ca4295b1df1c01bfbbe9f0a2) )
|
| 165 | | SOFTWARE_END
|
| 166 | | |
| 167 | | SOFTWARE_START( jungler )
|
| 168 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 169 | | ROM_LOAD( "jungler.bin", 0x0000, 0x2000, CRC(dfb5dd55) SHA1(8d6e32ab3cc872017c597e61c076330015411435) )
|
| 170 | | SOFTWARE_END
|
| 171 | | |
| 172 | | SOFTWARE_START( msslewar )
|
| 173 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 174 | | ROM_LOAD( "msslewar.bin", 0x0000, 0x1000, CRC(a615f068) SHA1(cc3e46adc8a3ed2cbfd5f9bbbf96f61f4e2ecebe) )
|
| 175 | | SOFTWARE_END
|
| 176 | | |
| 177 | | SOFTWARE_START( msgundam )
|
| 178 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 179 | | ROM_LOAD( "msgundam.bin", 0x0000, 0x2000, CRC(1241f128) SHA1(4b07a88b06008ddfc3676983e826e107caf3ba0f) )
|
| 180 | | SOFTWARE_END
|
| 181 | | |
| 182 | | SOFTWARE_START( nbblemen )
|
| 183 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 184 | | ROM_LOAD( "nbblemen.bin", 0x0000, 0x1000, CRC(7832f7ad) SHA1(a2f3d269e422e6ee89d58f001d39438704178e17) )
|
| 185 | | SOFTWARE_END
|
| 186 | | |
| 187 | | SOFTWARE_START( nbblemna )
|
| 188 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 189 | | ROM_LOAD( "nbblemna.bin", 0x0000, 0x1000, CRC(08d8b186) SHA1(ca2efbcb1f1f580b7995aa47ab7da09fa4a1b9e2) )
|
| 190 | | SOFTWARE_END
|
| 191 | | |
| 192 | | SOFTWARE_START( oceanbat )
|
| 193 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 194 | | ROM_LOAD( "oceanbat.bin", 0x0000, 0x1000, CRC(449e80cb) SHA1(444146bf89c3a0e0e010f6a30e675be3f2b023a7) )
|
| 195 | | SOFTWARE_END
|
| 196 | | |
| 197 | | SOFTWARE_START( parashtr )
|
| 198 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 199 | | ROM_LOAD( "parashtr.bin", 0x0000, 0x1000, CRC(4f538848) SHA1(2e7c8e4263eec7f033019ec763effebca40ca30b) )
|
| 200 | | SOFTWARE_END
|
| 201 | | |
| 202 | | SOFTWARE_START( pleiades )
|
| 203 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 204 | | ROM_LOAD( "pleiades.bin", 0x0000, 0x2000, CRC(4f19fd9b) SHA1(bdb7ce3d4552c82be3cf8db43d5ad103f9d9cc91) )
|
| 205 | | SOFTWARE_END
|
| 206 | | |
| 207 | | SOFTWARE_START( r2dtank )
|
| 208 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 209 | | ROM_LOAD( "r2dtank.bin", 0x0000, 0x1000, CRC(a0626e23) SHA1(e1daef4cc1e8c51cf542d900ba7139f5f472f2c8) )
|
| 210 | | SOFTWARE_END
|
| 211 | | |
| 212 | | SOFTWARE_START( redclash )
|
| 213 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 214 | | ROM_LOAD( "redclash.bin", 0x0000, 0x1000, CRC(a06f284b) SHA1(7a94f4f1768e4c62209cc03adc0fbadb954d2c24) )
|
| 215 | | SOFTWARE_END
|
| 216 | | |
| 217 | | SOFTWARE_START( robtkllr )
|
| 218 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 219 | | ROM_LOAD( "robtkllr.bin", 0x0000, 0x1000, CRC(4671b7f7) SHA1(acb45a8314fe531390d1c58be23ae860fa344c94) )
|
| 220 | | SOFTWARE_END
|
| 221 | | |
| 222 | | SOFTWARE_START( route16 )
|
| 223 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 224 | | ROM_LOAD( "route16.bin", 0x0000, 0x2000, CRC(8169864e) SHA1(6f6d0c0e2ae06112643c63cb6892f8c7269c98a6) )
|
| 225 | | SOFTWARE_END
|
| 226 | | |
| 227 | | SOFTWARE_START( soccer )
|
| 228 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 229 | | ROM_LOAD( "soccer.bin", 0x0000, 0x1000, CRC(b0b98a92) SHA1(1a575203b78af7ac992f109add1721dda8872fc1) )
|
| 230 | | SOFTWARE_END
|
| 231 | | |
| 232 | | SOFTWARE_START( spaceatt )
|
| 233 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 234 | | ROM_LOAD( "spaceatt.bin", 0x0000, 0x1000, CRC(e3794a2c) SHA1(25a27466dc3ffb6013cd4f632947834002c80105) )
|
| 235 | | SOFTWARE_END
|
| 236 | | |
| 237 | | SOFTWARE_START( spaceata )
|
| 238 | | ROM_REGION( 0x800, CARTRIDGE_REGION_ROM, 0 )
|
| 239 | | ROM_LOAD( "spaceata.bin", 0x000, 0x800, CRC(c91828cb) SHA1(9e84d1884a002aafb84682eeb9e1cb2f29944d64) )
|
| 240 | | SOFTWARE_END
|
| 241 | | |
| 242 | | SOFTWARE_START( spaceatb )
|
| 243 | | ROM_REGION( 0x800, CARTRIDGE_REGION_ROM, 0 )
|
| 244 | | ROM_LOAD( "spaceata.bin", 0x000, 0x800, CRC(669632ec) SHA1(0d96d79d22237312e217d8da8e2185e9245bdf47) )
|
| 245 | | SOFTWARE_END
|
| 246 | | |
| 247 | | SOFTWARE_START( spcemssn )
|
| 248 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 249 | | ROM_LOAD( "spcemssn.bin", 0x0000, 0x1000, CRC(3ff224e5) SHA1(a46fa9cbc12cb83218d3936ec3f4d0a4aff8cd60) )
|
| 250 | | SOFTWARE_END
|
| 251 | | |
| 252 | | SOFTWARE_START( spcerdrs )
|
| 253 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 254 | | ROM_LOAD( "spcerdrs.bin", 0x0000, 0x1000, CRC(88defacf) SHA1(c2c247b57c3d3a9321f7c16e48b1d733bd7d7dbb) )
|
| 255 | | SOFTWARE_END
|
| 256 | | |
| 257 | | SOFTWARE_START( spcesqdn )
|
| 258 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 259 | | ROM_LOAD( "spcesqdn.bin", 0x0000, 0x1000, CRC(caa5f449) SHA1(e76efb5f2707f67775d09d2d1547a4af0254b7b1) )
|
| 260 | | SOFTWARE_END
|
| 261 | | |
| 262 | | SOFTWARE_START( spcevult )
|
| 263 | | ROM_REGION( 0x1800, CARTRIDGE_REGION_ROM, 0 )
|
| 264 | | ROM_LOAD( "spcevult.bin", 0x0000, 0x1800, CRC(7666a712) SHA1(a1697ee165307792f07fdd7767122140958a4e9f) )
|
| 265 | | SOFTWARE_END
|
| 266 | | |
| 267 | | SOFTWARE_START( spiders )
|
| 268 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 269 | | ROM_LOAD( "spiders.bin", 0x0000, 0x1000, CRC(bb88daea) SHA1(e2fe75ec968a586a9c4885df02481b00abef2bc7) )
|
| 270 | | SOFTWARE_END
|
| 271 | | |
| 272 | | SOFTWARE_START( starchss )
|
| 273 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 274 | | ROM_LOAD( "starchss.bin", 0x0000, 0x1000, CRC(83e6e40b) SHA1(348ca876b1113827d8e7ffb9b2422e863ba92b0f) )
|
| 275 | | SOFTWARE_END
|
| 276 | | |
| 277 | | SOFTWARE_START( macross )
|
| 278 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 279 | | ROM_LOAD( "macross.bin", 0x0000, 0x2000, CRC(4c885af2) SHA1(3d24ab9e42ff44a223bb53c5491dea7f41691df2) )
|
| 280 | | SOFTWARE_END
|
| 281 | | |
| 282 | | SOFTWARE_START( superbug )
|
| 283 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 284 | | ROM_LOAD( "superbug.bin", 0x0000, 0x1000, CRC(fef2aae9) SHA1(1e7f7b81ecd2f766c94bd5ff17763374fb0318f1) )
|
| 285 | | SOFTWARE_END
|
| 286 | | |
| 287 | | SOFTWARE_START( superbga )
|
| 288 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 289 | | ROM_LOAD( "superbga.bin", 0x0000, 0x1000, CRC(15436f39) SHA1(bf22e0fae67bc3c2147a669b194752e34fe3564d) )
|
| 290 | | SOFTWARE_END
|
| 291 | | |
| 292 | | SOFTWARE_START( tnksalot )
|
| 293 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 294 | | ROM_LOAD( "tnksalot.bin", 0x0000, 0x1000, CRC(0076422e) SHA1(c431d5190e86f3dfbb3e8b1a3b9bec82bb5014ae) )
|
| 295 | | SOFTWARE_END
|
| 296 | | |
| 297 | | SOFTWARE_START( theend )
|
| 298 | | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 )
|
| 299 | | ROM_LOAD( "theend.bin", 0x0000, 0x1000, CRC(e66f362d) SHA1(1148aa1525d7b46640babb50b004c79abec45d3a) )
|
| 300 | | SOFTWARE_END
|
| 301 | | |
| 302 | | SOFTWARE_START( turtles )
|
| 303 | | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 )
|
| 304 | | ROM_LOAD( "turtles.bin", 0x0000, 0x2000, CRC(306e39c1) SHA1(a806e3f248a962bb99e2515f489d45bb11fb0a0e) )
|
| 305 | | SOFTWARE_END
|
| 306 | | |
| 307 | | |
| 308 | | SOFTWARE_LIST_START( arcadia_cart )
|
| 309 | | /* 3D Attack 1983 UA Ltd. */
|
| 310 | | SOFTWARE( 3dbwling, 0, 1982, "UA Ltd.", "3D Bowling", 0, 0 ) /* Also known as "Bowling" or "Bowling 3D" */
|
| 311 | | SOFTWARE( 3dsoccer, 0, 1983, "UA Ltd.", "3D Soccer", 0, 0 )
|
| 312 | | SOFTWARE( 3dsccera, 3dsoccer, 1983, "UA Ltd.", "3D Soccer (alt)", 0, 0 )
|
| 313 | | SOFTWARE( alieninv, 0, 1983, "UA Ltd.", "Alien Invaders", 0, 0 ) /* Also known as "Alien", "Alien Invader" or "Les Envahisseurs Etrangers" */
|
| 314 | | SOFTWARE( astroinv, 0, 1980, "UA Ltd.", "Astro Invaders", 0, 0 )
|
| 315 | | SOFTWARE( autorace, 0, 198?, "UA Ltd.", "Auto Race", 0, 0 )
|
| 316 | | SOFTWARE( baseball, 0, 1983, "UA Ltd.", "Baseball", 0, 0 )
|
| 317 | | SOFTWARE( bsktball, 0, 198?, "UA Ltd.", "Basketball", 0, 0 )
|
| 318 | | SOFTWARE( battle, 0, 198?, "UA Ltd.", "Battle", 0, 0 )
|
| 319 | | SOFTWARE( blckjack, 0, 198?, "UA Ltd.", "Blackjack & Poker", 0, 0 )
|
| 320 | | SOFTWARE( boxing, 0, 198?, "UA Ltd.", "Boxing", 0, 0 )
|
| 321 | | SOFTWARE( brainqz, 0, 1982, "UA Ltd.", "Brain Quiz", 0, 0 ) /* Also known as "Math/Logic" */
|
| 322 | | SOFTWARE( breakawy, 0, 1982, "UA Ltd.", "Breakaway", 0, 0 ) /* Also known as "Break Away", "Evasion", "Video Breakout" or "La Desertion" */
|
| 323 | | SOFTWARE( capture, 0, 1982, "UA Ltd.", "Capture", 0, 0 ) /* Also known as "Othello" or "Side Attack" */
|
| 324 | | SOFTWARE( cattrax, 0, 1982, "UA Ltd.", "Cat Trax", 0, 0 ) /* Also known as "Cat Track" or "Cat Tracks" */
|
| 325 | | SOFTWARE( circus, 0, 1983, "UA Ltd.", "Circus", 0, 0 ) /* Also known as "Acrobat" or "Clown" */
|
| 326 | | SOFTWARE( combat, 0, 198?, "UA Ltd.", "Combat", 0, 0 ) /* Also known as "Combat Zone" */
|
| 327 | | SOFTWARE( crzycmbr, 0, 1982, "UA Ltd.", "Crazy Climber", 0, 0 ) /* Also known as "Crazy Wall" */
|
| 328 | | SOFTWARE( crzygblr, 0, 1982, "UA Ltd.", "Crazy Gobbler", 0, 0 )
|
| 329 | | SOFTWARE( doraemon, 0, 1983, "Bandai", "Doraemon", 0, 0 ) /* Bandai Arcadia exclusive */
|
| 330 | | SOFTWARE( drslump, 0, 1983, "Bandai", "Dr. Slump", 0, 0 ) /* Bandai Arcadia exclusive */
|
| 331 | | SOFTWARE( escape, 0, 1982, "UA Ltd.", "Escape", 0, 0 ) /* Also known as "Escape Man" */
|
| 332 | | SOFTWARE( football, 0, 1982, "UA Ltd.", "Football", 0, 0 ) /* Also known as "American Football" */
|
| 333 | | SOFTWARE( funkyfsh, 0, 1983, "UA Ltd.", "Funky Fish", 0, 0 )
|
| 334 | | SOFTWARE( golf, 0, 198?, "UA Ltd.", "Golf", 0, 0 ) /* Also known as "Golfer" */
|
| 335 | | SOFTWARE( gstennis, 0, 1982, "UA Ltd.", "Grand Slam Tennis", 0, 0 ) /* Also known as "Tennis" or "Yannick Noah Tennis" */
|
| 336 | | SOFTWARE( gpmonaco, 0, 1982, "UA Ltd.", "Grand Prix de Monaco", 0, 0 ) /* Also known as "Monaco Grand Prix" */
|
| 337 | | SOFTWARE( hobo, 0, 1983, "UA Ltd.", "Hobo", 0, 0 )
|
| 338 | | SOFTWARE( horserac, 0, 198?, "UA Ltd.", "Horse Racing", 0, 0 )
|
| 339 | | SOFTWARE( jumpbug, 0, 1982, "UA Ltd.", "Jump Bug", 0, 0 ) /* Also known as "Hoppy Bug" */
|
| 340 | | SOFTWARE( jumpbuga, jumpbug, 1982, "UA Ltd.", "Jump Bug (alt)", 0, 0 ) /* Also known as "Hoppy Bug" */
|
| 341 | | SOFTWARE( jungler, 0, 1982, "UA Ltd.", "Jungler", 0, 0 )
|
| 342 | | SOFTWARE( msslewar, 0, 1982, "UA Ltd.", "Missile War", 0, 0 ) /* Also known as "Le Guerre des Missiles" */
|
| 343 | | SOFTWARE( msgundam, 0, 1983, "Bandai", "Mobile Soldier Gundam", 0, 0 ) /* Bandai Arcadia exclusive */
|
| 344 | | SOFTWARE( nbblemen, 0, 1982, "UA Ltd.", "Nibblemen", 0, 0 ) /* Also known as "Devilman the Dot Muncher" or "Super Gobbler" */
|
| 345 | | SOFTWARE( nbblemna, nbblemen, 1982, "UA Ltd.", "Nibblemen (alt)", 0, 0 ) /* Also known as "Devilman the Dot Muncher" or "Super Gobbler" */
|
| 346 | | SOFTWARE( oceanbat, 0, 1982, "UA Ltd.", "Ocean Battle", 0, 0 ) /* Also known as "Sea Battle" or "Le Combat Naval" */
|
| 347 | | SOFTWARE( parashtr, 0, 1982, "UA Ltd.", "Parashooter", 0, 0 ) /* Also known as "Parachute" */
|
| 348 | | SOFTWARE( pleiades, 0, 1983, "UA Ltd.", "Pleiades", 0, 0 )
|
| 349 | | SOFTWARE( r2dtank, 0, 1981, "UA Ltd.", "R2D Tank", 0, 0 )
|
| 350 | | SOFTWARE( redclash, 0, 1982, "UA Ltd.", "Red Clash", 0, 0 )
|
| 351 | | SOFTWARE( robtkllr, 0, 1982, "UA Ltd.", "Robot Killer", 0, 0 )
|
| 352 | | SOFTWARE( route16, 0, 1983, "UA Ltd.", "Route 16", 0, 0 )
|
| 353 | | SOFTWARE( soccer, 0, 1982, "UA Ltd.", "Soccer", 0, 0 ) /* Also known as "Football" */
|
| 354 | | SOFTWARE( spaceatt, 0, 1982, "UA Ltd.", "Space Attack", 0, 0 ) /* Also known as "Space War" */
|
| 355 | | SOFTWARE( spaceata, spaceatt, 1982, "UA Ltd.", "Space Attack (alt)", 0, 0 ) /* Prototype? Also known as "Space War" */
|
| 356 | | SOFTWARE( spaceatb, spaceatt, 1982, "UA Ltd.", "Space Attack (alt 2)", 0, 0 ) /* Also known as "Space War" */
|
| 357 | | SOFTWARE( spcemssn, 0, 1982, "UA Ltd.", "Space Mission", 0, 0 )
|
| 358 | | SOFTWARE( spcerdrs, 0, 1982, "UA Ltd.", "Space Raiders", 0, 0 ) /* Also known as "Space Raider" */
|
| 359 | | SOFTWARE( spcesqdn, 0, 1982, "UA Ltd.", "Space Squadron", 0, 0 ) /* Also known as "L'Escadron de L'Espace" */
|
| 360 | | SOFTWARE( spcevult, 0, 1982, "UA Ltd.", "Space Vultures", 0, 0 )
|
| 361 | | SOFTWARE( spiders, 0, 1982, "UA Ltd.", "Spiders", 0, 0 )
|
| 362 | | SOFTWARE( starchss, 0, 1982, "UA Ltd.", "Star Chess", 0, 0 ) /* Also known as "Echec Etiles" or "Video Chess" */
|
| 363 | | SOFTWARE( macross, 0, 1983, "Bandai", "Macross", 0, 0 ) /* Bandai Arcadia exclusive, Also known as "Super Dimension Fortress Macross" */
|
| 364 | | SOFTWARE( superbug, 0, 198?, "UA Ltd.", "Super Bug", 0, 0 )
|
| 365 | | SOFTWARE( superbga, superbug, 198?, "UA Ltd.", "Super Bug (alt)", 0, 0 )
|
| 366 | | SOFTWARE( tnksalot, 0, 1982, "UA Ltd.", "Tanks a Lot", 0, 0 )
|
| 367 | | SOFTWARE( theend, 0, 1982, "UA Ltd.", "The End", 0, 0 ) /* Also known as "Space Pirates" */
|
| 368 | | SOFTWARE( turtles, 0, 1982, "UA Ltd.", "Turtles Turpin", 0, 0 ) /* Overdumped? */
|
| 369 | | SOFTWARE_LIST_END
|
| 370 | | |
| 371 | | |
| 372 | | SOFTWARE_LIST( arcadia_cart, "Emerson Arcadia 2001 cartridges" )
|
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Emerson Arcadia 2001 cartridges |
| 4 | |
| 5 | ***************************************************************************/ |
| 6 | |
| 7 | #include "emu.h" |
| 8 | #include "softlist.h" |
| 9 | #include "devices/cartslot.h" |
| 10 | |
| 11 | |
| 12 | SOFTWARE_START( 3dbwling ) |
| 13 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 14 | ROM_LOAD( "3dbwling.bin", 0x0000, 0x1000, CRC(f3c08e19) SHA1(edd33cabd3d600e9e3d3c22f326a065ea6ebe32c) ) |
| 15 | SOFTWARE_END |
| 16 | |
| 17 | SOFTWARE_START( 3dsoccer ) |
| 18 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 19 | ROM_LOAD( "3dsoccer.bin", 0x0000, 0x2000, CRC(4da68df8) SHA1(50e799c96be3613f937825c6c722521bc6df0162) ) |
| 20 | SOFTWARE_END |
| 21 | |
| 22 | SOFTWARE_START( 3dsccera ) |
| 23 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 24 | ROM_LOAD( "3dsccera.bin", 0x0000, 0x2000, CRC(1b5be22a) SHA1(d3df9ed4e09bacacde47fa4f1128383fd62ffd6e) ) |
| 25 | SOFTWARE_END |
| 26 | |
| 27 | SOFTWARE_START( alieninv ) |
| 28 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 29 | ROM_LOAD( "alieninv.bin", 0x0000, 0x1000, CRC(1f65b21e) SHA1(8d17de81fbf70db8fe32830763c6a940aa9124c3) ) |
| 30 | SOFTWARE_END |
| 31 | |
| 32 | SOFTWARE_START( astroinv ) |
| 33 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 34 | ROM_LOAD( "astroinv.bin", 0x0000, 0x1000, CRC(ddcf5b2c) SHA1(b6f693e3333607181fbe3a43dffa9f30f9656998) ) |
| 35 | SOFTWARE_END |
| 36 | |
| 37 | SOFTWARE_START( autorace ) |
| 38 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 39 | ROM_LOAD( "autorace.bin", 0x0000, 0x1000, CRC(99ac48ca) SHA1(6182219b2b8c8747f67d627a056ac947754f0978) ) |
| 40 | SOFTWARE_END |
| 41 | |
| 42 | SOFTWARE_START( baseball ) |
| 43 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 44 | ROM_LOAD( "baseball.bin", 0x0000, 0x1000, CRC(1cf08155) SHA1(f4d39aaab61e6b01c673166ae54841d450860b31) ) |
| 45 | SOFTWARE_END |
| 46 | |
| 47 | SOFTWARE_START( bsktball ) |
| 48 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 49 | ROM_LOAD( "bsktball.bin", 0x0000, 0x1000, CRC(e93938f6) SHA1(c6e3f963ea9db520bcd682a3206cc291504c9e3d) ) |
| 50 | SOFTWARE_END |
| 51 | |
| 52 | SOFTWARE_START( battle ) |
| 53 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 54 | ROM_LOAD( "battle.bin", 0x0000, 0x1000, CRC(6818c8bd) SHA1(21eadc7841e0a59671aacca93d28d81c580f16f2) ) |
| 55 | SOFTWARE_END |
| 56 | |
| 57 | SOFTWARE_START( blckjack ) |
| 58 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 59 | ROM_LOAD( "blckjack.bin", 0x0000, 0x1000, CRC(0930ce04) SHA1(a8afadfcaea847c2e998005652ace36803d6601b) ) |
| 60 | SOFTWARE_END |
| 61 | |
| 62 | SOFTWARE_START( boxing ) |
| 63 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 64 | ROM_LOAD( "boxing.bin", 0x0000, 0x1000, CRC(9240891b) SHA1(0fc3a8a33f2e89b2b32ea0a962effcf3ee430d34) ) |
| 65 | SOFTWARE_END |
| 66 | |
| 67 | SOFTWARE_START( brainqz ) |
| 68 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 69 | ROM_LOAD( "brainqz.bin", 0x0000, 0x1000, CRC(ca58b3f8) SHA1(e9560e064043946b6bc0a88087d4164adf62e773) ) |
| 70 | SOFTWARE_END |
| 71 | |
| 72 | SOFTWARE_START( breakawy ) |
| 73 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 74 | ROM_LOAD( "breakawy.bin", 0x0000, 0x1000, CRC(33c348c1) SHA1(396fe12bd34cc7cd555ad3b9b66f20e56e862385) ) |
| 75 | SOFTWARE_END |
| 76 | |
| 77 | SOFTWARE_START( capture ) |
| 78 | ROM_REGION( 0x800, CARTRIDGE_REGION_ROM, 0 ) |
| 79 | ROM_LOAD( "capture.bin", 0x000, 0x800, CRC(aeb803e4) SHA1(107c864252647a4f3569ff501c8a9a3c7dd6067f) ) |
| 80 | SOFTWARE_END |
| 81 | |
| 82 | SOFTWARE_START( cattrax ) |
| 83 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 84 | ROM_LOAD( "cattrax.bin", 0x0000, 0x1000, CRC(fd2cf496) SHA1(b0982ed95d92a4d97a5451acbee36af10ff99a3f) ) |
| 85 | SOFTWARE_END |
| 86 | |
| 87 | SOFTWARE_START( circus ) |
| 88 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 89 | ROM_LOAD( "circus.bin", 0x0000, 0x1000, CRC(086ebc8c) SHA1(e8abeb702d9a7b7e12e1cea02946dae267b23041) ) |
| 90 | SOFTWARE_END |
| 91 | |
| 92 | SOFTWARE_START( combat ) |
| 93 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 94 | ROM_LOAD( "combat.bin", 0x0000, 0x1000, CRC(a6bffa9e) SHA1(87addcdd0fccb5f36066f21938458235d5a37bd0) ) |
| 95 | SOFTWARE_END |
| 96 | |
| 97 | SOFTWARE_START( crzycmbr ) |
| 98 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 99 | ROM_LOAD( "crzycmbr.bin", 0x0000, 0x1000, CRC(76e773fa) SHA1(0c6ce7577a121e7810ec54c5dd180a55dd0ace17) ) |
| 100 | SOFTWARE_END |
| 101 | |
| 102 | SOFTWARE_START( crzygblr ) |
| 103 | ROM_REGION( 0x800, CARTRIDGE_REGION_ROM, 0 ) |
| 104 | ROM_LOAD( "crzygblr.bin", 0x000, 0x800, CRC(e84df2ef) SHA1(021e78bbc1f2c4ee2e7ca2fa560dd448bdd39798) ) |
| 105 | SOFTWARE_END |
| 106 | |
| 107 | SOFTWARE_START( doraemon ) |
| 108 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 109 | ROM_LOAD( "doraemon.bin", 0x0000, 0x2000, CRC(62c45881) SHA1(a16fda96d00c8b08bb362f2573a45939aa6be051) ) |
| 110 | SOFTWARE_END |
| 111 | |
| 112 | SOFTWARE_START( drslump ) |
| 113 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 114 | ROM_LOAD( "drslump.bin", 0x0000, 0x2000, CRC(927c375a) SHA1(389259f1505deef5c0fb83f9cf8b0f7fa4ed5d04) ) |
| 115 | SOFTWARE_END |
| 116 | |
| 117 | SOFTWARE_START( escape ) |
| 118 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 119 | ROM_LOAD( "escape.bin", 0x0000, 0x1000, CRC(fc7eba76) SHA1(87f81511ea5b7a9671fb945cb22bb578bedb47c9) ) |
| 120 | SOFTWARE_END |
| 121 | |
| 122 | SOFTWARE_START( football ) |
| 123 | ROM_REGION( 0x1800, CARTRIDGE_REGION_ROM, 0 ) |
| 124 | ROM_LOAD( "football.bin", 0x0000, 0x1800, CRC(22624414) SHA1(359e938391b72742643c81228713fac804ff8244) ) |
| 125 | SOFTWARE_END |
| 126 | |
| 127 | SOFTWARE_START( funkyfsh ) |
| 128 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 129 | ROM_LOAD( "funkyfsh.bin", 0x0000, 0x2000, CRC(77c19320) SHA1(e56be2ecd8284cd43a44620d56d6615766f45451) ) |
| 130 | SOFTWARE_END |
| 131 | |
| 132 | SOFTWARE_START( golf ) |
| 133 | ROM_REGION( 0x1800, CARTRIDGE_REGION_ROM, 0 ) |
| 134 | ROM_LOAD( "golf.bin", 0x0000, 0x1800, CRC(a23c7a01) SHA1(7c9251e42fd03b9c26a13d0e25cdf9a838319a39) ) |
| 135 | SOFTWARE_END |
| 136 | |
| 137 | SOFTWARE_START( gstennis ) |
| 138 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 139 | ROM_LOAD( "gstennis.bin", 0x0000, 0x2000, CRC(8bf2dfa9) SHA1(03cedd5fd67ff11a4ac74d513f03a2266af89446) ) |
| 140 | SOFTWARE_END |
| 141 | |
| 142 | SOFTWARE_START( gpmonaco ) |
| 143 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 144 | ROM_LOAD( "gpmonaco.bin", 0x0000, 0x1000, CRC(5e033f9c) SHA1(7dcc1387892fa7275514c91ce584f83a5d3e14d6) ) |
| 145 | SOFTWARE_END |
| 146 | |
| 147 | SOFTWARE_START( hobo ) |
| 148 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 149 | ROM_LOAD( "hobo.bin", 0x0000, 0x2000, CRC(1cec4b21) SHA1(cebb340cb0a50b2815dafc6df8f46d814015a49f) ) |
| 150 | SOFTWARE_END |
| 151 | |
| 152 | SOFTWARE_START( horserac ) |
| 153 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 154 | ROM_LOAD( "horserac.bin", 0x0000, 0x1000, CRC(560daa7f) SHA1(72dd8dea83bf9ab7d486931516e99b2209ca0a1d) ) |
| 155 | SOFTWARE_END |
| 156 | |
| 157 | SOFTWARE_START( jumpbug ) |
| 158 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 159 | ROM_LOAD( "jumpbug.bin", 0x0000, 0x2000, CRC(97060a54) SHA1(d0ace24fd1f3805e46b077e8a4770f922157c8c4) ) |
| 160 | SOFTWARE_END |
| 161 | |
| 162 | SOFTWARE_START( jumpbuga ) |
| 163 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 164 | ROM_LOAD( "jumpbuga.bin", 0x0000, 0x2000, CRC(dc0264b8) SHA1(bf3ccf7a54409f22ca4295b1df1c01bfbbe9f0a2) ) |
| 165 | SOFTWARE_END |
| 166 | |
| 167 | SOFTWARE_START( jungler ) |
| 168 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 169 | ROM_LOAD( "jungler.bin", 0x0000, 0x2000, CRC(dfb5dd55) SHA1(8d6e32ab3cc872017c597e61c076330015411435) ) |
| 170 | SOFTWARE_END |
| 171 | |
| 172 | SOFTWARE_START( msslewar ) |
| 173 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 174 | ROM_LOAD( "msslewar.bin", 0x0000, 0x1000, CRC(a615f068) SHA1(cc3e46adc8a3ed2cbfd5f9bbbf96f61f4e2ecebe) ) |
| 175 | SOFTWARE_END |
| 176 | |
| 177 | SOFTWARE_START( msgundam ) |
| 178 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 179 | ROM_LOAD( "msgundam.bin", 0x0000, 0x2000, CRC(1241f128) SHA1(4b07a88b06008ddfc3676983e826e107caf3ba0f) ) |
| 180 | SOFTWARE_END |
| 181 | |
| 182 | SOFTWARE_START( nbblemen ) |
| 183 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 184 | ROM_LOAD( "nbblemen.bin", 0x0000, 0x1000, CRC(7832f7ad) SHA1(a2f3d269e422e6ee89d58f001d39438704178e17) ) |
| 185 | SOFTWARE_END |
| 186 | |
| 187 | SOFTWARE_START( nbblemna ) |
| 188 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 189 | ROM_LOAD( "nbblemna.bin", 0x0000, 0x1000, CRC(08d8b186) SHA1(ca2efbcb1f1f580b7995aa47ab7da09fa4a1b9e2) ) |
| 190 | SOFTWARE_END |
| 191 | |
| 192 | SOFTWARE_START( oceanbat ) |
| 193 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 194 | ROM_LOAD( "oceanbat.bin", 0x0000, 0x1000, CRC(449e80cb) SHA1(444146bf89c3a0e0e010f6a30e675be3f2b023a7) ) |
| 195 | SOFTWARE_END |
| 196 | |
| 197 | SOFTWARE_START( parashtr ) |
| 198 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 199 | ROM_LOAD( "parashtr.bin", 0x0000, 0x1000, CRC(4f538848) SHA1(2e7c8e4263eec7f033019ec763effebca40ca30b) ) |
| 200 | SOFTWARE_END |
| 201 | |
| 202 | SOFTWARE_START( pleiades ) |
| 203 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 204 | ROM_LOAD( "pleiades.bin", 0x0000, 0x2000, CRC(4f19fd9b) SHA1(bdb7ce3d4552c82be3cf8db43d5ad103f9d9cc91) ) |
| 205 | SOFTWARE_END |
| 206 | |
| 207 | SOFTWARE_START( r2dtank ) |
| 208 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 209 | ROM_LOAD( "r2dtank.bin", 0x0000, 0x1000, CRC(a0626e23) SHA1(e1daef4cc1e8c51cf542d900ba7139f5f472f2c8) ) |
| 210 | SOFTWARE_END |
| 211 | |
| 212 | SOFTWARE_START( redclash ) |
| 213 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 214 | ROM_LOAD( "redclash.bin", 0x0000, 0x1000, CRC(a06f284b) SHA1(7a94f4f1768e4c62209cc03adc0fbadb954d2c24) ) |
| 215 | SOFTWARE_END |
| 216 | |
| 217 | SOFTWARE_START( robtkllr ) |
| 218 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 219 | ROM_LOAD( "robtkllr.bin", 0x0000, 0x1000, CRC(4671b7f7) SHA1(acb45a8314fe531390d1c58be23ae860fa344c94) ) |
| 220 | SOFTWARE_END |
| 221 | |
| 222 | SOFTWARE_START( route16 ) |
| 223 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 224 | ROM_LOAD( "route16.bin", 0x0000, 0x2000, CRC(8169864e) SHA1(6f6d0c0e2ae06112643c63cb6892f8c7269c98a6) ) |
| 225 | SOFTWARE_END |
| 226 | |
| 227 | SOFTWARE_START( soccer ) |
| 228 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 229 | ROM_LOAD( "soccer.bin", 0x0000, 0x1000, CRC(b0b98a92) SHA1(1a575203b78af7ac992f109add1721dda8872fc1) ) |
| 230 | SOFTWARE_END |
| 231 | |
| 232 | SOFTWARE_START( spaceatt ) |
| 233 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 234 | ROM_LOAD( "spaceatt.bin", 0x0000, 0x1000, CRC(e3794a2c) SHA1(25a27466dc3ffb6013cd4f632947834002c80105) ) |
| 235 | SOFTWARE_END |
| 236 | |
| 237 | SOFTWARE_START( spaceata ) |
| 238 | ROM_REGION( 0x800, CARTRIDGE_REGION_ROM, 0 ) |
| 239 | ROM_LOAD( "spaceata.bin", 0x000, 0x800, CRC(c91828cb) SHA1(9e84d1884a002aafb84682eeb9e1cb2f29944d64) ) |
| 240 | SOFTWARE_END |
| 241 | |
| 242 | SOFTWARE_START( spaceatb ) |
| 243 | ROM_REGION( 0x800, CARTRIDGE_REGION_ROM, 0 ) |
| 244 | ROM_LOAD( "spaceata.bin", 0x000, 0x800, CRC(669632ec) SHA1(0d96d79d22237312e217d8da8e2185e9245bdf47) ) |
| 245 | SOFTWARE_END |
| 246 | |
| 247 | SOFTWARE_START( spcemssn ) |
| 248 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 249 | ROM_LOAD( "spcemssn.bin", 0x0000, 0x1000, CRC(3ff224e5) SHA1(a46fa9cbc12cb83218d3936ec3f4d0a4aff8cd60) ) |
| 250 | SOFTWARE_END |
| 251 | |
| 252 | SOFTWARE_START( spcerdrs ) |
| 253 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 254 | ROM_LOAD( "spcerdrs.bin", 0x0000, 0x1000, CRC(88defacf) SHA1(c2c247b57c3d3a9321f7c16e48b1d733bd7d7dbb) ) |
| 255 | SOFTWARE_END |
| 256 | |
| 257 | SOFTWARE_START( spcesqdn ) |
| 258 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 259 | ROM_LOAD( "spcesqdn.bin", 0x0000, 0x1000, CRC(caa5f449) SHA1(e76efb5f2707f67775d09d2d1547a4af0254b7b1) ) |
| 260 | SOFTWARE_END |
| 261 | |
| 262 | SOFTWARE_START( spcevult ) |
| 263 | ROM_REGION( 0x1800, CARTRIDGE_REGION_ROM, 0 ) |
| 264 | ROM_LOAD( "spcevult.bin", 0x0000, 0x1800, CRC(7666a712) SHA1(a1697ee165307792f07fdd7767122140958a4e9f) ) |
| 265 | SOFTWARE_END |
| 266 | |
| 267 | SOFTWARE_START( spiders ) |
| 268 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 269 | ROM_LOAD( "spiders.bin", 0x0000, 0x1000, CRC(bb88daea) SHA1(e2fe75ec968a586a9c4885df02481b00abef2bc7) ) |
| 270 | SOFTWARE_END |
| 271 | |
| 272 | SOFTWARE_START( starchss ) |
| 273 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 274 | ROM_LOAD( "starchss.bin", 0x0000, 0x1000, CRC(83e6e40b) SHA1(348ca876b1113827d8e7ffb9b2422e863ba92b0f) ) |
| 275 | SOFTWARE_END |
| 276 | |
| 277 | SOFTWARE_START( macross ) |
| 278 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 279 | ROM_LOAD( "macross.bin", 0x0000, 0x2000, CRC(4c885af2) SHA1(3d24ab9e42ff44a223bb53c5491dea7f41691df2) ) |
| 280 | SOFTWARE_END |
| 281 | |
| 282 | SOFTWARE_START( superbug ) |
| 283 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 284 | ROM_LOAD( "superbug.bin", 0x0000, 0x1000, CRC(fef2aae9) SHA1(1e7f7b81ecd2f766c94bd5ff17763374fb0318f1) ) |
| 285 | SOFTWARE_END |
| 286 | |
| 287 | SOFTWARE_START( superbga ) |
| 288 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 289 | ROM_LOAD( "superbga.bin", 0x0000, 0x1000, CRC(15436f39) SHA1(bf22e0fae67bc3c2147a669b194752e34fe3564d) ) |
| 290 | SOFTWARE_END |
| 291 | |
| 292 | SOFTWARE_START( tnksalot ) |
| 293 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 294 | ROM_LOAD( "tnksalot.bin", 0x0000, 0x1000, CRC(0076422e) SHA1(c431d5190e86f3dfbb3e8b1a3b9bec82bb5014ae) ) |
| 295 | SOFTWARE_END |
| 296 | |
| 297 | SOFTWARE_START( theend ) |
| 298 | ROM_REGION( 0x1000, CARTRIDGE_REGION_ROM, 0 ) |
| 299 | ROM_LOAD( "theend.bin", 0x0000, 0x1000, CRC(e66f362d) SHA1(1148aa1525d7b46640babb50b004c79abec45d3a) ) |
| 300 | SOFTWARE_END |
| 301 | |
| 302 | SOFTWARE_START( turtles ) |
| 303 | ROM_REGION( 0x2000, CARTRIDGE_REGION_ROM, 0 ) |
| 304 | ROM_LOAD( "turtles.bin", 0x0000, 0x2000, CRC(306e39c1) SHA1(a806e3f248a962bb99e2515f489d45bb11fb0a0e) ) |
| 305 | SOFTWARE_END |
| 306 | |
| 307 | |
| 308 | SOFTWARE_LIST_START( arcadia_cart ) |
| 309 | /* 3D Attack 1983 UA Ltd. */ |
| 310 | SOFTWARE( 3dbwling, 0, 1982, "UA Ltd.", "3D Bowling", 0, 0 ) /* Also known as "Bowling" or "Bowling 3D" */ |
| 311 | SOFTWARE( 3dsoccer, 0, 1983, "UA Ltd.", "3D Soccer", 0, 0 ) |
| 312 | SOFTWARE( 3dsccera, 3dsoccer, 1983, "UA Ltd.", "3D Soccer (alt)", 0, 0 ) |
| 313 | SOFTWARE( alieninv, 0, 1983, "UA Ltd.", "Alien Invaders", 0, 0 ) /* Also known as "Alien", "Alien Invader" or "Les Envahisseurs Etrangers" */ |
| 314 | SOFTWARE( astroinv, 0, 1980, "UA Ltd.", "Astro Invaders", 0, 0 ) |
| 315 | SOFTWARE( autorace, 0, 198?, "UA Ltd.", "Auto Race", 0, 0 ) |
| 316 | SOFTWARE( baseball, 0, 1983, "UA Ltd.", "Baseball", 0, 0 ) |
| 317 | SOFTWARE( bsktball, 0, 198?, "UA Ltd.", "Basketball", 0, 0 ) |
| 318 | SOFTWARE( battle, 0, 198?, "UA Ltd.", "Battle", 0, 0 ) |
| 319 | SOFTWARE( blckjack, 0, 198?, "UA Ltd.", "Blackjack & Poker", 0, 0 ) |
| 320 | SOFTWARE( boxing, 0, 198?, "UA Ltd.", "Boxing", 0, 0 ) |
| 321 | SOFTWARE( brainqz, 0, 1982, "UA Ltd.", "Brain Quiz", 0, 0 ) /* Also known as "Math/Logic" */ |
| 322 | SOFTWARE( breakawy, 0, 1982, "UA Ltd.", "Breakaway", 0, 0 ) /* Also known as "Break Away", "Evasion", "Video Breakout" or "La Desertion" */ |
| 323 | SOFTWARE( capture, 0, 1982, "UA Ltd.", "Capture", 0, 0 ) /* Also known as "Othello" or "Side Attack" */ |
| 324 | SOFTWARE( cattrax, 0, 1982, "UA Ltd.", "Cat Trax", 0, 0 ) /* Also known as "Cat Track" or "Cat Tracks" */ |
| 325 | SOFTWARE( circus, 0, 1983, "UA Ltd.", "Circus", 0, 0 ) /* Also known as "Acrobat" or "Clown" */ |
| 326 | SOFTWARE( combat, 0, 198?, "UA Ltd.", "Combat", 0, 0 ) /* Also known as "Combat Zone" */ |
| 327 | SOFTWARE( crzycmbr, 0, 1982, "UA Ltd.", "Crazy Climber", 0, 0 ) /* Also known as "Crazy Wall" */ |
| 328 | SOFTWARE( crzygblr, 0, 1982, "UA Ltd.", "Crazy Gobbler", 0, 0 ) |
| 329 | SOFTWARE( doraemon, 0, 1983, "Bandai", "Doraemon", 0, 0 ) /* Bandai Arcadia exclusive */ |
| 330 | SOFTWARE( drslump, 0, 1983, "Bandai", "Dr. Slump", 0, 0 ) /* Bandai Arcadia exclusive */ |
| 331 | SOFTWARE( escape, 0, 1982, "UA Ltd.", "Escape", 0, 0 ) /* Also known as "Escape Man" */ |
| 332 | SOFTWARE( football, 0, 1982, "UA Ltd.", "Football", 0, 0 ) /* Also known as "American Football" */ |
| 333 | SOFTWARE( funkyfsh, 0, 1983, "UA Ltd.", "Funky Fish", 0, 0 ) |
| 334 | SOFTWARE( golf, 0, 198?, "UA Ltd.", "Golf", 0, 0 ) /* Also known as "Golfer" */ |
| 335 | SOFTWARE( gstennis, 0, 1982, "UA Ltd.", "Grand Slam Tennis", 0, 0 ) /* Also known as "Tennis" or "Yannick Noah Tennis" */ |
| 336 | SOFTWARE( gpmonaco, 0, 1982, "UA Ltd.", "Grand Prix de Monaco", 0, 0 ) /* Also known as "Monaco Grand Prix" */ |
| 337 | SOFTWARE( hobo, 0, 1983, "UA Ltd.", "Hobo", 0, 0 ) |
| 338 | SOFTWARE( horserac, 0, 198?, "UA Ltd.", "Horse Racing", 0, 0 ) |
| 339 | SOFTWARE( jumpbug, 0, 1982, "UA Ltd.", "Jump Bug", 0, 0 ) /* Also known as "Hoppy Bug" */ |
| 340 | SOFTWARE( jumpbuga, jumpbug, 1982, "UA Ltd.", "Jump Bug (alt)", 0, 0 ) /* Also known as "Hoppy Bug" */ |
| 341 | SOFTWARE( jungler, 0, 1982, "UA Ltd.", "Jungler", 0, 0 ) |
| 342 | SOFTWARE( msslewar, 0, 1982, "UA Ltd.", "Missile War", 0, 0 ) /* Also known as "Le Guerre des Missiles" */ |
| 343 | SOFTWARE( msgundam, 0, 1983, "Bandai", "Mobile Soldier Gundam", 0, 0 ) /* Bandai Arcadia exclusive */ |
| 344 | SOFTWARE( nbblemen, 0, 1982, "UA Ltd.", "Nibblemen", 0, 0 ) /* Also known as "Devilman the Dot Muncher" or "Super Gobbler" */ |
| 345 | SOFTWARE( nbblemna, nbblemen, 1982, "UA Ltd.", "Nibblemen (alt)", 0, 0 ) /* Also known as "Devilman the Dot Muncher" or "Super Gobbler" */ |
| 346 | SOFTWARE( oceanbat, 0, 1982, "UA Ltd.", "Ocean Battle", 0, 0 ) /* Also known as "Sea Battle" or "Le Combat Naval" */ |
| 347 | SOFTWARE( parashtr, 0, 1982, "UA Ltd.", "Parashooter", 0, 0 ) /* Also known as "Parachute" */ |
| 348 | SOFTWARE( pleiades, 0, 1983, "UA Ltd.", "Pleiades", 0, 0 ) |
| 349 | SOFTWARE( r2dtank, 0, 1981, "UA Ltd.", "R2D Tank", 0, 0 ) |
| 350 | SOFTWARE( redclash, 0, 1982, "UA Ltd.", "Red Clash", 0, 0 ) |
| 351 | SOFTWARE( robtkllr, 0, 1982, "UA Ltd.", "Robot Killer", 0, 0 ) |
| 352 | SOFTWARE( route16, 0, 1983, "UA Ltd.", "Route 16", 0, 0 ) |
| 353 | SOFTWARE( soccer, 0, 1982, "UA Ltd.", "Soccer", 0, 0 ) /* Also known as "Football" */ |
| 354 | SOFTWARE( spaceatt, 0, 1982, "UA Ltd.", "Space Attack", 0, 0 ) /* Also known as "Space War" */ |
| 355 | SOFTWARE( spaceata, spaceatt, 1982, "UA Ltd.", "Space Attack (alt)", 0, 0 ) /* Prototype? Also known as "Space War" */ |
| 356 | SOFTWARE( spaceatb, spaceatt, 1982, "UA Ltd.", "Space Attack (alt 2)", 0, 0 ) /* Also known as "Space War" */ |
| 357 | SOFTWARE( spcemssn, 0, 1982, "UA Ltd.", "Space Mission", 0, 0 ) |
| 358 | SOFTWARE( spcerdrs, 0, 1982, "UA Ltd.", "Space Raiders", 0, 0 ) /* Also known as "Space Raider" */ |
| 359 | SOFTWARE( spcesqdn, 0, 1982, "UA Ltd.", "Space Squadron", 0, 0 ) /* Also known as "L'Escadron de L'Espace" */ |
| 360 | SOFTWARE( spcevult, 0, 1982, "UA Ltd.", "Space Vultures", 0, 0 ) |
| 361 | SOFTWARE( spiders, 0, 1982, "UA Ltd.", "Spiders", 0, 0 ) |
| 362 | SOFTWARE( starchss, 0, 1982, "UA Ltd.", "Star Chess", 0, 0 ) /* Also known as "Echec Etiles" or "Video Chess" */ |
| 363 | SOFTWARE( macross, 0, 1983, "Bandai", "Macross", 0, 0 ) /* Bandai Arcadia exclusive, Also known as "Super Dimension Fortress Macross" */ |
| 364 | SOFTWARE( superbug, 0, 198?, "UA Ltd.", "Super Bug", 0, 0 ) |
| 365 | SOFTWARE( superbga, superbug, 198?, "UA Ltd.", "Super Bug (alt)", 0, 0 ) |
| 366 | SOFTWARE( tnksalot, 0, 1982, "UA Ltd.", "Tanks a Lot", 0, 0 ) |
| 367 | SOFTWARE( theend, 0, 1982, "UA Ltd.", "The End", 0, 0 ) /* Also known as "Space Pirates" */ |
| 368 | SOFTWARE( turtles, 0, 1982, "UA Ltd.", "Turtles Turpin", 0, 0 ) /* Overdumped? */ |
| 369 | SOFTWARE_LIST_END |
| 370 | |
| 371 | |
| 372 | SOFTWARE_LIST( arcadia_cart, "Emerson Arcadia 2001 cartridges" ) |
src/mess/machine/i82371ab.c
| r7571 | r7572 | |
| 1 | | /***************************************************************************
|
| 2 | | |
| 3 | | Intel 82371AB PCI IDE ISA Xcelerator (PIIX4)
|
| 4 | | |
| 5 | | Part of the Intel 430TX chipset
|
| 6 | | |
| 7 | | - Integrated IDE Controller
|
| 8 | | - Enhanced DMA Controller based on two 82C37
|
| 9 | | - Interrupt Controller based on two 82C59
|
| 10 | | - Timers based on 82C54
|
| 11 | | - USB
|
| 12 | | - SMBus
|
| 13 | | - Real Time Clock based on MC146818
|
| 14 | | |
| 15 | | ***************************************************************************/
|
| 16 | | |
| 17 | | #include "emu.h"
|
| 18 | | #include "i82371ab.h"
|
| 19 | | |
| 20 | | |
| 21 | | /***************************************************************************
|
| 22 | | CONSTANTS
|
| 23 | | ***************************************************************************/
|
| 24 | | |
| 25 | | |
| 26 | | /***************************************************************************
|
| 27 | | TYPE DEFINITIONS
|
| 28 | | ***************************************************************************/
|
| 29 | | |
| 30 | | typedef struct _i82371ab_state i82371ab_state;
|
| 31 | | struct _i82371ab_state
|
| 32 | | {
|
| 33 | | UINT32 regs[4][0x100/4];
|
| 34 | | };
|
| 35 | | |
| 36 | | |
| 37 | | /*****************************************************************************
|
| 38 | | INLINE FUNCTIONS
|
| 39 | | *****************************************************************************/
|
| 40 | | |
| 41 | | INLINE i82371ab_state *get_safe_token(running_device *device)
|
| 42 | | {
|
| 43 | | assert(device != NULL);
|
| 44 | | assert(device->token != NULL);
|
| 45 | | assert(device->type == I82371AB);
|
| 46 | | |
| 47 | | return (i82371ab_state *)device->token;
|
| 48 | | }
|
| 49 | | |
| 50 | | |
| 51 | | /***************************************************************************
|
| 52 | | PCI INTERFACE
|
| 53 | | ***************************************************************************/
|
| 54 | | |
| 55 | | static UINT32 i82371ab_pci_isa_r(running_device *busdevice, running_device *device, int offset, UINT32 mem_mask)
|
| 56 | | {
|
| 57 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 58 | | UINT32 result = i82371ab->regs[0][offset];
|
| 59 | | |
| 60 | | logerror("i82371ab_pci_isa_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
|
| 61 | | |
| 62 | | return result;
|
| 63 | | }
|
| 64 | | |
| 65 | | void i82371ab_pci_isa_w(running_device *busdevice, running_device *device, int offset, UINT32 data, UINT32 mem_mask)
|
| 66 | | {
|
| 67 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 68 | | |
| 69 | | logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
|
| 70 | | |
| 71 | | switch (offset)
|
| 72 | | {
|
| 73 | | case 0x04:
|
| 74 | | COMBINE_DATA(&i82371ab->regs[0][offset]);
|
| 75 | | |
| 76 | | /* clear reserved bits */
|
| 77 | | i82371ab->regs[0][offset] &= 0x00000005;
|
| 78 | | |
| 79 | | /* set new status */
|
| 80 | | i82371ab->regs[0][offset] |= 0x02800000;
|
| 81 | | |
| 82 | | break;
|
| 83 | | }
|
| 84 | | }
|
| 85 | | |
| 86 | | static UINT32 i82371ab_pci_ide_r(running_device *busdevice, running_device *device, int offset, UINT32 mem_mask)
|
| 87 | | {
|
| 88 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 89 | | UINT32 result = i82371ab->regs[1][offset];
|
| 90 | | |
| 91 | | logerror("i82371ab_pci_ide_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
|
| 92 | | |
| 93 | | return result;
|
| 94 | | }
|
| 95 | | |
| 96 | | void i82371ab_pci_ide_w(running_device *busdevice, running_device *device, int offset, UINT32 data, UINT32 mem_mask)
|
| 97 | | {
|
| 98 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 99 | | |
| 100 | | logerror("i82371ab_pci_ide_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
|
| 101 | | |
| 102 | | switch (offset)
|
| 103 | | {
|
| 104 | | case 0x04:
|
| 105 | | COMBINE_DATA(&i82371ab->regs[1][offset]);
|
| 106 | | |
| 107 | | /* clear reserved bits */
|
| 108 | | i82371ab->regs[1][offset] &= 0x00000005;
|
| 109 | | |
| 110 | | /* set new status */
|
| 111 | | i82371ab->regs[1][offset] |= 0x02800000;
|
| 112 | | |
| 113 | | break;
|
| 114 | | }
|
| 115 | | }
|
| 116 | | |
| 117 | | static UINT32 i82371ab_pci_usb_r(running_device *busdevice, running_device *device, int offset, UINT32 mem_mask)
|
| 118 | | {
|
| 119 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 120 | | UINT32 result = i82371ab->regs[2][offset];
|
| 121 | | |
| 122 | | logerror("i82371ab_pci_usb_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
|
| 123 | | |
| 124 | | return result;
|
| 125 | | }
|
| 126 | | |
| 127 | | void i82371ab_pci_usb_w(running_device *busdevice, running_device *device, int offset, UINT32 data, UINT32 mem_mask)
|
| 128 | | {
|
| 129 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 130 | | |
| 131 | | logerror("i82371ab_pci_usb_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
|
| 132 | | |
| 133 | | switch (offset)
|
| 134 | | {
|
| 135 | | case 0x04:
|
| 136 | | COMBINE_DATA(&i82371ab->regs[2][offset]);
|
| 137 | | |
| 138 | | /* clear reserved bits */
|
| 139 | | i82371ab->regs[2][offset] &= 0x00000005;
|
| 140 | | |
| 141 | | /* set new status */
|
| 142 | | i82371ab->regs[2][offset] |= 0x02800000;
|
| 143 | | |
| 144 | | break;
|
| 145 | | }
|
| 146 | | }
|
| 147 | | |
| 148 | | static UINT32 i82371ab_pci_acpi_r(running_device *busdevice, running_device *device, int offset, UINT32 mem_mask)
|
| 149 | | {
|
| 150 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 151 | | UINT32 result = i82371ab->regs[3][offset];
|
| 152 | | |
| 153 | | logerror("i82371ab_pci_acpi_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
|
| 154 | | |
| 155 | | return result;
|
| 156 | | }
|
| 157 | | |
| 158 | | void i82371ab_pci_acpi_w(running_device *busdevice, running_device *device, int offset, UINT32 data, UINT32 mem_mask)
|
| 159 | | {
|
| 160 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 161 | | |
| 162 | | logerror("i82371ab_pci_acpi_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
|
| 163 | | |
| 164 | | switch (offset)
|
| 165 | | {
|
| 166 | | case 0x04:
|
| 167 | | COMBINE_DATA(&i82371ab->regs[3][offset]);
|
| 168 | | |
| 169 | | /* clear reserved bits */
|
| 170 | | i82371ab->regs[3][offset] &= 0x00000005;
|
| 171 | | |
| 172 | | /* set new status */
|
| 173 | | i82371ab->regs[3][offset] |= 0x02800000;
|
| 174 | | |
| 175 | | break;
|
| 176 | | }
|
| 177 | | }
|
| 178 | | |
| 179 | | UINT32 i82371ab_pci_read(running_device *busdevice, running_device *device, int function, int offset, UINT32 mem_mask)
|
| 180 | | {
|
| 181 | | switch (function)
|
| 182 | | {
|
| 183 | | case 0: return i82371ab_pci_isa_r(busdevice, device, offset, mem_mask);
|
| 184 | | case 1: return i82371ab_pci_ide_r(busdevice, device, offset, mem_mask);
|
| 185 | | case 2: return i82371ab_pci_usb_r(busdevice, device, offset, mem_mask);
|
| 186 | | case 3: return i82371ab_pci_acpi_r(busdevice, device, offset, mem_mask);
|
| 187 | | }
|
| 188 | | |
| 189 | | logerror("i82371ab_pci_read: read from undefined function %d\n", function);
|
| 190 | | |
| 191 | | return 0;
|
| 192 | | }
|
| 193 | | |
| 194 | | void i82371ab_pci_write(running_device *busdevice, running_device *device, int function, int offset, UINT32 data, UINT32 mem_mask)
|
| 195 | | {
|
| 196 | | switch (function)
|
| 197 | | {
|
| 198 | | case 0: i82371ab_pci_isa_w(busdevice, device, offset, data, mem_mask); break;
|
| 199 | | case 1: i82371ab_pci_ide_w(busdevice, device, offset, data, mem_mask); break;
|
| 200 | | case 2: i82371ab_pci_usb_w(busdevice, device, offset, data, mem_mask); break;
|
| 201 | | case 3: i82371ab_pci_acpi_w(busdevice, device, offset, data, mem_mask); break;
|
| 202 | | }
|
| 203 | | }
|
| 204 | | |
| 205 | | |
| 206 | | /*****************************************************************************
|
| 207 | | DEVICE INTERFACE
|
| 208 | | *****************************************************************************/
|
| 209 | | |
| 210 | | static DEVICE_START( i82371ab )
|
| 211 | | {
|
| 212 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 213 | | |
| 214 | | /* setup save states */
|
| 215 | | state_save_register_device_item_2d_array(device, 0, i82371ab->regs);
|
| 216 | | }
|
| 217 | | |
| 218 | | static DEVICE_RESET( i82371ab )
|
| 219 | | {
|
| 220 | | i82371ab_state *i82371ab = get_safe_token(device);
|
| 221 | | |
| 222 | | /* isa */
|
| 223 | | i82371ab->regs[0][0x00] = 0x71108086;
|
| 224 | | i82371ab->regs[0][0x04] = 0x00000000;
|
| 225 | | i82371ab->regs[0][0x08] = 0x06010000;
|
| 226 | | i82371ab->regs[0][0x0c] = 0x00800000;
|
| 227 | | |
| 228 | | /* ide */
|
| 229 | | i82371ab->regs[1][0x00] = 0x71118086;
|
| 230 | | i82371ab->regs[1][0x04] = 0x02800000;
|
| 231 | | i82371ab->regs[1][0x08] = 0x01018000;
|
| 232 | | i82371ab->regs[1][0x0c] = 0x00000000;
|
| 233 | | |
| 234 | | /* usb */
|
| 235 | | i82371ab->regs[2][0x00] = 0x71128086;
|
| 236 | | i82371ab->regs[2][0x04] = 0x02800000;
|
| 237 | | i82371ab->regs[2][0x08] = 0x0c030000;
|
| 238 | | i82371ab->regs[2][0x0c] = 0x00000000;
|
| 239 | | |
| 240 | | /* acpi */
|
| 241 | | i82371ab->regs[3][0x00] = 0x71138086;
|
| 242 | | i82371ab->regs[3][0x04] = 0x02800000;
|
| 243 | | i82371ab->regs[3][0x08] = 0x06800000;
|
| 244 | | i82371ab->regs[3][0x0c] = 0x02800000;
|
| 245 | | }
|
| 246 | | |
| 247 | | |
| 248 | | /***************************************************************************
|
| 249 | | DEVICE GETINFO
|
| 250 | | ***************************************************************************/
|
| 251 | | |
| 252 | | static const char DEVTEMPLATE_SOURCE[] = __FILE__;
|
| 253 | | |
| 254 | | #define DEVTEMPLATE_ID(p,s) p##i82371ab##s
|
| 255 | | #define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET
|
| 256 | | #define DEVTEMPLATE_NAME "Intel 82371AB"
|
| 257 | | #define DEVTEMPLATE_FAMILY "South Bridge"
|
| 258 | | #define DEVTEMPLATE_CLASS DEVICE_CLASS_OTHER
|
| 259 | | #define DEVTEMPLATE_VERSION "1.0"
|
| 260 | | #define DEVTEMPLATE_CREDITS "Copyright MESS Team"
|
| 261 | | #include "devtempl.h"
|
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Intel 82371AB PCI IDE ISA Xcelerator (PIIX4) |
| 4 | |
| 5 | Part of the Intel 430TX chipset |
| 6 | |
| 7 | - Integrated IDE Controller |
| 8 | - Enhanced DMA Controller based on two 82C37 |
| 9 | - Interrupt Controller based on two 82C59 |
| 10 | - Timers based on 82C54 |
| 11 | - USB |
| 12 | - SMBus |
| 13 | - Real Time Clock based on MC146818 |
| 14 | |
| 15 | ***************************************************************************/ |
| 16 | |
| 17 | #include "emu.h" |
| 18 | #include "i82371ab.h" |
| 19 | |
| 20 | |
| 21 | /*************************************************************************** |
| 22 | CONSTANTS |
| 23 | ***************************************************************************/ |
| 24 | |
| 25 | |
| 26 | /*************************************************************************** |
| 27 | TYPE DEFINITIONS |
| 28 | ***************************************************************************/ |
| 29 | |
| 30 | typedef struct _i82371ab_state i82371ab_state; |
| 31 | struct _i82371ab_state |
| 32 | { |
| 33 | UINT32 regs[4][0x100/4]; |
| 34 | }; |
| 35 | |
| 36 | |
| 37 | /***************************************************************************** |
| 38 | INLINE FUNCTIONS |
| 39 | *****************************************************************************/ |
| 40 | |
| 41 | INLINE i82371ab_state *get_safe_token(running_device *device) |
| 42 | { |
| 43 | assert(device != NULL); |
| 44 | assert(device->token != NULL); |
| 45 | assert(device->type == I82371AB); |
| 46 | |
| 47 | return (i82371ab_state *)device->token; |
| 48 | } |
| 49 | |
| 50 | |
| 51 | /*************************************************************************** |
| 52 | PCI INTERFACE |
| 53 | ***************************************************************************/ |
| 54 | |
| 55 | static UINT32 i82371ab_pci_isa_r(running_device *busdevice, running_device *device, int offset, UINT32 mem_mask) |
| 56 | { |
| 57 | i82371ab_state *i82371ab = get_safe_token(device); |
| 58 | UINT32 result = i82371ab->regs[0][offset]; |
| 59 | |
| 60 | logerror("i82371ab_pci_isa_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 61 | |
| 62 | return result; |
| 63 | } |
| 64 | |
| 65 | void i82371ab_pci_isa_w(running_device *busdevice, running_device *device, int offset, UINT32 data, UINT32 mem_mask) |
| 66 | { |
| 67 | i82371ab_state *i82371ab = get_safe_token(device); |
| 68 | |
| 69 | logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 70 | |
| 71 | switch (offset) |
| 72 | { |
| 73 | case 0x04: |
| 74 | COMBINE_DATA(&i82371ab->regs[0][offset]); |
| 75 | |
| 76 | /* clear reserved bits */ |
| 77 | i82371ab->regs[0][offset] &= 0x00000005; |
| 78 | |
| 79 | /* set new status */ |
| 80 | i82371ab->regs[0][offset] |= 0x02800000; |
| 81 | |
| 82 | break; |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | static UINT32 i82371ab_pci_ide_r(running_device *busdevice, running_device *device, int offset, UINT32 mem_mask) |
| 87 | { |
| 88 | i82371ab_state *i82371ab = get_safe_token(device); |
| 89 | UINT32 result = i82371ab->regs[1][offset]; |
| 90 | |
| 91 | logerror("i82371ab_pci_ide_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 92 | |
| 93 | return result; |
| 94 | } |
| 95 | |
| 96 | void i82371ab_pci_ide_w(running_device *busdevice, running_device *device, int offset, UINT32 data, UINT32 mem_mask) |
| 97 | { |
| 98 | i82371ab_state *i82371ab = get_safe_token(device); |
| 99 | |
| 100 | logerror("i82371ab_pci_ide_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 101 | |
| 102 | switch (offset) |
| 103 | { |
| 104 | case 0x04: |
| 105 | COMBINE_DATA(&i82371ab->regs[1][offset]); |
| 106 | |
| 107 | /* clear reserved bits */ |
| 108 | i82371ab->regs[1][offset] &= 0x00000005; |
| 109 | |
| 110 | /* set new status */ |
| 111 | i82371ab->regs[1][offset] |= 0x02800000; |
| 112 | |
| 113 | break; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | static UINT32 i82371ab_pci_usb_r(running_device *busdevice, running_device *device, int offset, UINT32 mem_mask) |
| 118 | { |
| 119 | i82371ab_state *i82371ab = get_safe_token(device); |
| 120 | UINT32 result = i82371ab->regs[2][offset]; |
| 121 | |
| 122 | logerror("i82371ab_pci_usb_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 123 | |
| 124 | return result; |
| 125 | } |
| 126 | |
| 127 | void i82371ab_pci_usb_w(running_device *busdevice, running_device *device, int offset, UINT32 data, UINT32 mem_mask) |
| 128 | { |
| 129 | i82371ab_state *i82371ab = get_safe_token(device); |
| 130 | |
| 131 | logerror("i82371ab_pci_usb_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 132 | |
| 133 | switch (offset) |
| 134 | { |
| 135 | case 0x04: |
| 136 | COMBINE_DATA(&i82371ab->regs[2][offset]); |
| 137 | |
| 138 | /* clear reserved bits */ |
| 139 | i82371ab->regs[2][offset] &= 0x00000005; |
| 140 | |
| 141 | /* set new status */ |
| 142 | i82371ab->regs[2][offset] |= 0x02800000; |
| 143 | |
| 144 | break; |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | static UINT32 i82371ab_pci_acpi_r(running_device *busdevice, running_device *device, int offset, UINT32 mem_mask) |
| 149 | { |
| 150 | i82371ab_state *i82371ab = get_safe_token(device); |
| 151 | UINT32 result = i82371ab->regs[3][offset]; |
| 152 | |
| 153 | logerror("i82371ab_pci_acpi_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 154 | |
| 155 | return result; |
| 156 | } |
| 157 | |
| 158 | void i82371ab_pci_acpi_w(running_device *busdevice, running_device *device, int offset, UINT32 data, UINT32 mem_mask) |
| 159 | { |
| 160 | i82371ab_state *i82371ab = get_safe_token(device); |
| 161 | |
| 162 | logerror("i82371ab_pci_acpi_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 163 | |
| 164 | switch (offset) |
| 165 | { |
| 166 | case 0x04: |
| 167 | COMBINE_DATA(&i82371ab->regs[3][offset]); |
| 168 | |
| 169 | /* clear reserved bits */ |
| 170 | i82371ab->regs[3][offset] &= 0x00000005; |
| 171 | |
| 172 | /* set new status */ |
| 173 | i82371ab->regs[3][offset] |= 0x02800000; |
| 174 | |
| 175 | break; |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | UINT32 i82371ab_pci_read(running_device *busdevice, running_device *device, int function, int offset, UINT32 mem_mask) |
| 180 | { |
| 181 | switch (function) |
| 182 | { |
| 183 | case 0: return i82371ab_pci_isa_r(busdevice, device, offset, mem_mask); |
| 184 | case 1: return i82371ab_pci_ide_r(busdevice, device, offset, mem_mask); |
| 185 | case 2: return i82371ab_pci_usb_r(busdevice, device, offset, mem_mask); |
| 186 | case 3: return i82371ab_pci_acpi_r(busdevice, device, offset, mem_mask); |
| 187 | } |
| 188 | |
| 189 | logerror("i82371ab_pci_read: read from undefined function %d\n", function); |
| 190 | |
| 191 | return 0; |
| 192 | } |
| 193 | |
| 194 | void i82371ab_pci_write(running_device *busdevice, running_device *device, int function, int offset, UINT32 data, UINT32 mem_mask) |
| 195 | { |
| 196 | switch (function) |
| 197 | { |
| 198 | case 0: i82371ab_pci_isa_w(busdevice, device, offset, data, mem_mask); break; |
| 199 | case 1: i82371ab_pci_ide_w(busdevice, device, offset, data, mem_mask); break; |
| 200 | case 2: i82371ab_pci_usb_w(busdevice, device, offset, data, mem_mask); break; |
| 201 | case 3: i82371ab_pci_acpi_w(busdevice, device, offset, data, mem_mask); break; |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | |
| 206 | /***************************************************************************** |
| 207 | DEVICE INTERFACE |
| 208 | *****************************************************************************/ |
| 209 | |
| 210 | static DEVICE_START( i82371ab ) |
| 211 | { |
| 212 | i82371ab_state *i82371ab = get_safe_token(device); |
| 213 | |
| 214 | /* setup save states */ |
| 215 | state_save_register_device_item_2d_array(device, 0, i82371ab->regs); |
| 216 | } |
| 217 | |
| 218 | static DEVICE_RESET( i82371ab ) |
| 219 | { |
| 220 | i82371ab_state *i82371ab = get_safe_token(device); |
| 221 | |
| 222 | /* isa */ |
| 223 | i82371ab->regs[0][0x00] = 0x71108086; |
| 224 | i82371ab->regs[0][0x04] = 0x00000000; |
| 225 | i82371ab->regs[0][0x08] = 0x06010000; |
| 226 | i82371ab->regs[0][0x0c] = 0x00800000; |
| 227 | |
| 228 | /* ide */ |
| 229 | i82371ab->regs[1][0x00] = 0x71118086; |
| 230 | i82371ab->regs[1][0x04] = 0x02800000; |
| 231 | i82371ab->regs[1][0x08] = 0x01018000; |
| 232 | i82371ab->regs[1][0x0c] = 0x00000000; |
| 233 | |
| 234 | /* usb */ |
| 235 | i82371ab->regs[2][0x00] = 0x71128086; |
| 236 | i82371ab->regs[2][0x04] = 0x02800000; |
| 237 | i82371ab->regs[2][0x08] = 0x0c030000; |
| 238 | i82371ab->regs[2][0x0c] = 0x00000000; |
| 239 | |
| 240 | /* acpi */ |
| 241 | i82371ab->regs[3][0x00] = 0x71138086; |
| 242 | i82371ab->regs[3][0x04] = 0x02800000; |
| 243 | i82371ab->regs[3][0x08] = 0x06800000; |
| 244 | i82371ab->regs[3][0x0c] = 0x02800000; |
| 245 | } |
| 246 | |
| 247 | |
| 248 | /*************************************************************************** |
| 249 | DEVICE GETINFO |
| 250 | ***************************************************************************/ |
| 251 | |
| 252 | static const char DEVTEMPLATE_SOURCE[] = __FILE__; |
| 253 | |
| 254 | #define DEVTEMPLATE_ID(p,s) p##i82371ab##s |
| 255 | #define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET |
| 256 | #define DEVTEMPLATE_NAME "Intel 82371AB" |
| 257 | #define DEVTEMPLATE_FAMILY "South Bridge" |
| 258 | #define DEVTEMPLATE_CLASS DEVICE_CLASS_OTHER |
| 259 | #define DEVTEMPLATE_VERSION "1.0" |
| 260 | #define DEVTEMPLATE_CREDITS "Copyright MESS Team" |
| 261 | #include "devtempl.h" |
src/mess/machine/scsibus.c
| r7571 | r7572 | |
| 1 | | /*
|
| 2 | | SCSIBus.c
|
| 3 | | |
| 4 | | Implementation of a raw SCSI/SASI bus for machines that don't use a SCSI
|
| 5 | | controler chip such as the RM Nimbus, which implements it as a bunch of
|
| 6 | | 74LS series chips.
|
| 7 | | |
| 8 | | */
|
| 9 | | |
| 10 | | #include "emu.h"
|
| 11 | | #include "machine/scsi.h"
|
| 12 | | #include "machine/scsibus.h"
|
| 13 | | |
| 14 | | /* LOGLEVEL 0=no logging, 1=just commands and data, 2=everything ! */
|
| 15 | | |
| 16 | | #define LOGLEVEL 0
|
| 17 | | |
| 18 | | #define LOG(level,...) if(LOGLEVEL>=level) logerror(__VA_ARGS__)
|
| 19 | | |
| 20 | | typedef struct _scsibus_t scsibus_t;
|
| 21 | | struct _scsibus_t
|
| 22 | | {
|
| 23 | | SCSIInstance *devices[8];
|
| 24 | | const SCSIBus_interface *interface;
|
| 25 | | |
| 26 | | UINT8 linestate;
|
| 27 | | UINT8 last_id;
|
| 28 | | UINT8 phase;
|
| 29 | | |
| 30 | | UINT8 command[CMD_BUF_SIZE];
|
| 31 | | UINT8 cmd_idx;
|
| 32 | | UINT8 is_linked;
|
| 33 | | |
| 34 | | UINT8 data[DATA_BUF_SIZE+RW_BUFFER_HEAD_BYTES];
|
| 35 | | UINT16 data_idx;
|
| 36 | | int xfer_count;
|
| 37 | | int bytes_left;
|
| 38 | | int data_last;
|
| 39 | | |
| 40 | | emu_timer *req_timer;
|
| 41 | | emu_timer *ack_timer;
|
| 42 | | |
| 43 | | UINT8 initialised;
|
| 44 | | };
|
| 45 | | |
| 46 | | static void set_scsi_line_now(running_device *device, UINT8 line, UINT8 state);
|
| 47 | | static void set_scsi_line_ack(running_device *device, UINT8 state);
|
| 48 | | static void scsi_in_line_changed(running_device *device, UINT8 line, UINT8 state);
|
| 49 | | static void scsi_out_line_change(running_device *device, UINT8 line, UINT8 state);
|
| 50 | | static void scsi_out_line_change_now(running_device *device, UINT8 line, UINT8 state);
|
| 51 | | static void scsi_out_line_req(running_device *device, UINT8 state);
|
| 52 | | static TIMER_CALLBACK(req_timer_callback);
|
| 53 | | static TIMER_CALLBACK(ack_timer_callback);
|
| 54 | | static void scsi_change_phase(running_device *device, UINT8 newphase);
|
| 55 | | |
| 56 | | static const char *const linenames[] =
|
| 57 | | {
|
| 58 | | "select", "busy", "request", "acknoledge", "C/D", "I/O", "message", "reset"
|
| 59 | | };
|
| 60 | | |
| 61 | | static const char *const phasenames[] =
|
| 62 | | {
|
| 63 | | "data out", "data in", "command", "status", "none", "none", "message out", "message in", "bus free","select"
|
| 64 | | };
|
| 65 | | |
| 66 | | INLINE scsibus_t *get_token(running_device *device)
|
| 67 | | {
|
| 68 | | assert(device->type == SCSIBUS);
|
| 69 | | return (scsibus_t *) device->token;
|
| 70 | | }
|
| 71 | | |
| 72 | | static void scsibus_read_data(scsibus_t *bus)
|
| 73 | | {
|
| 74 | | bus->data_last = (bus->bytes_left >= DATA_BUF_SIZE) ? DATA_BUF_SIZE : bus->bytes_left;
|
| 75 | | |
| 76 | | LOG(1,"SCSIBUS:scsibus_read_data bus->bytes_left=%04X, bus->data_last=%04X, bus->xfer_count=%04X\n",bus->bytes_left,bus->data_last,bus->xfer_count);
|
| 77 | | |
| 78 | | if (bus->data_last > 0)
|
| 79 | | {
|
| 80 | | SCSIReadData(bus->devices[bus->last_id], bus->data, bus->data_last);
|
| 81 | | bus->bytes_left-=bus->data_last;
|
| 82 | | bus->data_idx=0;
|
| 83 | | }
|
| 84 | | }
|
| 85 | | |
| 86 | | static void scsibus_write_data(scsibus_t *bus)
|
| 87 | | {
|
| 88 | | if(bus->bytes_left >= DATA_BUF_SIZE)
|
| 89 | | {
|
| 90 | | SCSIWriteData(bus->devices[bus->last_id], bus->data, DATA_BUF_SIZE);
|
| 91 | | |
| 92 | | bus->bytes_left-=DATA_BUF_SIZE;
|
| 93 | | bus->data_idx=0;
|
| 94 | | }
|
| 95 | | }
|
| 96 | | |
| 97 | | /* SCSI Bus read/write */
|
| 98 | | |
| 99 | | UINT8 scsi_data_r(running_device *device)
|
| 100 | | {
|
| 101 | | scsibus_t *bus = get_token(device);
|
| 102 | | UINT8 result = 0;
|
| 103 | | |
| 104 | | switch (bus->phase)
|
| 105 | | {
|
| 106 | | case SCSI_PHASE_DATAIN :
|
| 107 | | result=bus->data[bus->data_idx++];
|
| 108 | | |
| 109 | | // check to see if we have reached the end of the block buffer
|
| 110 | | // and that there is more data to read from the scsi disk
|
| 111 | | if((bus->data_idx==DATA_BUF_SIZE) && (bus->bytes_left>0) && IS_READ_COMMAND())
|
| 112 | | {
|
| 113 | | scsibus_read_data(bus);
|
| 114 | | }
|
| 115 | | break;
|
| 116 | | |
| 117 | | case SCSI_PHASE_STATUS :
|
| 118 | | result=0; // no errors for the time being !
|
| 119 | | bus->cmd_idx++;
|
| 120 | | break;
|
| 121 | | |
| 122 | | case SCSI_PHASE_MESSAGE_IN :
|
| 123 | | result=0; // no errors for the time being !
|
| 124 | | bus->cmd_idx++;
|
| 125 | | break;
|
| 126 | | }
|
| 127 | | |
| 128 | | LOG(2,"scsi_data_r : phase=%s, data_idx=%d, cmd_idx=%d\n",phasenames[bus->phase],bus->data_idx,bus->cmd_idx);
|
| 129 | | return result;
|
| 130 | | }
|
| 131 | | |
| 132 | | void scsi_data_w(running_device *device, UINT8 data)
|
| 133 | | {
|
| 134 | | scsibus_t *bus = get_token(device);
|
| 135 | | |
| 136 | | switch (bus->phase)
|
| 137 | | {
|
| 138 | | // Note this assumes we only have one initiator and therefore
|
| 139 | | // only one line active.
|
| 140 | | case SCSI_PHASE_BUS_FREE :
|
| 141 | | bus->last_id=driveno(data);
|
| 142 | | break;
|
| 143 | | |
| 144 | | case SCSI_PHASE_COMMAND :
|
| 145 | | bus->command[bus->cmd_idx++]=data;
|
| 146 | | break;
|
| 147 | | |
| 148 | | case SCSI_PHASE_DATAOUT :
|
| 149 | | |
| 150 | | //LOG(1,"SCSIBUS:xfer_count=%02X, bytes_left=%02X data_idx=%02X\n",bus->xfer_count,bus->bytes_left,bus->data_idx);
|
| 151 | | |
| 152 | | // Write (blocks) and write buffer, just buffer it
|
| 153 | | if(IS_WRITE_COMMAND() || IS_COMMAND(SCSI_CMD_BUFFER_WRITE) || IS_COMMAND(SCSI_CMD_MODE_SELECT))
|
| 154 | | bus->data[bus->data_idx++]=data;
|
| 155 | | |
| 156 | | if(IS_COMMAND(SCSI_CMD_FORMAT_UNIT))
|
| 157 | | {
|
| 158 | | // Only store the first 4 bytes of the bad block list (the header)
|
| 159 | | if(bus->data_idx<4)
|
| 160 | | bus->data[bus->data_idx++]=data;
|
| 161 | | else
|
| 162 | | bus->data_idx++;
|
| 163 | | |
| 164 | | // When we have the first 3 bytes, calculate how many more are in the
|
| 165 | | // bad block list.
|
| 166 | | if(bus->data_idx==3)
|
| 167 | | {
|
| 168 | | bus->xfer_count+=((bus->data[2]<<8)+bus->data[3]);
|
| 169 | | bus->data_last=bus->xfer_count;
|
| 170 | | }
|
| 171 | | }
|
| 172 | | |
| 173 | | // If the data buffer is full, and we are writing blocks flush it to the SCSI disk
|
| 174 | | if((bus->data_idx == DATA_BUF_SIZE) && IS_WRITE_COMMAND())
|
| 175 | | scsibus_write_data(bus);
|
| 176 | | break;
|
| 177 | | }
|
| 178 | | }
|
| 179 | | |
| 180 | | /* Get/Set lines */
|
| 181 | | |
| 182 | | UINT8 get_scsi_lines(running_device *device)
|
| 183 | | {
|
| 184 | | scsibus_t *bus = get_token(device);
|
| 185 | | |
| 186 | | return bus->linestate;
|
| 187 | | }
|
| 188 | | |
| 189 | | UINT8 get_scsi_line(running_device *device, UINT8 lineno)
|
| 190 | | {
|
| 191 | | scsibus_t *bus = get_token(device);
|
| 192 | | UINT8 result=0;
|
| 193 | | |
| 194 | | switch (lineno)
|
| 195 | | {
|
| 196 | | case SCSI_LINE_SEL : result=(bus->linestate & (1<<SCSI_LINE_SEL)) >> SCSI_LINE_SEL;
|
| 197 | | case SCSI_LINE_BSY : result=(bus->linestate & (1<<SCSI_LINE_BSY)) >> SCSI_LINE_BSY;
|
| 198 | | case SCSI_LINE_REQ : result=(bus->linestate & (1<<SCSI_LINE_REQ)) >> SCSI_LINE_REQ;
|
| 199 | | case SCSI_LINE_ACK : result=(bus->linestate & (1<<SCSI_LINE_ACK)) >> SCSI_LINE_ACK;
|
| 200 | | case SCSI_LINE_CD : result=(bus->linestate & (1<<SCSI_LINE_CD )) >> SCSI_LINE_CD;
|
| 201 | | case SCSI_LINE_IO : result=(bus->linestate & (1<<SCSI_LINE_IO )) >> SCSI_LINE_IO;
|
| 202 | | case SCSI_LINE_MSG : result=(bus->linestate & (1<<SCSI_LINE_MSG)) >> SCSI_LINE_MSG;
|
| 203 | | case SCSI_LINE_RESET : result=(bus->linestate & (1<<SCSI_LINE_RESET)) >> SCSI_LINE_RESET;
|
| 204 | | }
|
| 205 | | |
| 206 | | LOG(2,"get_scsi_line(%s)=%d\n",linenames[lineno],result);
|
| 207 | | |
| 208 | | return result;
|
| 209 | | }
|
| 210 | | |
| 211 | | void set_scsi_line(running_device *device, UINT8 line, UINT8 state)
|
| 212 | | {
|
| 213 | | scsibus_t *bus = get_token(device);
|
| 214 | | UINT8 changed;
|
| 215 | | |
| 216 | | changed = ((bus->linestate & (1<<line)) != (state << line));
|
| 217 | | |
| 218 | | LOG(2,"set_scsi_line(%s,%d), changed=%d, linestate=%02X\n",linenames[line],state,changed,bus->linestate);
|
| 219 | | |
| 220 | | if(changed)
|
| 221 | | {
|
| 222 | | if (line==SCSI_LINE_ACK)
|
| 223 | | set_scsi_line_ack(device,state);
|
| 224 | | else
|
| 225 | | set_scsi_line_now(device,line,state);
|
| 226 | | }
|
| 227 | | }
|
| 228 | | |
| 229 | | static void set_scsi_line_now(running_device *device, UINT8 line, UINT8 state)
|
| 230 | | {
|
| 231 | | scsibus_t *bus = get_token(device);
|
| 232 | | |
| 233 | | if(state)
|
| 234 | | bus->linestate |= (1<<line);
|
| 235 | | else
|
| 236 | | bus->linestate &= ~(1<<line);
|
| 237 | | |
| 238 | | scsi_in_line_changed(device,line,state);
|
| 239 | | }
|
| 240 | | |
| 241 | | void set_scsi_line_ack(running_device *device, UINT8 state)
|
| 242 | | {
|
| 243 | | scsibus_t *bus = get_token(device);
|
| 244 | | |
| 245 | | timer_adjust_oneshot(bus->ack_timer,ATTOTIME_IN_NSEC(ACK_DELAY_NS),state);
|
| 246 | | }
|
| 247 | | |
| 248 | | void dump_command_bytes(scsibus_t *bus)
|
| 249 | | {
|
| 250 | | int byteno;
|
| 251 | | |
| 252 | | logerror("sending command 0x%02X to ScsiID %d\n",bus->command[0],bus->last_id);
|
| 253 | | |
| 254 | | for(byteno=0; byteno<bus->cmd_idx; byteno++)
|
| 255 | | {
|
| 256 | | logerror("%02X ",bus->command[byteno]);
|
| 257 | | }
|
| 258 | | logerror("\n\n");
|
| 259 | | }
|
| 260 | | |
| 261 | | static void scsibus_exec_command(running_device *device)
|
| 262 | | {
|
| 263 | | scsibus_t *bus = get_token(device);
|
| 264 | | int command_local = 0;
|
| 265 | | int newphase;
|
| 266 | | |
| 267 | | if(LOGLEVEL)
|
| 268 | | dump_command_bytes(bus);
|
| 269 | | |
| 270 | | bus->is_linked=bus->command[bus->cmd_idx-1] & 0x01;
|
| 271 | | |
| 272 | | // Check for locally executed commands, and if found execute them
|
| 273 | | switch (bus->command[0])
|
| 274 | | {
|
| 275 | | // Format unit
|
| 276 | | case SCSI_CMD_FORMAT_UNIT :
|
| 277 | | LOG(1,"SCSIBUS: format unit bus->command[1]=%02X & 0x10\n",(bus->command[1] & 0x10));
|
| 278 | | command_local=1;
|
| 279 | | if((bus->command[1] & 0x10)==0x10)
|
| 280 | | SCSISetPhase(bus->devices[bus->last_id],SCSI_PHASE_DATAOUT);
|
| 281 | | else
|
| 282 | | SCSISetPhase(bus->devices[bus->last_id],SCSI_PHASE_STATUS);
|
| 283 | | |
| 284 | | bus->xfer_count=4;
|
| 285 | | bus->data_last=bus->xfer_count;
|
| 286 | | bus->bytes_left=0;
|
| 287 | | break;
|
| 288 | | |
| 289 | | case SCSI_CMD_READ_DEFECT :
|
| 290 | | LOG(1,"SCSIBUS: read defect list\n");
|
| 291 | | command_local=1;
|
| 292 | | |
| 293 | | bus->data[0] = 0x00;
|
| 294 | | bus->data[1] = bus->command[2];
|
| 295 | | bus->data[3] = 0x00; // defect list len msb
|
| 296 | | bus->data[4] = 0x00; // defect list len lsb
|
| 297 | | |
| 298 | | bus->xfer_count=4;
|
| 299 | | bus->data_last=bus->xfer_count;
|
| 300 | | bus->bytes_left=0;
|
| 301 | | SCSISetPhase(bus->devices[bus->last_id], SCSI_PHASE_DATAIN );
|
| 302 | | break;
|
| 303 | | |
| 304 | | // write buffer
|
| 305 | | case SCSI_CMD_BUFFER_WRITE :
|
| 306 | | LOG(1,"SCSIBUS: write_buffer\n");
|
| 307 | | command_local=1;
|
| 308 | | bus->xfer_count=(bus->command[7]<<8)+bus->command[8];
|
| 309 | | bus->data_last=bus->xfer_count;
|
| 310 | | bus->bytes_left=0;
|
| 311 | | SCSISetPhase(bus->devices[bus->last_id],SCSI_PHASE_DATAOUT);
|
| 312 | | break;
|
| 313 | | |
| 314 | | // read buffer
|
| 315 | | case SCSI_CMD_BUFFER_READ :
|
| 316 | | LOG(1,"SCSIBUS: read_buffer\n");
|
| 317 | | command_local=1;
|
| 318 | | bus->xfer_count=(bus->command[7]<<8)+bus->command[8];
|
| 319 | | bus->data_last=bus->xfer_count;
|
| 320 | | bus->bytes_left=0;
|
| 321 | | SCSISetPhase(bus->devices[bus->last_id],SCSI_PHASE_DATAIN);
|
| 322 | | break;
|
| 323 | | }
|
| 324 | | |
| 325 | | |
| 326 | | // Check for locally executed command, if not then pass it on
|
| 327 | | // to the disk driver
|
| 328 | | if(!command_local)
|
| 329 | | {
|
| 330 | | SCSISetCommand(bus->devices[bus->last_id], bus->command, bus->cmd_idx);
|
| 331 | | SCSIExecCommand(bus->devices[bus->last_id], &bus->xfer_count);
|
| 332 | | bus->bytes_left=bus->xfer_count;
|
| 333 | | bus->data_last=bus->xfer_count;
|
| 334 | | bus->data_idx=0;
|
| 335 | | }
|
| 336 | | |
| 337 | | SCSIGetPhase(bus->devices[bus->last_id], &newphase);
|
| 338 | | |
| 339 | | scsi_change_phase(device,newphase);
|
| 340 | | |
| 341 | | LOG(1,"SCSIBUS:xfer_count=%02X, bytes_left=%02X data_idx=%02X\n",bus->xfer_count,bus->bytes_left,bus->data_idx);
|
| 342 | | |
| 343 | | // This is correct as we need to read from disk for commands other than just read data
|
| 344 | | if ((bus->phase == SCSI_PHASE_DATAIN) && (!command_local))
|
| 345 | | scsibus_read_data(bus);
|
| 346 | | }
|
| 347 | | |
| 348 | | static int datain_done(scsibus_t *bus)
|
| 349 | | {
|
| 350 | | int result=0;
|
| 351 | | |
| 352 | | // Read data commands
|
| 353 | | if(IS_READ_COMMAND() && (bus->data_idx == bus->data_last) && (bus->bytes_left == 0))
|
| 354 | | result=1;
|
| 355 | | else if (bus->data_idx==bus->data_last)
|
| 356 | | result=1;
|
| 357 | | |
| 358 | | return result;
|
| 359 | | }
|
| 360 | | |
| 361 | | static int dataout_done(scsibus_t *bus)
|
| 362 | | {
|
| 363 | | int result=0;
|
| 364 | | |
| 365 | | // Write data commands
|
| 366 | | if(IS_WRITE_COMMAND() && (bus->data_idx == 0) && (bus->bytes_left == 0))
|
| 367 | | result=1;
|
| 368 | | else if (bus->data_idx==bus->data_last)
|
| 369 | | result=1;
|
| 370 | | |
| 371 | | return result;
|
| 372 | | }
|
| 373 | | |
| 374 | | static void scsi_in_line_changed(running_device *device, UINT8 line, UINT8 state)
|
| 375 | | {
|
| 376 | | scsibus_t *bus = get_token(device);
|
| 377 | | |
| 378 | | // Reset aborts and returns to bus free
|
| 379 | | if((line==SCSI_LINE_RESET) && (state==0))
|
| 380 | | {
|
| 381 | | scsi_change_phase(device,SCSI_PHASE_BUS_FREE);
|
| 382 | | bus->cmd_idx=0;
|
| 383 | | bus->data_idx=0;
|
| 384 | | bus->is_linked=0;
|
| 385 | | |
| 386 | | return;
|
| 387 | | }
|
| 388 | | |
| 389 | | switch (bus->phase)
|
| 390 | | {
|
| 391 | | case SCSI_PHASE_BUS_FREE :
|
| 392 | | if((line==SCSI_LINE_SEL) && (bus->devices[bus->last_id]!=NULL))
|
| 393 | | {
|
| 394 | | if(state==0)
|
| 395 | | scsi_out_line_change(device,SCSI_LINE_BSY,0);
|
| 396 | | else
|
| 397 | | scsi_change_phase(device,SCSI_PHASE_COMMAND);
|
| 398 | | }
|
| 399 | | break;
|
| 400 | | |
| 401 | | case SCSI_PHASE_COMMAND :
|
| 402 | | if(line==SCSI_LINE_ACK)
|
| 403 | | {
|
| 404 | | if(state)
|
| 405 | | {
|
| 406 | | // If the command is ready go and execute it
|
| 407 | | if(bus->cmd_idx==get_scsi_cmd_len(bus->command[0]))
|
| 408 | | {
|
| 409 | | scsibus_exec_command(device);
|
| 410 | | }
|
| 411 | | else
|
| 412 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 413 | | }
|
| 414 | | else
|
| 415 | | scsi_out_line_change(device,SCSI_LINE_REQ,1);
|
| 416 | | }
|
| 417 | | break;
|
| 418 | | |
| 419 | | case SCSI_PHASE_DATAIN :
|
| 420 | | if(line==SCSI_LINE_ACK)
|
| 421 | | {
|
| 422 | | if(state)
|
| 423 | | {
|
| 424 | | if(datain_done(bus))
|
| 425 | | scsi_change_phase(device,SCSI_PHASE_STATUS);
|
| 426 | | else
|
| 427 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 428 | | }
|
| 429 | | else
|
| 430 | | scsi_out_line_change(device,SCSI_LINE_REQ,1);
|
| 431 | | }
|
| 432 | | break;
|
| 433 | | |
| 434 | | case SCSI_PHASE_DATAOUT :
|
| 435 | | if(line==SCSI_LINE_ACK)
|
| 436 | | {
|
| 437 | | if(state)
|
| 438 | | {
|
| 439 | | if(dataout_done(bus))
|
| 440 | | scsi_change_phase(device,SCSI_PHASE_STATUS);
|
| 441 | | else
|
| 442 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 443 | | }
|
| 444 | | else
|
| 445 | | scsi_out_line_change(device,SCSI_LINE_REQ,1);
|
| 446 | | }
|
| 447 | | break;
|
| 448 | | |
| 449 | | case SCSI_PHASE_STATUS :
|
| 450 | | if(line==SCSI_LINE_ACK)
|
| 451 | | {
|
| 452 | | if(state)
|
| 453 | | {
|
| 454 | | if(bus->cmd_idx > 0)
|
| 455 | | {
|
| 456 | | scsi_change_phase(device,SCSI_PHASE_MESSAGE_IN);
|
| 457 | | }
|
| 458 | | else
|
| 459 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 460 | | }
|
| 461 | | else
|
| 462 | | scsi_out_line_change(device,SCSI_LINE_REQ,1);
|
| 463 | | }
|
| 464 | | break;
|
| 465 | | |
| 466 | | case SCSI_PHASE_MESSAGE_IN :
|
| 467 | | if(line==SCSI_LINE_ACK)
|
| 468 | | {
|
| 469 | | if(state)
|
| 470 | | {
|
| 471 | | if(bus->cmd_idx > 0)
|
| 472 | | {
|
| 473 | | if(bus->is_linked)
|
| 474 | | scsi_change_phase(device,SCSI_PHASE_COMMAND);
|
| 475 | | else
|
| 476 | | scsi_change_phase(device,SCSI_PHASE_BUS_FREE);
|
| 477 | | }
|
| 478 | | else
|
| 479 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 480 | | }
|
| 481 | | else
|
| 482 | | scsi_out_line_change(device,SCSI_LINE_REQ,1);
|
| 483 | | }
|
| 484 | | break;
|
| 485 | | }
|
| 486 | | }
|
| 487 | | |
| 488 | | static void scsi_out_line_change(running_device *device, UINT8 line, UINT8 state)
|
| 489 | | {
|
| 490 | | if(line==SCSI_LINE_REQ)
|
| 491 | | scsi_out_line_req(device,state);
|
| 492 | | else
|
| 493 | | scsi_out_line_change_now(device,line,state);
|
| 494 | | }
|
| 495 | | |
| 496 | | static void scsi_out_line_change_now(running_device *device, UINT8 line, UINT8 state)
|
| 497 | | {
|
| 498 | | scsibus_t *bus = get_token(device);
|
| 499 | | |
| 500 | | if(state)
|
| 501 | | bus->linestate |= (1<<line);
|
| 502 | | else
|
| 503 | | bus->linestate &= ~(1<<line);
|
| 504 | | |
| 505 | | LOG(2,"scsi_out_line_change(%s,%d)\n",linenames[line],state);
|
| 506 | | |
| 507 | | if(bus->interface->line_change_cb!=NULL)
|
| 508 | | bus->interface->line_change_cb(device,line,state);
|
| 509 | | }
|
| 510 | | |
| 511 | | static void scsi_out_line_req(running_device *device, UINT8 state)
|
| 512 | | {
|
| 513 | | scsibus_t *bus = get_token(device);
|
| 514 | | |
| 515 | | timer_adjust_oneshot(bus->req_timer,ATTOTIME_IN_NSEC(REQ_DELAY_NS),state);
|
| 516 | | }
|
| 517 | | |
| 518 | | |
| 519 | | static TIMER_CALLBACK(req_timer_callback)
|
| 520 | | {
|
| 521 | | scsi_out_line_change_now((running_device *)ptr, SCSI_LINE_REQ, param);
|
| 522 | | }
|
| 523 | | |
| 524 | | static TIMER_CALLBACK(ack_timer_callback)
|
| 525 | | {
|
| 526 | | set_scsi_line_now((running_device *)ptr, SCSI_LINE_ACK, param);
|
| 527 | | }
|
| 528 | | |
| 529 | | |
| 530 | | UINT8 get_scsi_phase(running_device *device)
|
| 531 | | {
|
| 532 | | scsibus_t *bus = get_token(device);
|
| 533 | | |
| 534 | | return bus->phase;
|
| 535 | | }
|
| 536 | | |
| 537 | | |
| 538 | | static void scsi_change_phase(running_device *device, UINT8 newphase)
|
| 539 | | {
|
| 540 | | scsibus_t *bus = get_token(device);
|
| 541 | | |
| 542 | | LOG(1,"scsi_change_phase() from=%s, to=%s\n",phasenames[bus->phase],phasenames[newphase]);
|
| 543 | | |
| 544 | | bus->phase=newphase;
|
| 545 | | bus->cmd_idx=0;
|
| 546 | | bus->data_idx=0;
|
| 547 | | |
| 548 | | switch(bus->phase)
|
| 549 | | {
|
| 550 | | case SCSI_PHASE_BUS_FREE :
|
| 551 | | scsi_out_line_change(device,SCSI_LINE_CD,1);
|
| 552 | | scsi_out_line_change(device,SCSI_LINE_IO,1);
|
| 553 | | scsi_out_line_change(device,SCSI_LINE_MSG,1);
|
| 554 | | scsi_out_line_change(device,SCSI_LINE_REQ,1);
|
| 555 | | scsi_out_line_change(device,SCSI_LINE_BSY,1);
|
| 556 | | break;
|
| 557 | | |
| 558 | | case SCSI_PHASE_COMMAND :
|
| 559 | | scsi_out_line_change(device,SCSI_LINE_CD,0);
|
| 560 | | scsi_out_line_change(device,SCSI_LINE_IO,1);
|
| 561 | | scsi_out_line_change(device,SCSI_LINE_MSG,1);
|
| 562 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 563 | | break;
|
| 564 | | |
| 565 | | case SCSI_PHASE_DATAOUT :
|
| 566 | | scsi_out_line_change(device,SCSI_LINE_CD,1);
|
| 567 | | scsi_out_line_change(device,SCSI_LINE_IO,1);
|
| 568 | | scsi_out_line_change(device,SCSI_LINE_MSG,1);
|
| 569 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 570 | | break;
|
| 571 | | |
| 572 | | case SCSI_PHASE_DATAIN :
|
| 573 | | scsi_out_line_change(device,SCSI_LINE_CD,1);
|
| 574 | | scsi_out_line_change(device,SCSI_LINE_IO,0);
|
| 575 | | scsi_out_line_change(device,SCSI_LINE_MSG,1);
|
| 576 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 577 | | break;
|
| 578 | | |
| 579 | | case SCSI_PHASE_STATUS :
|
| 580 | | scsi_out_line_change(device,SCSI_LINE_CD,0);
|
| 581 | | scsi_out_line_change(device,SCSI_LINE_IO,0);
|
| 582 | | scsi_out_line_change(device,SCSI_LINE_MSG,1);
|
| 583 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 584 | | break;
|
| 585 | | |
| 586 | | case SCSI_PHASE_MESSAGE_OUT :
|
| 587 | | scsi_out_line_change(device,SCSI_LINE_CD,0);
|
| 588 | | scsi_out_line_change(device,SCSI_LINE_IO,1);
|
| 589 | | scsi_out_line_change(device,SCSI_LINE_MSG,0);
|
| 590 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 591 | | break;
|
| 592 | | |
| 593 | | case SCSI_PHASE_MESSAGE_IN :
|
| 594 | | scsi_out_line_change(device,SCSI_LINE_CD,0);
|
| 595 | | scsi_out_line_change(device,SCSI_LINE_IO,0);
|
| 596 | | scsi_out_line_change(device,SCSI_LINE_MSG,0);
|
| 597 | | scsi_out_line_change(device,SCSI_LINE_REQ,0);
|
| 598 | | break;
|
| 599 | | }
|
| 600 | | }
|
| 601 | | |
| 602 | | UINT8 driveno(UINT8 drivesel)
|
| 603 | | {
|
| 604 | | switch (drivesel)
|
| 605 | | {
|
| 606 | | case 0x01 : return 0;
|
| 607 | | case 0x02 : return 1;
|
| 608 | | case 0x04 : return 2;
|
| 609 | | case 0x08 : return 3;
|
| 610 | | case 0x10 : return 4;
|
| 611 | | case 0x20 : return 5;
|
| 612 | | case 0x40 : return 6;
|
| 613 | | case 0x80 : return 7;
|
| 614 | | default : return 0;
|
| 615 | | }
|
| 616 | | }
|
| 617 | | |
| 618 | | // get the length of a SCSI command based on it's command byte type
|
| 619 | | int get_scsi_cmd_len(int cbyte)
|
| 620 | | {
|
| 621 | | int group;
|
| 622 | | |
| 623 | | group = (cbyte>>5) & 7;
|
| 624 | | |
| 625 | | if (group == 0) return 6;
|
| 626 | | if (group == 1 || group == 2) return 10;
|
| 627 | | if (group == 5) return 12;
|
| 628 | | |
| 629 | | fatalerror("scsibus: Unknown SCSI command group %d\n", group);
|
| 630 | | |
| 631 | | return 6;
|
| 632 | | }
|
| 633 | | |
| 634 | | void init_scsibus(running_device *device)
|
| 635 | | {
|
| 636 | | scsibus_t *bus = get_token(device);
|
| 637 | | const SCSIConfigTable *scsidevs = bus->interface->scsidevs;
|
| 638 | | int devno;
|
| 639 | | |
| 640 | | if(!bus->initialised)
|
| 641 | | {
|
| 642 | | // try to open the devices
|
| 643 | | for (devno = 0; devno < scsidevs->devs_present; devno++)
|
| 644 | | {
|
| 645 | | LOG(1,"init_scsibus devno=%d \n",devno);
|
| 646 | | SCSIAllocInstance( device->machine, scsidevs->devices[devno].scsiClass, &bus->devices[scsidevs->devices[devno].scsiID], scsidevs->devices[devno].diskregion );
|
| 647 | | }
|
| 648 | | |
| 649 | | bus->initialised=1;
|
| 650 | | }
|
| 651 | | }
|
| 652 | | |
| 653 | | static DEVICE_START( scsibus )
|
| 654 | | {
|
| 655 | | scsibus_t *bus = get_token(device);
|
| 656 | | |
| 657 | | assert(device->baseconfig().static_config != NULL);
|
| 658 | | bus->interface = (const SCSIBus_interface*)device->baseconfig().static_config;
|
| 659 | | |
| 660 | | memset(bus->devices, 0, sizeof(bus->devices));
|
| 661 | | |
| 662 | | // Flag not initialised
|
| 663 | | bus->initialised=0;
|
| 664 | | |
| 665 | | // All lines start high - inactive
|
| 666 | | bus->linestate=0xFF;
|
| 667 | | |
| 668 | | // Start with bus free
|
| 669 | | bus->phase=SCSI_PHASE_BUS_FREE;
|
| 670 | | |
| 671 | | // Setup req/ack timers
|
| 672 | | bus->req_timer=timer_alloc(device->machine, req_timer_callback, (void *)device);
|
| 673 | | bus->ack_timer=timer_alloc(device->machine, ack_timer_callback, (void *)device);
|
| 674 | | }
|
| 675 | | |
| 676 | | static DEVICE_STOP( scsibus )
|
| 677 | | {
|
| 678 | | scsibus_t *bus = get_token(device);
|
| 679 | | int devno;
|
| 680 | | |
| 681 | | for (devno = 0; devno < bus->interface->scsidevs->devs_present; devno++)
|
| 682 | | {
|
| 683 | | SCSIDeleteInstance( bus->devices[devno] );
|
| 684 | | }
|
| 685 | | }
|
| 686 | | |
| 687 | | static DEVICE_RESET( scsibus )
|
| 688 | | {
|
| 689 | | }
|
| 690 | | |
| 691 | | DEVICE_GET_INFO( scsibus )
|
| 692 | | {
|
| 693 | | switch ( state )
|
| 694 | | {
|
| 695 | | /* --- the following bits of info are returned as 64-bit signed integers --- */
|
| 696 | | case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(scsibus_t); break;
|
| 697 | | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
| 698 | | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
|
| 699 | | |
| 700 | | /* --- the following bits of info are returned as pointers to data or functions --- */
|
| 701 | | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(scsibus); break;
|
| 702 | | case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME(scsibus); break;
|
| 703 | | case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(scsibus); break;
|
| 704 | | |
| 705 | | /* --- the following bits of info are returned as NULL-terminated strings --- */
|
| 706 | | case DEVINFO_STR_NAME: strcpy(info->s, "SCSI bus"); break;
|
| 707 | | case DEVINFO_STR_FAMILY: strcpy(info->s, "SCSI"); break;
|
| 708 | | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
|
| 709 | | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
| 710 | | case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MAME and MESS Teams"); break;
|
| 711 | | }
|
| 712 | | }
|
| 1 | /* |
| 2 | SCSIBus.c |
| 3 | |
| 4 | Implementation of a raw SCSI/SASI bus for machines that don't use a SCSI |
| 5 | controler chip such as the RM Nimbus, which implements it as a bunch of |
| 6 | 74LS series chips. |
| 7 | |
| 8 | */ |
| 9 | |
| 10 | #include "emu.h" |
| 11 | #include "machine/scsi.h" |
| 12 | #include "machine/scsibus.h" |
| 13 | |
| 14 | /* LOGLEVEL 0=no logging, 1=just commands and data, 2=everything ! */ |
| 15 | |
| 16 | #define LOGLEVEL 0 |
| 17 | |
| 18 | #define LOG(level,...) if(LOGLEVEL>=level) logerror(__VA_ARGS__) |
| 19 | |
| 20 | typedef struct _scsibus_t scsibus_t; |
| 21 | struct _scsibus_t |
| 22 | { |
| 23 | SCSIInstance *devices[8]; |
| 24 | const SCSIBus_interface *interface; |
| 25 | |
| 26 | UINT8 linestate; |
| 27 | UINT8 last_id; |
| 28 | UINT8 phase; |
| 29 | |
| 30 | UINT8 command[CMD_BUF_SIZE]; |
| 31 | UINT8 cmd_idx; |
| 32 | UINT8 is_linked; |
| 33 | |
| 34 | UINT8 data[DATA_BUF_SIZE+RW_BUFFER_HEAD_BYTES]; |
| 35 | UINT16 data_idx; |
| 36 | int xfer_count; |
| 37 | int bytes_left; |
| 38 | int data_last; |
| 39 | |
| 40 | emu_timer *req_timer; |
| 41 | emu_timer *ack_timer; |
| 42 | |
| 43 | UINT8 initialised; |
| 44 | }; |
| 45 | |
| 46 | static void set_scsi_line_now(running_device *device, UINT8 line, UINT8 state); |
| 47 | static void set_scsi_line_ack(running_device *device, UINT8 state); |
| 48 | static void scsi_in_line_changed(running_device *device, UINT8 line, UINT8 state); |
| 49 | static void scsi_out_line_change(running_device *device, UINT8 line, UINT8 state); |
| 50 | static void scsi_out_line_change_now(running_device *device, UINT8 line, UINT8 state); |
| 51 | static void scsi_out_line_req(running_device *device, UINT8 state); |
| 52 | static TIMER_CALLBACK(req_timer_callback); |
| 53 | static TIMER_CALLBACK(ack_timer_callback); |
| 54 | static void scsi_change_phase(running_device *device, UINT8 newphase); |
| 55 | |
| 56 | static const char *const linenames[] = |
| 57 | { |
| 58 | "select", "busy", "request", "acknoledge", "C/D", "I/O", "message", "reset" |
| 59 | }; |
| 60 | |
| 61 | static const char *const phasenames[] = |
| 62 | { |
| 63 | "data out", "data in", "command", "status", "none", "none", "message out", "message in", "bus free","select" |
| 64 | }; |
| 65 | |
| 66 | INLINE scsibus_t *get_token(running_device *device) |
| 67 | { |
| 68 | assert(device->type == SCSIBUS); |
| 69 | return (scsibus_t *) device->token; |
| 70 | } |
| 71 | |
| 72 | static void scsibus_read_data(scsibus_t *bus) |
| 73 | { |
| 74 | bus->data_last = (bus->bytes_left >= DATA_BUF_SIZE) ? DATA_BUF_SIZE : bus->bytes_left; |
| 75 | |
| 76 | LOG(1,"SCSIBUS:scsibus_read_data bus->bytes_left=%04X, bus->data_last=%04X, bus->xfer_count=%04X\n",bus->bytes_left,bus->data_last,bus->xfer_count); |
| 77 | |
| 78 | if (bus->data_last > 0) |
| 79 | { |
| 80 | SCSIReadData(bus->devices[bus->last_id], bus->data, bus->data_last); |
| 81 | bus->bytes_left-=bus->data_last; |
| 82 | bus->data_idx=0; |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | static void scsibus_write_data(scsibus_t *bus) |
| 87 | { |
| 88 | if(bus->bytes_left >= DATA_BUF_SIZE) |
| 89 | { |
| 90 | SCSIWriteData(bus->devices[bus->last_id], bus->data, DATA_BUF_SIZE); |
| 91 | |
| 92 | bus->bytes_left-=DATA_BUF_SIZE; |
| 93 | bus->data_idx=0; |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | /* SCSI Bus read/write */ |
| 98 | |
| 99 | UINT8 scsi_data_r(running_device *device) |
| 100 | { |
| 101 | scsibus_t *bus = get_token(device); |
| 102 | UINT8 result = 0; |
| 103 | |
| 104 | switch (bus->phase) |
| 105 | { |
| 106 | case SCSI_PHASE_DATAIN : |
| 107 | result=bus->data[bus->data_idx++]; |
| 108 | |
| 109 | // check to see if we have reached the end of the block buffer |
| 110 | // and that there is more data to read from the scsi disk |
| 111 | if((bus->data_idx==DATA_BUF_SIZE) && (bus->bytes_left>0) && IS_READ_COMMAND()) |
| 112 | { |
| 113 | scsibus_read_data(bus); |
| 114 | } |
| 115 | break; |
| 116 | |
| 117 | case SCSI_PHASE_STATUS : |
| 118 | result=0; // no errors for the time being ! |
| 119 | bus->cmd_idx++; |
| 120 | break; |
| 121 | |
| 122 | case SCSI_PHASE_MESSAGE_IN : |
| 123 | result=0; // no errors for the time being ! |
| 124 | bus->cmd_idx++; |
| 125 | break; |
| 126 | } |
| 127 | |
| 128 | LOG(2,"scsi_data_r : phase=%s, data_idx=%d, cmd_idx=%d\n",phasenames[bus->phase],bus->data_idx,bus->cmd_idx); |
| 129 | return result; |
| 130 | } |
| 131 | |
| 132 | void scsi_data_w(running_device *device, UINT8 data) |
| 133 | { |
| 134 | scsibus_t *bus = get_token(device); |
| 135 | |
| 136 | switch (bus->phase) |
| 137 | { |
| 138 | // Note this assumes we only have one initiator and therefore |
| 139 | // only one line active. |
| 140 | case SCSI_PHASE_BUS_FREE : |
| 141 | bus->last_id=driveno(data); |
| 142 | break; |
| 143 | |
| 144 | case SCSI_PHASE_COMMAND : |
| 145 | bus->command[bus->cmd_idx++]=data; |
| 146 | break; |
| 147 | |
| 148 | case SCSI_PHASE_DATAOUT : |
| 149 | |
| 150 | //LOG(1,"SCSIBUS:xfer_count=%02X, bytes_left=%02X data_idx=%02X\n",bus->xfer_count,bus->bytes_left,bus->data_idx); |
| 151 | |
| 152 | // Write (blocks) and write buffer, just buffer it |
| 153 | if(IS_WRITE_COMMAND() || IS_COMMAND(SCSI_CMD_BUFFER_WRITE) || IS_COMMAND(SCSI_CMD_MODE_SELECT)) |
| 154 | bus->data[bus->data_idx++]=data; |
| 155 | |
| 156 | if(IS_COMMAND(SCSI_CMD_FORMAT_UNIT)) |
| 157 | { |
| 158 | // Only store the first 4 bytes of the bad block list (the header) |
| 159 | if(bus->data_idx<4) |
| 160 | bus->data[bus->data_idx++]=data; |
| 161 | else |
| 162 | bus->data_idx++; |
| 163 | |
| 164 | // When we have the first 3 bytes, calculate how many more are in the |
| 165 | // bad block list. |
| 166 | if(bus->data_idx==3) |
| 167 | { |
| 168 | bus->xfer_count+=((bus->data[2]<<8)+bus->data[3]); |
| 169 | bus->data_last=bus->xfer_count; |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | // If the data buffer is full, and we are writing blocks flush it to the SCSI disk |
| 174 | if((bus->data_idx == DATA_BUF_SIZE) && IS_WRITE_COMMAND()) |
| 175 | scsibus_write_data(bus); |
| 176 | break; |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | /* Get/Set lines */ |
| 181 | |
| 182 | UINT8 get_scsi_lines(running_device *device) |
| 183 | { |
| 184 | scsibus_t *bus = get_token(device); |
| 185 | |
| 186 | return bus->linestate; |
| 187 | } |
| 188 | |
| 189 | UINT8 get_scsi_line(running_device *device, UINT8 lineno) |
| 190 | { |
| 191 | scsibus_t *bus = get_token(device); |
| 192 | UINT8 result=0; |
| 193 | |
| 194 | switch (lineno) |
| 195 | { |
| 196 | case SCSI_LINE_SEL : result=(bus->linestate & (1<<SCSI_LINE_SEL)) >> SCSI_LINE_SEL; |
| 197 | case SCSI_LINE_BSY : result=(bus->linestate & (1<<SCSI_LINE_BSY)) >> SCSI_LINE_BSY; |
| 198 | case SCSI_LINE_REQ : result=(bus->linestate & (1<<SCSI_LINE_REQ)) >> SCSI_LINE_REQ; |
| 199 | case SCSI_LINE_ACK : result=(bus->linestate & (1<<SCSI_LINE_ACK)) >> SCSI_LINE_ACK; |
| 200 | case SCSI_LINE_CD : result=(bus->linestate & (1<<SCSI_LINE_CD )) >> SCSI_LINE_CD; |
| 201 | case SCSI_LINE_IO : result=(bus->linestate & (1<<SCSI_LINE_IO )) >> SCSI_LINE_IO; |
| 202 | case SCSI_LINE_MSG : result=(bus->linestate & (1<<SCSI_LINE_MSG)) >> SCSI_LINE_MSG; |
| 203 | case SCSI_LINE_RESET : result=(bus->linestate & (1<<SCSI_LINE_RESET)) >> SCSI_LINE_RESET; |
| 204 | } |
| 205 | |
| 206 | LOG(2,"get_scsi_line(%s)=%d\n",linenames[lineno],result); |
| 207 | |
| 208 | return result; |
| 209 | } |
| 210 | |
| 211 | void set_scsi_line(running_device *device, UINT8 line, UINT8 state) |
| 212 | { |
| 213 | scsibus_t *bus = get_token(device); |
| 214 | UINT8 changed; |
| 215 | |
| 216 | changed = ((bus->linestate & (1<<line)) != (state << line)); |
| 217 | |
| 218 | LOG(2,"set_scsi_line(%s,%d), changed=%d, linestate=%02X\n",linenames[line],state,changed,bus->linestate); |
| 219 | |
| 220 | if(changed) |
| 221 | { |
| 222 | if (line==SCSI_LINE_ACK) |
| 223 | set_scsi_line_ack(device,state); |
| 224 | else |
| 225 | set_scsi_line_now(device,line,state); |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | static void set_scsi_line_now(running_device *device, UINT8 line, UINT8 state) |
| 230 | { |
| 231 | scsibus_t *bus = get_token(device); |
| 232 | |
| 233 | if(state) |
| 234 | bus->linestate |= (1<<line); |
| 235 | else |
| 236 | bus->linestate &= ~(1<<line); |
| 237 | |
| 238 | scsi_in_line_changed(device,line,state); |
| 239 | } |
| 240 | |
| 241 | void set_scsi_line_ack(running_device *device, UINT8 state) |
| 242 | { |
| 243 | scsibus_t *bus = get_token(device); |
| 244 | |
| 245 | timer_adjust_oneshot(bus->ack_timer,ATTOTIME_IN_NSEC(ACK_DELAY_NS),state); |
| 246 | } |
| 247 | |
| 248 | void dump_command_bytes(scsibus_t *bus) |
| 249 | { |
| 250 | int byteno; |
| 251 | |
| 252 | logerror("sending command 0x%02X to ScsiID %d\n",bus->command[0],bus->last_id); |
| 253 | |
| 254 | for(byteno=0; byteno<bus->cmd_idx; byteno++) |
| 255 | { |
| 256 | logerror("%02X ",bus->command[byteno]); |
| 257 | } |
| 258 | logerror("\n\n"); |
| 259 | } |
| 260 | |
| 261 | static void scsibus_exec_command(running_device *device) |
| 262 | { |
| 263 | scsibus_t *bus = get_token(device); |
| 264 | int command_local = 0; |
| 265 | int newphase; |
| 266 | |
| 267 | if(LOGLEVEL) |
| 268 | dump_command_bytes(bus); |
| 269 | |
| 270 | bus->is_linked=bus->command[bus->cmd_idx-1] & 0x01; |
| 271 | |
| 272 | // Check for locally executed commands, and if found execute them |
| 273 | switch (bus->command[0]) |
| 274 | { |
| 275 | // Format unit |
| 276 | case SCSI_CMD_FORMAT_UNIT : |
| 277 | LOG(1,"SCSIBUS: format unit bus->command[1]=%02X & 0x10\n",(bus->command[1] & 0x10)); |
| 278 | command_local=1; |
| 279 | if((bus->command[1] & 0x10)==0x10) |
| 280 | SCSISetPhase(bus->devices[bus->last_id],SCSI_PHASE_DATAOUT); |
| 281 | else |
| 282 | SCSISetPhase(bus->devices[bus->last_id],SCSI_PHASE_STATUS); |
| 283 | |
| 284 | bus->xfer_count=4; |
| 285 | bus->data_last=bus->xfer_count; |
| 286 | bus->bytes_left=0; |
| 287 | break; |
| 288 | |
| 289 | case SCSI_CMD_READ_DEFECT : |
| 290 | LOG(1,"SCSIBUS: read defect list\n"); |
| 291 | command_local=1; |
| 292 | |
| 293 | bus->data[0] = 0x00; |
| 294 | bus->data[1] = bus->command[2]; |
| 295 | bus->data[3] = 0x00; // defect list len msb |
| 296 | bus->data[4] = 0x00; // defect list len lsb |
| 297 | |
| 298 | bus->xfer_count=4; |
| 299 | bus->data_last=bus->xfer_count; |
| 300 | bus->bytes_left=0; |
| 301 | SCSISetPhase(bus->devices[bus->last_id], SCSI_PHASE_DATAIN ); |
| 302 | break; |
| 303 | |
| 304 | // write buffer |
| 305 | case SCSI_CMD_BUFFER_WRITE : |
| 306 | LOG(1,"SCSIBUS: write_buffer\n"); |
| 307 | command_local=1; |
| 308 | bus->xfer_count=(bus->command[7]<<8)+bus->command[8]; |
| 309 | bus->data_last=bus->xfer_count; |
| 310 | bus->bytes_left=0; |
| 311 | SCSISetPhase(bus->devices[bus->last_id],SCSI_PHASE_DATAOUT); |
| 312 | break; |
| 313 | |
| 314 | // read buffer |
| 315 | case SCSI_CMD_BUFFER_READ : |
| 316 | LOG(1,"SCSIBUS: read_buffer\n"); |
| 317 | command_local=1; |
| 318 | bus->xfer_count=(bus->command[7]<<8)+bus->command[8]; |
| 319 | bus->data_last=bus->xfer_count; |
| 320 | bus->bytes_left=0; |
| 321 | SCSISetPhase(bus->devices[bus->last_id],SCSI_PHASE_DATAIN); |
| 322 | break; |
| 323 | } |
| 324 | |
| 325 | |
| 326 | // Check for locally executed command, if not then pass it on |
| 327 | // to the disk driver |
| 328 | if(!command_local) |
| 329 | { |
| 330 | SCSISetCommand(bus->devices[bus->last_id], bus->command, bus->cmd_idx); |
| 331 | SCSIExecCommand(bus->devices[bus->last_id], &bus->xfer_count); |
| 332 | bus->bytes_left=bus->xfer_count; |
| 333 | bus->data_last=bus->xfer_count; |
| 334 | bus->data_idx=0; |
| 335 | } |
| 336 | |
| 337 | SCSIGetPhase(bus->devices[bus->last_id], &newphase); |
| 338 | |
| 339 | scsi_change_phase(device,newphase); |
| 340 | |
| 341 | LOG(1,"SCSIBUS:xfer_count=%02X, bytes_left=%02X data_idx=%02X\n",bus->xfer_count,bus->bytes_left,bus->data_idx); |
| 342 | |
| 343 | // This is correct as we need to read from disk for commands other than just read data |
| 344 | if ((bus->phase == SCSI_PHASE_DATAIN) && (!command_local)) |
| 345 | scsibus_read_data(bus); |
| 346 | } |
| 347 | |
| 348 | static int datain_done(scsibus_t *bus) |
| 349 | { |
| 350 | int result=0; |
| 351 | |
| 352 | // Read data commands |
| 353 | if(IS_READ_COMMAND() && (bus->data_idx == bus->data_last) && (bus->bytes_left == 0)) |
| 354 | result=1; |
| 355 | else if (bus->data_idx==bus->data_last) |
| 356 | result=1; |
| 357 | |
| 358 | return result; |
| 359 | } |
| 360 | |
| 361 | static int dataout_done(scsibus_t *bus) |
| 362 | { |
| 363 | int result=0; |
| 364 | |
| 365 | // Write data commands |
| 366 | if(IS_WRITE_COMMAND() && (bus->data_idx == 0) && (bus->bytes_left == 0)) |
| 367 | result=1; |
| 368 | else if (bus->data_idx==bus->data_last) |
| 369 | result=1; |
| 370 | |
| 371 | return result; |
| 372 | } |
| 373 | |
| 374 | static void scsi_in_line_changed(running_device *device, UINT8 line, UINT8 state) |
| 375 | { |
| 376 | scsibus_t *bus = get_token(device); |
| 377 | |
| 378 | // Reset aborts and returns to bus free |
| 379 | if((line==SCSI_LINE_RESET) && (state==0)) |
| 380 | { |
| 381 | scsi_change_phase(device,SCSI_PHASE_BUS_FREE); |
| 382 | bus->cmd_idx=0; |
| 383 | bus->data_idx=0; |
| 384 | bus->is_linked=0; |
| 385 | |
| 386 | return; |
| 387 | } |
| 388 | |
| 389 | switch (bus->phase) |
| 390 | { |
| 391 | case SCSI_PHASE_BUS_FREE : |
| 392 | if((line==SCSI_LINE_SEL) && (bus->devices[bus->last_id]!=NULL)) |
| 393 | { |
| 394 | if(state==0) |
| 395 | scsi_out_line_change(device,SCSI_LINE_BSY,0); |
| 396 | else |
| 397 | scsi_change_phase(device,SCSI_PHASE_COMMAND); |
| 398 | } |
| 399 | break; |
| 400 | |
| 401 | case SCSI_PHASE_COMMAND : |
| 402 | if(line==SCSI_LINE_ACK) |
| 403 | { |
| 404 | if(state) |
| 405 | { |
| 406 | // If the command is ready go and execute it |
| 407 | if(bus->cmd_idx==get_scsi_cmd_len(bus->command[0])) |
| 408 | { |
| 409 | scsibus_exec_command(device); |
| 410 | } |
| 411 | else |
| 412 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 413 | } |
| 414 | else |
| 415 | scsi_out_line_change(device,SCSI_LINE_REQ,1); |
| 416 | } |
| 417 | break; |
| 418 | |
| 419 | case SCSI_PHASE_DATAIN : |
| 420 | if(line==SCSI_LINE_ACK) |
| 421 | { |
| 422 | if(state) |
| 423 | { |
| 424 | if(datain_done(bus)) |
| 425 | scsi_change_phase(device,SCSI_PHASE_STATUS); |
| 426 | else |
| 427 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 428 | } |
| 429 | else |
| 430 | scsi_out_line_change(device,SCSI_LINE_REQ,1); |
| 431 | } |
| 432 | break; |
| 433 | |
| 434 | case SCSI_PHASE_DATAOUT : |
| 435 | if(line==SCSI_LINE_ACK) |
| 436 | { |
| 437 | if(state) |
| 438 | { |
| 439 | if(dataout_done(bus)) |
| 440 | scsi_change_phase(device,SCSI_PHASE_STATUS); |
| 441 | else |
| 442 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 443 | } |
| 444 | else |
| 445 | scsi_out_line_change(device,SCSI_LINE_REQ,1); |
| 446 | } |
| 447 | break; |
| 448 | |
| 449 | case SCSI_PHASE_STATUS : |
| 450 | if(line==SCSI_LINE_ACK) |
| 451 | { |
| 452 | if(state) |
| 453 | { |
| 454 | if(bus->cmd_idx > 0) |
| 455 | { |
| 456 | scsi_change_phase(device,SCSI_PHASE_MESSAGE_IN); |
| 457 | } |
| 458 | else |
| 459 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 460 | } |
| 461 | else |
| 462 | scsi_out_line_change(device,SCSI_LINE_REQ,1); |
| 463 | } |
| 464 | break; |
| 465 | |
| 466 | case SCSI_PHASE_MESSAGE_IN : |
| 467 | if(line==SCSI_LINE_ACK) |
| 468 | { |
| 469 | if(state) |
| 470 | { |
| 471 | if(bus->cmd_idx > 0) |
| 472 | { |
| 473 | if(bus->is_linked) |
| 474 | scsi_change_phase(device,SCSI_PHASE_COMMAND); |
| 475 | else |
| 476 | scsi_change_phase(device,SCSI_PHASE_BUS_FREE); |
| 477 | } |
| 478 | else |
| 479 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 480 | } |
| 481 | else |
| 482 | scsi_out_line_change(device,SCSI_LINE_REQ,1); |
| 483 | } |
| 484 | break; |
| 485 | } |
| 486 | } |
| 487 | |
| 488 | static void scsi_out_line_change(running_device *device, UINT8 line, UINT8 state) |
| 489 | { |
| 490 | if(line==SCSI_LINE_REQ) |
| 491 | scsi_out_line_req(device,state); |
| 492 | else |
| 493 | scsi_out_line_change_now(device,line,state); |
| 494 | } |
| 495 | |
| 496 | static void scsi_out_line_change_now(running_device *device, UINT8 line, UINT8 state) |
| 497 | { |
| 498 | scsibus_t *bus = get_token(device); |
| 499 | |
| 500 | if(state) |
| 501 | bus->linestate |= (1<<line); |
| 502 | else |
| 503 | bus->linestate &= ~(1<<line); |
| 504 | |
| 505 | LOG(2,"scsi_out_line_change(%s,%d)\n",linenames[line],state); |
| 506 | |
| 507 | if(bus->interface->line_change_cb!=NULL) |
| 508 | bus->interface->line_change_cb(device,line,state); |
| 509 | } |
| 510 | |
| 511 | static void scsi_out_line_req(running_device *device, UINT8 state) |
| 512 | { |
| 513 | scsibus_t *bus = get_token(device); |
| 514 | |
| 515 | timer_adjust_oneshot(bus->req_timer,ATTOTIME_IN_NSEC(REQ_DELAY_NS),state); |
| 516 | } |
| 517 | |
| 518 | |
| 519 | static TIMER_CALLBACK(req_timer_callback) |
| 520 | { |
| 521 | scsi_out_line_change_now((running_device *)ptr, SCSI_LINE_REQ, param); |
| 522 | } |
| 523 | |
| 524 | static TIMER_CALLBACK(ack_timer_callback) |
| 525 | { |
| 526 | set_scsi_line_now((running_device *)ptr, SCSI_LINE_ACK, param); |
| 527 | } |
| 528 | |
| 529 | |
| 530 | UINT8 get_scsi_phase(running_device *device) |
| 531 | { |
| 532 | scsibus_t *bus = get_token(device); |
| 533 | |
| 534 | return bus->phase; |
| 535 | } |
| 536 | |
| 537 | |
| 538 | static void scsi_change_phase(running_device *device, UINT8 newphase) |
| 539 | { |
| 540 | scsibus_t *bus = get_token(device); |
| 541 | |
| 542 | LOG(1,"scsi_change_phase() from=%s, to=%s\n",phasenames[bus->phase],phasenames[newphase]); |
| 543 | |
| 544 | bus->phase=newphase; |
| 545 | bus->cmd_idx=0; |
| 546 | bus->data_idx=0; |
| 547 | |
| 548 | switch(bus->phase) |
| 549 | { |
| 550 | case SCSI_PHASE_BUS_FREE : |
| 551 | scsi_out_line_change(device,SCSI_LINE_CD,1); |
| 552 | scsi_out_line_change(device,SCSI_LINE_IO,1); |
| 553 | scsi_out_line_change(device,SCSI_LINE_MSG,1); |
| 554 | scsi_out_line_change(device,SCSI_LINE_REQ,1); |
| 555 | scsi_out_line_change(device,SCSI_LINE_BSY,1); |
| 556 | break; |
| 557 | |
| 558 | case SCSI_PHASE_COMMAND : |
| 559 | scsi_out_line_change(device,SCSI_LINE_CD,0); |
| 560 | scsi_out_line_change(device,SCSI_LINE_IO,1); |
| 561 | scsi_out_line_change(device,SCSI_LINE_MSG,1); |
| 562 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 563 | break; |
| 564 | |
| 565 | case SCSI_PHASE_DATAOUT : |
| 566 | scsi_out_line_change(device,SCSI_LINE_CD,1); |
| 567 | scsi_out_line_change(device,SCSI_LINE_IO,1); |
| 568 | scsi_out_line_change(device,SCSI_LINE_MSG,1); |
| 569 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 570 | break; |
| 571 | |
| 572 | case SCSI_PHASE_DATAIN : |
| 573 | scsi_out_line_change(device,SCSI_LINE_CD,1); |
| 574 | scsi_out_line_change(device,SCSI_LINE_IO,0); |
| 575 | scsi_out_line_change(device,SCSI_LINE_MSG,1); |
| 576 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 577 | break; |
| 578 | |
| 579 | case SCSI_PHASE_STATUS : |
| 580 | scsi_out_line_change(device,SCSI_LINE_CD,0); |
| 581 | scsi_out_line_change(device,SCSI_LINE_IO,0); |
| 582 | scsi_out_line_change(device,SCSI_LINE_MSG,1); |
| 583 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 584 | break; |
| 585 | |
| 586 | case SCSI_PHASE_MESSAGE_OUT : |
| 587 | scsi_out_line_change(device,SCSI_LINE_CD,0); |
| 588 | scsi_out_line_change(device,SCSI_LINE_IO,1); |
| 589 | scsi_out_line_change(device,SCSI_LINE_MSG,0); |
| 590 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 591 | break; |
| 592 | |
| 593 | case SCSI_PHASE_MESSAGE_IN : |
| 594 | scsi_out_line_change(device,SCSI_LINE_CD,0); |
| 595 | scsi_out_line_change(device,SCSI_LINE_IO,0); |
| 596 | scsi_out_line_change(device,SCSI_LINE_MSG,0); |
| 597 | scsi_out_line_change(device,SCSI_LINE_REQ,0); |
| 598 | break; |
| 599 | } |
| 600 | } |
| 601 | |
| 602 | UINT8 driveno(UINT8 drivesel) |
| 603 | { |
| 604 | switch (drivesel) |
| 605 | { |
| 606 | case 0x01 : return 0; |
| 607 | case 0x02 : return 1; |
| 608 | case 0x04 : return 2; |
| 609 | case 0x08 : return 3; |
| 610 | case 0x10 : return 4; |
| 611 | case 0x20 : return 5; |
| 612 | case 0x40 : return 6; |
| 613 | case 0x80 : return 7; |
| 614 | default : return 0; |
| 615 | } |
| 616 | } |
| 617 | |
| 618 | // get the length of a SCSI command based on it's command byte type |
| 619 | int get_scsi_cmd_len(int cbyte) |
| 620 | { |
| 621 | int group; |
| 622 | |
| 623 | group = (cbyte>>5) & 7; |
| 624 | |
| 625 | if (group == 0) return 6; |
| 626 | if (group == 1 || group == 2) return 10; |
| 627 | if (group == 5) return 12; |
| 628 | |
| 629 | fatalerror("scsibus: Unknown SCSI command group %d\n", group); |
| 630 | |
| 631 | return 6; |
| 632 | } |
| 633 | |
| 634 | void init_scsibus(running_device *device) |
| 635 | { |
| 636 | scsibus_t *bus = get_token(device); |
| 637 | const SCSIConfigTable *scsidevs = bus->interface->scsidevs; |
| 638 | int devno; |
| 639 | |
| 640 | if(!bus->initialised) |
| 641 | { |
| 642 | // try to open the devices |
| 643 | for (devno = 0; devno < scsidevs->devs_present; devno++) |
| 644 | { |
| 645 | LOG(1,"init_scsibus devno=%d \n",devno); |
| 646 | SCSIAllocInstance( device->machine, scsidevs->devices[devno].scsiClass, &bus->devices[scsidevs->devices[devno].scsiID], scsidevs->devices[devno].diskregion ); |
| 647 | } |
| 648 | |
| 649 | bus->initialised=1; |
| 650 | } |
| 651 | } |
| 652 | |
| 653 | static DEVICE_START( scsibus ) |
| 654 | { |
| 655 | scsibus_t *bus = get_token(device); |
| 656 | |
| 657 | assert(device->baseconfig().static_config != NULL); |
| 658 | bus->interface = (const SCSIBus_interface*)device->baseconfig().static_config; |
| 659 | |
| 660 | memset(bus->devices, 0, sizeof(bus->devices)); |
| 661 | |
| 662 | // Flag not initialised |
| 663 | bus->initialised=0; |
| 664 | |
| 665 | // All lines start high - inactive |
| 666 | bus->linestate=0xFF; |
| 667 | |
| 668 | // Start with bus free |
| 669 | bus->phase=SCSI_PHASE_BUS_FREE; |
| 670 | |
| 671 | // Setup req/ack timers |
| 672 | bus->req_timer=timer_alloc(device->machine, req_timer_callback, (void *)device); |
| 673 | bus->ack_timer=timer_alloc(device->machine, ack_timer_callback, (void *)device); |
| 674 | } |
| 675 | |
| 676 | static DEVICE_STOP( scsibus ) |
| 677 | { |
| 678 | scsibus_t *bus = get_token(device); |
| 679 | int devno; |
| 680 | |
| 681 | for (devno = 0; devno < bus->interface->scsidevs->devs_present; devno++) |
| 682 | { |
| 683 | SCSIDeleteInstance( bus->devices[devno] ); |
| 684 | } |
| 685 | } |
| 686 | |
| 687 | static DEVICE_RESET( scsibus ) |
| 688 | { |
| 689 | } |
| 690 | |
| 691 | DEVICE_GET_INFO( scsibus ) |
| 692 | { |
| 693 | switch ( state ) |
| 694 | { |
| 695 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 696 | case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(scsibus_t); break; |
| 697 | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break; |
| 698 | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break; |
| 699 | |
| 700 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 701 | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(scsibus); break; |
| 702 | case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME(scsibus); break; |
| 703 | case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(scsibus); break; |
| 704 | |
| 705 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 706 | case DEVINFO_STR_NAME: strcpy(info->s, "SCSI bus"); break; |
| 707 | case DEVINFO_STR_FAMILY: strcpy(info->s, "SCSI"); break; |
| 708 | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; |
| 709 | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; |
| 710 | case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MAME and MESS Teams"); break; |
| 711 | } |
| 712 | } |
src/mess/machine/er59256.c
| r7571 | r7572 | |
| 1 | | /*********************************************************************
|
| 2 | | |
| 3 | | er59256.c
|
| 4 | | |
| 5 | | Microchip ER59256 serial eeprom.
|
| 6 | | |
| 7 | | |
| 8 | | *********************************************************************/
|
| 9 | | |
| 10 | | #include "emu.h"
|
| 11 | | #include "er59256.h"
|
| 12 | | |
| 13 | | /* LOGLEVEL 0=no logging, 1=just commands and data, 2=everything ! */
|
| 14 | | |
| 15 | | #define LOGLEVEL 0
|
| 16 | | |
| 17 | | #define LOG(level,...) if(LOGLEVEL>=level) logerror(__VA_ARGS__)
|
| 18 | | #define LOG_BITS(bits) logerror("CS=%d CK=%d DI=%d DO=%d", (bits&CS_MASK) ? 1 : 0, (bits&CK_MASK) ? 1 : 0, (bits&DI_MASK) ? 1 : 0, (bits&DO_MASK) ? 1 : 0)
|
| 19 | | |
| 20 | | /***************************************************************************
|
| 21 | | TYPE DEFINITIONS
|
| 22 | | ***************************************************************************/
|
| 23 | | |
| 24 | | typedef struct _er59256_t er59256_t;
|
| 25 | | struct _er59256_t
|
| 26 | | {
|
| 27 | | /* The actual memory */
|
| 28 | | UINT16 eerom[EEROM_WORDS];
|
| 29 | | |
| 30 | | /* Bits as they appear on the io pins, current state */
|
| 31 | | UINT8 io_bits;
|
| 32 | | |
| 33 | | /* Bits as they appear on the io pins, previous state */
|
| 34 | | UINT8 old_io_bits;
|
| 35 | | |
| 36 | | |
| 37 | | /* the 16 bit shift in/out reg */
|
| 38 | | UINT16 in_shifter;
|
| 39 | | UINT32 out_shifter;
|
| 40 | | |
| 41 | | /* Count of bits recieved since last CS low->high */
|
| 42 | | UINT8 bitcount;
|
| 43 | | |
| 44 | | /* Command & addresss */
|
| 45 | | UINT8 command;
|
| 46 | | |
| 47 | | /* Write enable and write in progress flags */
|
| 48 | | UINT8 flags;
|
| 49 | | };
|
| 50 | | |
| 51 | | /***************************************************************************
|
| 52 | | FUNCTION PROTOTYPES
|
| 53 | | ************************************************************************/
|
| 54 | | |
| 55 | | void decode_command(er59256_t *er59256);
|
| 56 | | |
| 57 | | /***************************************************************************
|
| 58 | | INLINE FUNCTIONS
|
| 59 | | ***************************************************************************/
|
| 60 | | |
| 61 | | INLINE er59256_t *get_token(running_device *device)
|
| 62 | | {
|
| 63 | | assert(device->type == ER59256);
|
| 64 | | return (er59256_t *) device->token;
|
| 65 | | }
|
| 66 | | |
| 67 | | |
| 68 | | /***************************************************************************
|
| 69 | | IMPLEMENTATION
|
| 70 | | ***************************************************************************/
|
| 71 | | |
| 72 | | void preload_rom(running_device *device, UINT16 *rom_data, int count)
|
| 73 | | {
|
| 74 | | er59256_t *er59256 = get_token(device);
|
| 75 | | int WordNo;
|
| 76 | | |
| 77 | | logerror("Preloading %d words of data\n",count);
|
| 78 | | |
| 79 | | if(count>EEROM_WORDS)
|
| 80 | | memcpy(&er59256->eerom,rom_data,count*2);
|
| 81 | | else
|
| 82 | | memcpy(&er59256->eerom,rom_data,EEROM_WORDS*2);
|
| 83 | | |
| 84 | | for(WordNo=0;WordNo<EEROM_WORDS;WordNo++)
|
| 85 | | logerror("%04X ",er59256->eerom[WordNo]);
|
| 86 | | |
| 87 | | logerror("\n");
|
| 88 | | }
|
| 89 | | |
| 90 | | UINT8 data_loaded(running_device *device)
|
| 91 | | {
|
| 92 | | er59256_t *er59256 = get_token(device);
|
| 93 | | |
| 94 | | return (er59256->flags & FLAG_DATA_LOADED) ? 1 : 0;
|
| 95 | | }
|
| 96 | | |
| 97 | | /*-------------------------------------------------
|
| 98 | | DEVICE_START( er59256 )
|
| 99 | | -------------------------------------------------*/
|
| 100 | | |
| 101 | | static DEVICE_START( er59256 )
|
| 102 | | {
|
| 103 | | er59256_t *er59256 = get_token(device);
|
| 104 | | |
| 105 | | memset(er59256, 0x00, sizeof(er59256_t));
|
| 106 | | |
| 107 | | // Start with rom defaulted to erased
|
| 108 | | memset(&er59256->eerom, 0xFF, EEROM_WORDS*2);
|
| 109 | | |
| 110 | | er59256->command=CMD_INVALID;
|
| 111 | | |
| 112 | | er59256->flags&= ~FLAG_DATA_LOADED;
|
| 113 | | }
|
| 114 | | |
| 115 | | static DEVICE_STOP( er59256 )
|
| 116 | | {
|
| 117 | | /* Save contents of eerom */
|
| 118 | | }
|
| 119 | | |
| 120 | | void er59256_set_iobits(running_device *device, UINT8 newbits)
|
| 121 | | {
|
| 122 | | er59256_t *er59256 = get_token(device);
|
| 123 | | //UINT32 bit;
|
| 124 | | |
| 125 | | // Make sure we only apply valid bits
|
| 126 | | newbits&=ALL_MASK;
|
| 127 | | |
| 128 | | if(LOGLEVEL>1)
|
| 129 | | {
|
| 130 | | logerror("er59256:newbits=%02X : ",newbits);
|
| 131 | | LOG_BITS(newbits);
|
| 132 | | logerror(" io_bits=%02X : ",er59256->io_bits);
|
| 133 | | LOG_BITS(er59256->io_bits);
|
| 134 | | logerror(" old_io_bits=%02X : ",er59256->old_io_bits);
|
| 135 | | LOG_BITS(er59256->old_io_bits);
|
| 136 | | logerror(" bitcount=%d, in_shifter=%04X, out_shifter=%05X, flags=%02X\n",er59256->bitcount,er59256->in_shifter,er59256->out_shifter,er59256->flags);
|
| 137 | | }
|
| 138 | | // Only do anything if the inputs have changed
|
| 139 | | if((newbits&IN_MASK)!=(er59256->io_bits&IN_MASK))
|
| 140 | | {
|
| 141 | | // save the current state, then set the new one, remembering to preserve data out
|
| 142 | | er59256->old_io_bits=er59256->io_bits;
|
| 143 | | er59256->io_bits=(newbits & ~DO_MASK) | (er59256->old_io_bits&DO_MASK);
|
| 144 | | |
| 145 | | if(CS_RISE(er59256))
|
| 146 | | {
|
| 147 | | er59256->flags&=~FLAG_START_BIT;
|
| 148 | | er59256->command=CMD_INVALID;
|
| 149 | | }
|
| 150 | | |
| 151 | | if(LOGLEVEL>1)
|
| 152 | | {
|
| 153 | | if(CK_RISE(er59256)) logerror("er59256:CK rise\n");
|
| 154 | | if(CS_RISE(er59256)) logerror("er59256:CS rise\n");
|
| 155 | | if(CK_FALL(er59256)) logerror("er59256:CK fall\n");
|
| 156 | | if(CS_FALL(er59256)) logerror("er59256:CS fall\n");
|
| 157 | | }
|
| 158 | | |
| 159 | | if(CK_RISE(er59256) && CS_VALID(er59256))
|
| 160 | | {
|
| 161 | | if((STARTED(er59256)==0) && (GET_DI(er59256)==1))
|
| 162 | | {
|
| 163 | | er59256->bitcount=0;
|
| 164 | | er59256->flags|=FLAG_START_BIT;
|
| 165 | | }
|
| 166 | | else
|
| 167 | | {
|
| 168 | | SHIFT_IN(er59256);
|
| 169 | | er59256->bitcount++;
|
| 170 | | |
| 171 | | if(er59256->bitcount==CMD_BITLEN)
|
| 172 | | decode_command(er59256);
|
| 173 | | |
| 174 | | if((er59256->bitcount==WRITE_BITLEN) && ((er59256->command & CMD_MASK)==CMD_WRITE))
|
| 175 | | {
|
| 176 | | er59256->eerom[er59256->command & ADDR_MASK]=er59256->in_shifter;
|
| 177 | | LOG(1,"er59256:write[%02X]=%04X\n",(er59256->command & ADDR_MASK),er59256->in_shifter);
|
| 178 | | er59256->command=CMD_INVALID;
|
| 179 | | }
|
| 180 | | LOG(1,"out_shifter=%05X, io_bits=%02X\n",er59256->out_shifter,er59256->io_bits);
|
| 181 | | SHIFT_OUT(er59256);
|
| 182 | | }
|
| 183 | | |
| 184 | | LOG(2,"io_bits:out=%02X\n",er59256->io_bits);
|
| 185 | | }
|
| 186 | | }
|
| 187 | | }
|
| 188 | | |
| 189 | | UINT8 er59256_get_iobits(running_device *device)
|
| 190 | | {
|
| 191 | | er59256_t *er59256 = get_token(device);
|
| 192 | | |
| 193 | | return er59256->io_bits;
|
| 194 | | }
|
| 195 | | |
| 196 | | |
| 197 | | void decode_command(er59256_t *er59256)
|
| 198 | | {
|
| 199 | | er59256->out_shifter=0x0000;
|
| 200 | | er59256->command=(er59256->in_shifter & (CMD_MASK | ADDR_MASK));
|
| 201 | | |
| 202 | | switch(er59256->command & CMD_MASK)
|
| 203 | | {
|
| 204 | | case CMD_READ : er59256->out_shifter=er59256->eerom[er59256->command & ADDR_MASK];
|
| 205 | | LOG(1,"er59256:read[%02X]=%04X\n",(er59256->command&ADDR_MASK),er59256->eerom[er59256->command & ADDR_MASK]);
|
| 206 | | break;
|
| 207 | | case CMD_WRITE : break;
|
| 208 | | case CMD_ERASE : if (WRITE_ENABLED(er59256)) er59256->eerom[er59256->command & ADDR_MASK]=0xFF;
|
| 209 | | LOG(1,"er59256:erase[%02X]\n",(er59256->command&ADDR_MASK));
|
| 210 | | break;
|
| 211 | | case CMD_EWEN : er59256->flags|=FLAG_WRITE_EN;
|
| 212 | | LOG(1,"er59256:erase/write enabled\n");
|
| 213 | | break;
|
| 214 | | case CMD_EWDS : er59256->flags&=~FLAG_WRITE_EN;
|
| 215 | | LOG(1,"er59256:erase/write disabled\n");
|
| 216 | | break;
|
| 217 | | case CMD_ERAL : if (WRITE_ENABLED(er59256)) memset(&er59256->eerom, 0xFF, EEROM_WORDS*2);
|
| 218 | | LOG(1,"er59256:erase all\n");
|
| 219 | | break;
|
| 220 | | }
|
| 221 | | |
| 222 | | if ((er59256->command & CMD_MASK)!=CMD_WRITE)
|
| 223 | | er59256->command=CMD_INVALID;
|
| 224 | | }
|
| 225 | | |
| 226 | | /*-------------------------------------------------
|
| 227 | | DEVICE_GET_INFO( er59256 )
|
| 228 | | -------------------------------------------------*/
|
| 229 | | |
| 230 | | DEVICE_GET_INFO( er59256 )
|
| 231 | | {
|
| 232 | | switch (state)
|
| 233 | | {
|
| 234 | | /* --- the following bits of info are returned as 64-bit signed integers --- */
|
| 235 | | case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(er59256_t); break;
|
| 236 | | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
| 237 | | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
|
| 238 | | |
| 239 | | /* --- the following bits of info are returned as pointers to data or functions --- */
|
| 240 | | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(er59256); break;
|
| 241 | | case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME(er59256); break;
|
| 242 | | case DEVINFO_FCT_RESET: /* Nothing */ break;
|
| 243 | | |
| 244 | | /* --- the following bits of info are returned as NULL-terminated strings --- */
|
| 245 | | case DEVINFO_STR_NAME: strcpy(info->s, "Microchip ER59256 serial eeprom."); break;
|
| 246 | | case DEVINFO_STR_FAMILY: strcpy(info->s, "Microchip ER59256 serial eeprom."); break;
|
| 247 | | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
|
| 248 | | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
| 249 | | case DEVINFO_STR_CREDITS: /* Nothing */ break;
|
| 250 | | }
|
| 251 | | }
|
| 1 | /********************************************************************* |
| 2 | |
| 3 | er59256.c |
| 4 | |
| 5 | Microchip ER59256 serial eeprom. |
| 6 | |
| 7 | |
| 8 | *********************************************************************/ |
| 9 | |
| 10 | #include "emu.h" |
| 11 | #include "er59256.h" |
| 12 | |
| 13 | /* LOGLEVEL 0=no logging, 1=just commands and data, 2=everything ! */ |
| 14 | |
| 15 | #define LOGLEVEL 0 |
| 16 | |
| 17 | #define LOG(level,...) if(LOGLEVEL>=level) logerror(__VA_ARGS__) |
| 18 | #define LOG_BITS(bits) logerror("CS=%d CK=%d DI=%d DO=%d", (bits&CS_MASK) ? 1 : 0, (bits&CK_MASK) ? 1 : 0, (bits&DI_MASK) ? 1 : 0, (bits&DO_MASK) ? 1 : 0) |
| 19 | |
| 20 | /*************************************************************************** |
| 21 | TYPE DEFINITIONS |
| 22 | ***************************************************************************/ |
| 23 | |
| 24 | typedef struct _er59256_t er59256_t; |
| 25 | struct _er59256_t |
| 26 | { |
| 27 | /* The actual memory */ |
| 28 | UINT16 eerom[EEROM_WORDS]; |
| 29 | |
| 30 | /* Bits as they appear on the io pins, current state */ |
| 31 | UINT8 io_bits; |
| 32 | |
| 33 | /* Bits as they appear on the io pins, previous state */ |
| 34 | UINT8 old_io_bits; |
| 35 | |
| 36 | |
| 37 | /* the 16 bit shift in/out reg */ |
| 38 | UINT16 in_shifter; |
| 39 | UINT32 out_shifter; |
| 40 | |
| 41 | /* Count of bits recieved since last CS low->high */ |
| 42 | UINT8 bitcount; |
| 43 | |
| 44 | /* Command & addresss */ |
| 45 | UINT8 command; |
| 46 | |
| 47 | /* Write enable and write in progress flags */ |
| 48 | UINT8 flags; |
| 49 | }; |
| 50 | |
| 51 | /*************************************************************************** |
| 52 | FUNCTION PROTOTYPES |
| 53 | ************************************************************************/ |
| 54 | |
| 55 | void decode_command(er59256_t *er59256); |
| 56 | |
| 57 | /*************************************************************************** |
| 58 | INLINE FUNCTIONS |
| 59 | ***************************************************************************/ |
| 60 | |
| 61 | INLINE er59256_t *get_token(running_device *device) |
| 62 | { |
| 63 | assert(device->type == ER59256); |
| 64 | return (er59256_t *) device->token; |
| 65 | } |
| 66 | |
| 67 | |
| 68 | /*************************************************************************** |
| 69 | IMPLEMENTATION |
| 70 | ***************************************************************************/ |
| 71 | |
| 72 | void preload_rom(running_device *device, UINT16 *rom_data, int count) |
| 73 | { |
| 74 | er59256_t *er59256 = get_token(device); |
| 75 | int WordNo; |
| 76 | |
| 77 | logerror("Preloading %d words of data\n",count); |
| 78 | |
| 79 | if(count>EEROM_WORDS) |
| 80 | memcpy(&er59256->eerom,rom_data,count*2); |
| 81 | else |
| 82 | memcpy(&er59256->eerom,rom_data,EEROM_WORDS*2); |
| 83 | |
| 84 | for(WordNo=0;WordNo<EEROM_WORDS;WordNo++) |
| 85 | logerror("%04X ",er59256->eerom[WordNo]); |
| 86 | |
| 87 | logerror("\n"); |
| 88 | } |
| 89 | |
| 90 | UINT8 data_loaded(running_device *device) |
| 91 | { |
| 92 | er59256_t *er59256 = get_token(device); |
| 93 | |
| 94 | return (er59256->flags & FLAG_DATA_LOADED) ? 1 : 0; |
| 95 | } |
| 96 | |
| 97 | /*------------------------------------------------- |
| 98 | DEVICE_START( er59256 ) |
| 99 | -------------------------------------------------*/ |
| 100 | |
| 101 | static DEVICE_START( er59256 ) |
| 102 | { |
| 103 | er59256_t *er59256 = get_token(device); |
| 104 | |
| 105 | memset(er59256, 0x00, sizeof(er59256_t)); |
| 106 | |
| 107 | // Start with rom defaulted to erased |
| 108 | memset(&er59256->eerom, 0xFF, EEROM_WORDS*2); |
| 109 | |
| 110 | er59256->command=CMD_INVALID; |
| 111 | |
| 112 | er59256->flags&= ~FLAG_DATA_LOADED; |
| 113 | } |
| 114 | |
| 115 | static DEVICE_STOP( er59256 ) |
| 116 | { |
| 117 | /* Save contents of eerom */ |
| 118 | } |
| 119 | |
| 120 | void er59256_set_iobits(running_device *device, UINT8 newbits) |
| 121 | { |
| 122 | er59256_t *er59256 = get_token(device); |
| 123 | //UINT32 bit; |
| 124 | |
| 125 | // Make sure we only apply valid bits |
| 126 | newbits&=ALL_MASK; |
| 127 | |
| 128 | if(LOGLEVEL>1) |
| 129 | { |
| 130 | logerror("er59256:newbits=%02X : ",newbits); |
| 131 | LOG_BITS(newbits); |
| 132 | logerror(" io_bits=%02X : ",er59256->io_bits); |
| 133 | LOG_BITS(er59256->io_bits); |
| 134 | logerror(" old_io_bits=%02X : ",er59256->old_io_bits); |
| 135 | LOG_BITS(er59256->old_io_bits); |
| 136 | logerror(" bitcount=%d, in_shifter=%04X, out_shifter=%05X, flags=%02X\n",er59256->bitcount,er59256->in_shifter,er59256->out_shifter,er59256->flags); |
| 137 | } |
| 138 | // Only do anything if the inputs have changed |
| 139 | if((newbits&IN_MASK)!=(er59256->io_bits&IN_MASK)) |
| 140 | { |
| 141 | // save the current state, then set the new one, remembering to preserve data out |
| 142 | er59256->old_io_bits=er59256->io_bits; |
| 143 | er59256->io_bits=(newbits & ~DO_MASK) | (er59256->old_io_bits&DO_MASK); |
| 144 | |
| 145 | if(CS_RISE(er59256)) |
| 146 | { |
| 147 | er59256->flags&=~FLAG_START_BIT; |
| 148 | er59256->command=CMD_INVALID; |
| 149 | } |
| 150 | |
| 151 | if(LOGLEVEL>1) |
| 152 | { |
| 153 | if(CK_RISE(er59256)) logerror("er59256:CK rise\n"); |
| 154 | if(CS_RISE(er59256)) logerror("er59256:CS rise\n"); |
| 155 | if(CK_FALL(er59256)) logerror("er59256:CK fall\n"); |
| 156 | if(CS_FALL(er59256)) logerror("er59256:CS fall\n"); |
| 157 | } |
| 158 | |
| 159 | if(CK_RISE(er59256) && CS_VALID(er59256)) |
| 160 | { |
| 161 | if((STARTED(er59256)==0) && (GET_DI(er59256)==1)) |
| 162 | { |
| 163 | er59256->bitcount=0; |
| 164 | er59256->flags|=FLAG_START_BIT; |
| 165 | } |
| 166 | else |
| 167 | { |
| 168 | SHIFT_IN(er59256); |
| 169 | er59256->bitcount++; |
| 170 | |
| 171 | if(er59256->bitcount==CMD_BITLEN) |
| 172 | decode_command(er59256); |
| 173 | |
| 174 | if((er59256->bitcount==WRITE_BITLEN) && ((er59256->command & CMD_MASK)==CMD_WRITE)) |
| 175 | { |
| 176 | er59256->eerom[er59256->command & ADDR_MASK]=er59256->in_shifter; |
| 177 | LOG(1,"er59256:write[%02X]=%04X\n",(er59256->command & ADDR_MASK),er59256->in_shifter); |
| 178 | er59256->command=CMD_INVALID; |
| 179 | } |
| 180 | LOG(1,"out_shifter=%05X, io_bits=%02X\n",er59256->out_shifter,er59256->io_bits); |
| 181 | SHIFT_OUT(er59256); |
| 182 | } |
| 183 | |
| 184 | LOG(2,"io_bits:out=%02X\n",er59256->io_bits); |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | UINT8 er59256_get_iobits(running_device *device) |
| 190 | { |
| 191 | er59256_t *er59256 = get_token(device); |
| 192 | |
| 193 | return er59256->io_bits; |
| 194 | } |
| 195 | |
| 196 | |
| 197 | void decode_command(er59256_t *er59256) |
| 198 | { |
| 199 | er59256->out_shifter=0x0000; |
| 200 | er59256->command=(er59256->in_shifter & (CMD_MASK | ADDR_MASK)); |
| 201 | |
| 202 | switch(er59256->command & CMD_MASK) |
| 203 | { |
| 204 | case CMD_READ : er59256->out_shifter=er59256->eerom[er59256->command & ADDR_MASK]; |
| 205 | LOG(1,"er59256:read[%02X]=%04X\n",(er59256->command&ADDR_MASK),er59256->eerom[er59256->command & ADDR_MASK]); |
| 206 | break; |
| 207 | case CMD_WRITE : break; |
| 208 | case CMD_ERASE : if (WRITE_ENABLED(er59256)) er59256->eerom[er59256->command & ADDR_MASK]=0xFF; |
| 209 | LOG(1,"er59256:erase[%02X]\n",(er59256->command&ADDR_MASK)); |
| 210 | break; |
| 211 | case CMD_EWEN : er59256->flags|=FLAG_WRITE_EN; |
| 212 | LOG(1,"er59256:erase/write enabled\n"); |
| 213 | break; |
| 214 | case CMD_EWDS : er59256->flags&=~FLAG_WRITE_EN; |
| 215 | LOG(1,"er59256:erase/write disabled\n"); |
| 216 | break; |
| 217 | case CMD_ERAL : if (WRITE_ENABLED(er59256)) memset(&er59256->eerom, 0xFF, EEROM_WORDS*2); |
| 218 | LOG(1,"er59256:erase all\n"); |
| 219 | break; |
| 220 | } |
| 221 | |
| 222 | if ((er59256->command & CMD_MASK)!=CMD_WRITE) |
| 223 | er59256->command=CMD_INVALID; |
| 224 | } |
| 225 | |
| 226 | /*------------------------------------------------- |
| 227 | DEVICE_GET_INFO( er59256 ) |
| 228 | -------------------------------------------------*/ |
| 229 | |
| 230 | DEVICE_GET_INFO( er59256 ) |
| 231 | { |
| 232 | switch (state) |
| 233 | { |
| 234 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 235 | case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(er59256_t); break; |
| 236 | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break; |
| 237 | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break; |
| 238 | |
| 239 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 240 | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(er59256); break; |
| 241 | case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME(er59256); break; |
| 242 | case DEVINFO_FCT_RESET: /* Nothing */ break; |
| 243 | |
| 244 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 245 | case DEVINFO_STR_NAME: strcpy(info->s, "Microchip ER59256 serial eeprom."); break; |
| 246 | case DEVINFO_STR_FAMILY: strcpy(info->s, "Microchip ER59256 serial eeprom."); break; |
| 247 | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; |
| 248 | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; |
| 249 | case DEVINFO_STR_CREDITS: /* Nothing */ break; |
| 250 | } |
| 251 | } |
src/mess/machine/c9060.c
| r7571 | r7572 | |
| 1 | | /**********************************************************************
|
| 2 | | |
| 3 | | Commodore 9060/9090 Hard Disk Drive emulation
|
| 4 | | |
| 5 | | Copyright MESS Team.
|
| 6 | | Visit http://mamedev.org for licensing and usage restrictions.
|
| 7 | | |
| 8 | | **********************************************************************/
|
| 9 | | |
| 10 | | /*
|
| 11 | | |
| 12 | | TODO:
|
| 13 | | |
| 14 | | - everything
|
| 15 | | |
| 16 | | */
|
| 17 | | |
| 18 | | #include "emu.h"
|
| 19 | | #include "c9060.h"
|
| 20 | | #include "cpu/m6502/m6502.h"
|
| 21 | | #include "machine/6522via.h"
|
| 22 | | #include "machine/6532riot.h"
|
| 23 | | #include "machine/ieee488.h"
|
| 24 | | |
| 25 | | /***************************************************************************
|
| 26 | | PARAMETERS
|
| 27 | | ***************************************************************************/
|
| 28 | | |
| 29 | | #define LOG 0
|
| 30 | | |
| 31 | | #define M6502_TAG "7e"
|
| 32 | | #define M6532_0_TAG "7f"
|
| 33 | | #define M6532_1_TAG "7g"
|
| 34 | | |
| 35 | | #define M6504_TAG "4a"
|
| 36 | | #define M6522_TAG "4b"
|
| 37 | | |
| 38 | | #define C9060_REGION "c9060"
|
| 39 | | |
| 40 | | /***************************************************************************
|
| 41 | | TYPE DEFINITIONS
|
| 42 | | ***************************************************************************/
|
| 43 | | |
| 44 | | typedef struct _c9060_t c9060_t;
|
| 45 | | struct _c9060_t
|
| 46 | | {
|
| 47 | | /* IEEE-488 bus */
|
| 48 | | int address; /* device address - 8 */
|
| 49 | | int rfdo; /* not ready for data output */
|
| 50 | | int daco; /* not data accepted output */
|
| 51 | | int atna; /* attention acknowledge */
|
| 52 | | |
| 53 | | /* devices */
|
| 54 | | running_device *cpu_dos;
|
| 55 | | running_device *cpu_hdc;
|
| 56 | | running_device *riot0;
|
| 57 | | running_device *riot1;
|
| 58 | | running_device *via;
|
| 59 | | running_device *bus;
|
| 60 | | };
|
| 61 | | |
| 62 | | /***************************************************************************
|
| 63 | | INLINE FUNCTIONS
|
| 64 | | ***************************************************************************/
|
| 65 | | |
| 66 | | INLINE c9060_t *get_safe_token(running_device *device)
|
| 67 | | {
|
| 68 | | assert(device != NULL);
|
| 69 | | assert(device->token != NULL);
|
| 70 | | assert((device->type == C9060) || (device->type == C9090));
|
| 71 | | return (c9060_t *)device->token;
|
| 72 | | }
|
| 73 | | |
| 74 | | INLINE c9060_config *get_safe_config(running_device *device)
|
| 75 | | {
|
| 76 | | assert(device != NULL);
|
| 77 | | assert((device->type == C9060) || (device->type == C9090));
|
| 78 | | return (c9060_config *)device->baseconfig().inline_config;
|
| 79 | | }
|
| 80 | | |
| 81 | | INLINE void update_ieee_signals(running_device *device)
|
| 82 | | {
|
| 83 | | c9060_t *c9060 = get_safe_token(device);
|
| 84 | | |
| 85 | | int atn = ieee488_atn_r(c9060->bus);
|
| 86 | | int atna = c9060->atna;
|
| 87 | | int rfdo = c9060->rfdo;
|
| 88 | | int daco = c9060->daco;
|
| 89 | | |
| 90 | | int nrfd = !(!(!(atn&atna)&rfdo)|!(atn|atna));
|
| 91 | | int ndac = !(daco|!(atn|atna));
|
| 92 | | |
| 93 | | ieee488_nrfd_w(c9060->bus, device, nrfd);
|
| 94 | | ieee488_ndac_w(c9060->bus, device, ndac);
|
| 95 | | }
|
| 96 | | |
| 97 | | /***************************************************************************
|
| 98 | | IMPLEMENTATION
|
| 99 | | ***************************************************************************/
|
| 100 | | |
| 101 | | /*-------------------------------------------------
|
| 102 | | c9060_ieee488_atn_w - IEEE-488 bus attention
|
| 103 | | -------------------------------------------------*/
|
| 104 | | |
| 105 | | WRITE_LINE_DEVICE_HANDLER( c9060_ieee488_atn_w )
|
| 106 | | {
|
| 107 | | c9060_t *c9060 = get_safe_token(device);
|
| 108 | | |
| 109 | | update_ieee_signals(device);
|
| 110 | | |
| 111 | | /* set RIOT PA7 */
|
| 112 | | riot6532_porta_in_set(c9060->riot1, !state << 7, 0x80);
|
| 113 | | }
|
| 114 | | |
| 115 | | /*-------------------------------------------------
|
| 116 | | c9060_ieee488_ifc_w - IEEE-488 bus reset
|
| 117 | | -------------------------------------------------*/
|
| 118 | | |
| 119 | | WRITE_LINE_DEVICE_HANDLER( c9060_ieee488_ifc_w )
|
| 120 | | {
|
| 121 | | if (!state)
|
| 122 | | {
|
| 123 | | device->reset();
|
| 124 | | }
|
| 125 | | }
|
| 126 | | |
| 127 | | /*-------------------------------------------------
|
| 128 | | ADDRESS_MAP( c9060_dos_map )
|
| 129 | | -------------------------------------------------*/
|
| 130 | | |
| 131 | | static ADDRESS_MAP_START( c9060_dos_map, ADDRESS_SPACE_PROGRAM, 8 )
|
| 132 | | AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x0100) AM_RAM // 6532 #1
|
| 133 | | AM_RANGE(0x0080, 0x00ff) AM_MIRROR(0x0100) AM_RAM // 6532 #2
|
| 134 | | AM_RANGE(0x0200, 0x021f) AM_MIRROR(0x0d60) AM_DEVREADWRITE(M6532_0_TAG, riot6532_r, riot6532_w)
|
| 135 | | AM_RANGE(0x0280, 0x029f) AM_MIRROR(0x0d60) AM_DEVREADWRITE(M6532_1_TAG, riot6532_r, riot6532_w)
|
| 136 | | AM_RANGE(0x1000, 0x13ff) AM_MIRROR(0x0c00) AM_RAM AM_SHARE("share1")
|
| 137 | | AM_RANGE(0x2000, 0x23ff) AM_MIRROR(0x0c00) AM_RAM AM_SHARE("share2")
|
| 138 | | AM_RANGE(0x3000, 0x33ff) AM_MIRROR(0x0c00) AM_RAM AM_SHARE("share3")
|
| 139 | | AM_RANGE(0x4000, 0x43ff) AM_MIRROR(0x0c00) AM_RAM AM_SHARE("share4")
|
| 140 | | AM_RANGE(0xc000, 0xffff) AM_ROM AM_REGION(C9060_REGION, 0x0000)
|
| 141 | | ADDRESS_MAP_END
|
| 142 | | |
| 143 | | /*-------------------------------------------------
|
| 144 | | ADDRESS_MAP( c9060_fdc_map )
|
| 145 | | -------------------------------------------------*/
|
| 146 | | |
| 147 | | static ADDRESS_MAP_START( c9060_fdc_map, ADDRESS_SPACE_PROGRAM, 8 )
|
| 148 | | ADDRESS_MAP_GLOBAL_MASK(0x1fff)
|
| 149 | | AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_RAM // 6530
|
| 150 | | AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6522_TAG, via_r, via_w)
|
| 151 | | AM_RANGE(0x0400, 0x07ff) AM_RAM AM_SHARE("share1")
|
| 152 | | AM_RANGE(0x0800, 0x0bff) AM_RAM AM_SHARE("share2")
|
| 153 | | AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("share3")
|
| 154 | | AM_RANGE(0x1000, 0x13ff) AM_RAM AM_SHARE("share4")
|
| 155 | | AM_RANGE(0x1800, 0x1fff) AM_ROM AM_REGION(C9060_REGION, 0x2000) // 6530
|
| 156 | | ADDRESS_MAP_END
|
| 157 | | |
| 158 | | /*-------------------------------------------------
|
| 159 | | riot6532_interface riot0_intf 7f
|
| 160 | | -------------------------------------------------*/
|
| 161 | | |
| 162 | | static READ8_DEVICE_HANDLER( dio_r )
|
| 163 | | {
|
| 164 | | /*
|
| 165 | | |
| 166 | | bit description
|
| 167 | | |
| 168 | | PA0 DI0
|
| 169 | | PA1 DI1
|
| 170 | | PA2 DI2
|
| 171 | | PA3 DI3
|
| 172 | | PA4 DI4
|
| 173 | | PA5 DI5
|
| 174 | | PA6 DI6
|
| 175 | | PA7 DI7
|
| 176 | | |
| 177 | | */
|
| 178 | | |
| 179 | | c9060_t *c9060 = get_safe_token(device->owner);
|
| 180 | | |
| 181 | | return ieee488_dio_r(c9060->bus, 0);
|
| 182 | | }
|
| 183 | | |
| 184 | | static WRITE8_DEVICE_HANDLER( dio_w )
|
| 185 | | {
|
| 186 | | /*
|
| 187 | | |
| 188 | | bit description
|
| 189 | | |
| 190 | | PB0 DO0
|
| 191 | | PB1 DO1
|
| 192 | | PB2 DO2
|
| 193 | | PB3 DO3
|
| 194 | | PB4 DO4
|
| 195 | | PB5 DO5
|
| 196 | | PB6 DO6
|
| 197 | | PB7 DO7
|
| 198 | | |
| 199 | | */
|
| 200 | | |
| 201 | | c9060_t *c9060 = get_safe_token(device->owner);
|
| 202 | | |
| 203 | | ieee488_dio_w(c9060->bus, device->owner, data);
|
| 204 | | }
|
| 205 | | |
| 206 | | static const riot6532_interface riot0_intf =
|
| 207 | | {
|
| 208 | | DEVCB_HANDLER(dio_r),
|
| 209 | | DEVCB_NULL,
|
| 210 | | DEVCB_NULL,
|
| 211 | | DEVCB_HANDLER(dio_w),
|
| 212 | | DEVCB_NULL
|
| 213 | | };
|
| 214 | | |
| 215 | | /*-------------------------------------------------
|
| 216 | | riot6532_interface riot1_intf ue1
|
| 217 | | -------------------------------------------------*/
|
| 218 | | |
| 219 | | static READ8_DEVICE_HANDLER( riot1_pa_r )
|
| 220 | | {
|
| 221 | | /*
|
| 222 | | |
| 223 | | bit description
|
| 224 | | |
| 225 | | PA0 ATNA
|
| 226 | | PA1 DACO
|
| 227 | | PA2 RFDO
|
| 228 | | PA3 EOIO
|
| 229 | | PA4 DAVO
|
| 230 | | PA5 EOII
|
| 231 | | PA6 DAVI
|
| 232 | | PA7 _ATN
|
| 233 | | |
| 234 | | */
|
| 235 | | |
| 236 | | c9060_t *c9060 = get_safe_token(device->owner);
|
| 237 | | |
| 238 | | UINT8 data = 0;
|
| 239 | | |
| 240 | | /* end or identify in */
|
| 241 | | data |= ieee488_eoi_r(c9060->bus) << 5;
|
| 242 | | |
| 243 | | /* data valid in */
|
| 244 | | data |= ieee488_dav_r(c9060->bus) << 6;
|
| 245 | | |
| 246 | | /* attention */
|
| 247 | | data |= !ieee488_atn_r(c9060->bus) << 7;
|
| 248 | | |
| 249 | | return data;
|
| 250 | | }
|
| 251 | | |
| 252 | | static WRITE8_DEVICE_HANDLER( riot1_pa_w )
|
| 253 | | {
|
| 254 | | /*
|
| 255 | | |
| 256 | | bit description
|
| 257 | | |
| 258 | | PA0 ATNA
|
| 259 | | PA1 DACO
|
| 260 | | PA2 RFDO
|
| 261 | | PA3 EOIO
|
| 262 | | PA4 DAVO
|
| 263 | | PA5 EOII
|
| 264 | | PA6 DAVI
|
| 265 | | PA7 _ATN
|
| 266 | | |
| 267 | | */
|
| 268 | | |
| 269 | | c9060_t *c9060 = get_safe_token(device->owner);
|
| 270 | | |
| 271 | | /* attention acknowledge */
|
| 272 | | c9060->atna = BIT(data, 0);
|
| 273 | | |
| 274 | | /* data accepted out */
|
| 275 | | c9060->daco = BIT(data, 1);
|
| 276 | | |
| 277 | | /* not ready for data out */
|
| 278 | | c9060->rfdo = BIT(data, 2);
|
| 279 | | |
| 280 | | /* end or identify out */
|
| 281 | | ieee488_eoi_w(c9060->bus, device->owner, BIT(data, 3));
|
| 282 | | |
| 283 | | /* data valid out */
|
| 284 | | ieee488_dav_w(c9060->bus, device->owner, BIT(data, 4));
|
| 285 | | |
| 286 | | update_ieee_signals(device->owner);
|
| 287 | | }
|
| 288 | | |
| 289 | | static READ8_DEVICE_HANDLER( riot1_pb_r )
|
| 290 | | {
|
| 291 | | /*
|
| 292 | | |
| 293 | | bit description
|
| 294 | | |
| 295 | | PB0
|
| 296 | | PB1
|
| 297 | | PB2
|
| 298 | | PB3
|
| 299 | | PB4 DRIVE RDY
|
| 300 | | PB5 PWR ON AND NO ERRORS
|
| 301 | | PB6 DACI
|
| 302 | | PB7 RFDI
|
| 303 | | |
| 304 | | */
|
| 305 | | |
| 306 | | c9060_t *c9060 = get_safe_token(device->owner);
|
| 307 | | |
| 308 | | UINT8 data = 0;
|
| 309 | | |
| 310 | | /* data accepted in */
|
| 311 | | data |= ieee488_ndac_r(c9060->bus) << 6;
|
| 312 | | |
| 313 | | /* ready for data in */
|
| 314 | | data |= ieee488_nrfd_r(c9060->bus) << 7;
|
| 315 | | |
| 316 | | return data;
|
| 317 | | }
|
| 318 | | |
| 319 | | static WRITE8_DEVICE_HANDLER( riot1_pb_w )
|
| 320 | | {
|
| 321 | | /*
|
| 322 | | |
| 323 | | bit description
|
| 324 | | |
| 325 | | PB0
|
| 326 | | PB1
|
| 327 | | PB2
|
| 328 | | PB3
|
| 329 | | PB4 DRIVE RDY
|
| 330 | | PB5 PWR ON AND NO ERRORS
|
| 331 | | PB6 DACI
|
| 332 | | PB7 RFDI
|
| 333 | | |
| 334 | | */
|
| 335 | | }
|
| 336 | | |
| 337 | | static WRITE_LINE_DEVICE_HANDLER( riot1_irq_w )
|
| 338 | | {
|
| 339 | | c9060_t *c9060 = get_safe_token(device->owner);
|
| 340 | | |
| 341 | | cpu_set_input_line(c9060->cpu_dos, M6502_IRQ_LINE, state);
|
| 342 | | }
|
| 343 | | |
| 344 | | static const riot6532_interface riot1_intf =
|
| 345 | | {
|
| 346 | | DEVCB_HANDLER(riot1_pa_r),
|
| 347 | | DEVCB_HANDLER(riot1_pb_r),
|
| 348 | | DEVCB_HANDLER(riot1_pa_w),
|
| 349 | | DEVCB_HANDLER(riot1_pb_w),
|
| 350 | | DEVCB_LINE(riot1_irq_w)
|
| 351 | | };
|
| 352 | | |
| 353 | | /*-------------------------------------------------
|
| 354 | | via6522_interface via_intf 4b
|
| 355 | | -------------------------------------------------*/
|
| 356 | | |
| 357 | | static READ8_DEVICE_HANDLER( via_pa_r )
|
| 358 | | {
|
| 359 | | /*
|
| 360 | | |
| 361 | | bit description
|
| 362 | | |
| 363 | | PA0 DB0
|
| 364 | | PA1 DB1
|
| 365 | | PA2 DB2
|
| 366 | | PA3 DB3
|
| 367 | | PA4 DB4
|
| 368 | | PA5 DB5
|
| 369 | | PA6 DB6
|
| 370 | | PA7 DB7
|
| 371 | | |
| 372 | | */
|
| 373 | | |
| 374 | | return 0;
|
| 375 | | }
|
| 376 | | |
| 377 | | static WRITE8_DEVICE_HANDLER( via_pa_w )
|
| 378 | | {
|
| 379 | | /*
|
| 380 | | |
| 381 | | bit description
|
| 382 | | |
| 383 | | PA0 DB0
|
| 384 | | PA1 DB1
|
| 385 | | PA2 DB2
|
| 386 | | PA3 DB3
|
| 387 | | PA4 DB4
|
| 388 | | PA5 DB5
|
| 389 | | PA6 DB6
|
| 390 | | PA7 DB7
|
| 391 | | |
| 392 | | */
|
| 393 | | }
|
| 394 | | |
| 395 | | static READ8_DEVICE_HANDLER( via_pb_r )
|
| 396 | | {
|
| 397 | | /*
|
| 398 | | |
| 399 | | bit description
|
| 400 | | |
| 401 | | PB0 SEL
|
| 402 | | PB1 RST
|
| 403 | | PB2 C/D
|
| 404 | | PB3 BUSY
|
| 405 | | PB4 J14
|
| 406 | | PB5 J14
|
| 407 | | PB6 I/O
|
| 408 | | PB7 MSG
|
| 409 | | |
| 410 | | */
|
| 411 | | |
| 412 | | return 0;
|
| 413 | | }
|
| 414 | | |
| 415 | | static WRITE8_DEVICE_HANDLER( via_pb_w )
|
| 416 | | {
|
| 417 | | /*
|
| 418 | | |
| 419 | | bit description
|
| 420 | | |
| 421 | | PB0 SEL
|
| 422 | | PB1 RST
|
| 423 | | PB2 C/D
|
| 424 | | PB3 BUSY
|
| 425 | | PB4 J14
|
| 426 | | PB5 J14
|
| 427 | | PB6 I/O
|
| 428 | | PB7 MSG
|
| 429 | | |
| 430 | | */
|
| 431 | | }
|
| 432 | | |
| 433 | | static const via6522_interface via_intf =
|
| 434 | | {
|
| 435 | | DEVCB_HANDLER(via_pa_r),
|
| 436 | | DEVCB_HANDLER(via_pb_r),
|
| 437 | | DEVCB_NULL, // ACK
|
| 438 | | DEVCB_NULL,
|
| 439 | | DEVCB_NULL, // MSG
|
| 440 | | DEVCB_NULL, // ?
|
| 441 | | |
| 442 | | DEVCB_HANDLER(via_pa_w),
|
| 443 | | DEVCB_HANDLER(via_pb_w),
|
| 444 | | DEVCB_NULL,
|
| 445 | | DEVCB_NULL,
|
| 446 | | DEVCB_NULL,
|
| 447 | | DEVCB_NULL,
|
| 448 | | |
| 449 | | DEVCB_NULL
|
| 450 | | };
|
| 451 | | |
| 452 | | /*-------------------------------------------------
|
| 453 | | MACHINE_DRIVER( c9060 )
|
| 454 | | -------------------------------------------------*/
|
| 455 | | |
| 456 | | static MACHINE_DRIVER_START( c9060 )
|
| 457 | | /* DOS */
|
| 458 | | MDRV_CPU_ADD(M6502_TAG, M6502, XTAL_16MHz/16)
|
| 459 | | MDRV_CPU_PROGRAM_MAP(c9060_dos_map)
|
| 460 | | |
| 461 | | MDRV_RIOT6532_ADD(M6532_0_TAG, XTAL_16MHz/16, riot0_intf)
|
| 462 | | MDRV_RIOT6532_ADD(M6532_1_TAG, XTAL_16MHz/16, riot1_intf)
|
| 463 | | |
| 464 | | /* controller */
|
| 465 | | MDRV_CPU_ADD(M6504_TAG, M6502, XTAL_16MHz/16)
|
| 466 | | MDRV_CPU_PROGRAM_MAP(c9060_fdc_map)
|
| 467 | | |
| 468 | | MDRV_VIA6522_ADD(M6522_TAG, XTAL_16MHz/16, via_intf)
|
| 469 | | |
| 470 | | // Tandon TM602S
|
| 471 | | MACHINE_DRIVER_END
|
| 472 | | |
| 473 | | /*-------------------------------------------------
|
| 474 | | MACHINE_DRIVER( c9090 )
|
| 475 | | -------------------------------------------------*/
|
| 476 | | |
| 477 | | static MACHINE_DRIVER_START( c9090 )
|
| 478 | | MDRV_IMPORT_FROM(c9060)
|
| 479 | | |
| 480 | | // Tandon TM603S
|
| 481 | | MACHINE_DRIVER_END
|
| 482 | | |
| 483 | | /*-------------------------------------------------
|
| 484 | | ROM( c9060 )
|
| 485 | | -------------------------------------------------*/
|
| 486 | | |
| 487 | | ROM_START( c9060 ) // schematic 300010
|
| 488 | | ROM_REGION( 0x4800, C9060_REGION, ROMREGION_LOADBYNAME )
|
| 489 | | ROM_LOAD( "300516-revb.7c", 0x0000, 0x2000, CRC(2d758a14) SHA1(c959cc9dde84fc3d64e95e58a0a096a26d8107fd) )
|
| 490 | | ROM_LOAD( "300516-revc.7c", 0x0000, 0x2000, CRC(d6a3e88f) SHA1(bb1ddb5da94a86266012eca54818aa21dc4cef6a) )
|
| 491 | | ROM_LOAD( "300517-reva.7d", 0x2000, 0x2000, CRC(566df630) SHA1(b1602dfff408b165ee52a6a4ca3e2ec27e689ba9) )
|
| 492 | | ROM_LOAD( "300517-revb.7d", 0x2000, 0x2000, CRC(f0382bc3) SHA1(0b0a8dc520f5b41ffa832e4a636b3d226ccbb7f1) )
|
| 493 | | ROM_LOAD( "300517-revc.7d", 0x2000, 0x2000, CRC(2a9ad4ad) SHA1(4c17d014de48c906871b9b6c7d037d8736b1fd52) )
|
| 494 | | |
| 495 | | ROM_LOAD( "300515-reva.4c", 0x4000, 0x0800, CRC(99e096f7) SHA1(a3d1deb27bf5918b62b89c27fa3e488eb8f717a4) )
|
| 496 | | ROM_LOAD( "300515-revb.4c", 0x4000, 0x0800, CRC(49adf4fb) SHA1(59dafbd4855083074ba8dc96a04d4daa5b76e0d6) )
|
| 497 | | ROM_END
|
| 498 | | |
| 499 | | /*-------------------------------------------------
|
| 500 | | DEVICE_START( c9060 )
|
| 501 | | -------------------------------------------------*/
|
| 502 | | |
| 503 | | static DEVICE_START( c9060 )
|
| 504 | | {
|
| 505 | | c9060_t *c9060 = get_safe_token(device);
|
| 506 | | const c9060_config *config = get_safe_config(device);
|
| 507 | | |
| 508 | | /* find our CPU */
|
| 509 | | c9060->cpu_dos = device->subdevice(M6502_TAG);
|
| 510 | | c9060->cpu_hdc = device->subdevice(M6504_TAG);
|
| 511 | | |
| 512 | | /* find devices */
|
| 513 | | c9060->riot0 = device->subdevice(M6532_0_TAG);
|
| 514 | | c9060->riot1 = device->subdevice(M6532_1_TAG);
|
| 515 | | c9060->via = device->subdevice(M6522_TAG);
|
| 516 | | c9060->bus = devtag_get_device(device->machine, config->bus_tag);
|
| 517 | | |
| 518 | | /* register for state saving */
|
| 519 | | // state_save_register_device_item(device, 0, c9060->);
|
| 520 | | }
|
| 521 | | |
| 522 | | /*-------------------------------------------------
|
| 523 | | DEVICE_RESET( c9060 )
|
| 524 | | -------------------------------------------------*/
|
| 525 | | |
| 526 | | static DEVICE_RESET( c9060 )
|
| 527 | | {
|
| 528 | | c9060_t *c9060 = get_safe_token(device);
|
| 529 | | |
| 530 | | /* reset devices */
|
| 531 | | c9060->cpu_dos->reset();
|
| 532 | | c9060->cpu_hdc->reset();
|
| 533 | | c9060->riot0->reset();
|
| 534 | | c9060->riot1->reset();
|
| 535 | | c9060->via->reset();
|
| 536 | | |
| 537 | | /* toggle M6502 SO */
|
| 538 | | cpu_set_input_line(c9060->cpu_dos, M6502_SET_OVERFLOW, ASSERT_LINE);
|
| 539 | | cpu_set_input_line(c9060->cpu_dos, M6502_SET_OVERFLOW, CLEAR_LINE);
|
| 540 | | }
|
| 541 | | |
| 542 | | /*-------------------------------------------------
|
| 543 | | DEVICE_GET_INFO( c9060 )
|
| 544 | | -------------------------------------------------*/
|
| 545 | | |
| 546 | | DEVICE_GET_INFO( c9060 )
|
| 547 | | {
|
| 548 | | switch (state)
|
| 549 | | {
|
| 550 | | /* --- the following bits of info are returned as 64-bit signed integers --- */
|
| 551 | | case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(c9060_t); break;
|
| 552 | | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(c9060_config); break;
|
| 553 | | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
|
| 554 | | |
| 555 | | /* --- the following bits of info are returned as pointers --- */
|
| 556 | | case DEVINFO_PTR_ROM_REGION: info->romregion = ROM_NAME(c9060); break;
|
| 557 | | case DEVINFO_PTR_MACHINE_CONFIG: info->machine_config = MACHINE_DRIVER_NAME(c9060); break;
|
| 558 | | |
| 559 | | /* --- the following bits of info are returned as pointers to data or functions --- */
|
| 560 | | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(c9060); break;
|
| 561 | | case DEVINFO_FCT_STOP: /* Nothing */ break;
|
| 562 | | case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(c9060); break;
|
| 563 | | |
| 564 | | /* --- the following bits of info are returned as NULL-terminated strings --- */
|
| 565 | | case DEVINFO_STR_NAME: strcpy(info->s, "Commodore 9060"); break;
|
| 566 | | case DEVINFO_STR_FAMILY: strcpy(info->s, "Commodore PET"); break;
|
| 567 | | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
|
| 568 | | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
| 569 | | case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MESS Team"); break;
|
| 570 | | }
|
| 571 | | }
|
| 572 | | |
| 573 | | /*-------------------------------------------------
|
| 574 | | DEVICE_GET_INFO( c9090 )
|
| 575 | | -------------------------------------------------*/
|
| 576 | | |
| 577 | | DEVICE_GET_INFO( c9090 )
|
| 578 | | {
|
| 579 | | switch (state)
|
| 580 | | {
|
| 581 | | /* --- the following bits of info are returned as pointers --- */
|
| 582 | | case DEVINFO_PTR_MACHINE_CONFIG: info->machine_config = MACHINE_DRIVER_NAME(c9090); break;
|
| 583 | | |
| 584 | | /* --- the following bits of info are returned as NULL-terminated strings --- */
|
| 585 | | case DEVINFO_STR_NAME: strcpy(info->s, "Commodore 9090"); break;
|
| 586 | | |
| 587 | | default: DEVICE_GET_INFO_CALL(c9060); break;
|
| 588 | | }
|
| 589 | | }
|
| 1 | /********************************************************************** |
| 2 | |
| 3 | Commodore 9060/9090 Hard Disk Drive emulation |
| 4 | |
| 5 | Copyright MESS Team. |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. |
| 7 | |
| 8 | **********************************************************************/ |
| 9 | |
| 10 | /* |
| 11 | |
| 12 | TODO: |
| 13 | |
| 14 | - everything |
| 15 | |
| 16 | */ |
| 17 | |
| 18 | #include "emu.h" |
| 19 | #include "c9060.h" |
| 20 | #include "cpu/m6502/m6502.h" |
| 21 | #include "machine/6522via.h" |
| 22 | #include "machine/6532riot.h" |
| 23 | #include "machine/ieee488.h" |
| 24 | |
| 25 | /*************************************************************************** |
| 26 | PARAMETERS |
| 27 | ***************************************************************************/ |
| 28 | |
| 29 | #define LOG 0 |
| 30 | |
| 31 | #define M6502_TAG "7e" |
| 32 | #define M6532_0_TAG "7f" |
| 33 | #define M6532_1_TAG "7g" |
| 34 | |
| 35 | #define M6504_TAG "4a" |
| 36 | #define M6522_TAG "4b" |
| 37 | |
| 38 | #define C9060_REGION "c9060" |
| 39 | |
| 40 | /*************************************************************************** |
| 41 | TYPE DEFINITIONS |
| 42 | ***************************************************************************/ |
| 43 | |
| 44 | typedef struct _c9060_t c9060_t; |
| 45 | struct _c9060_t |
| 46 | { |
| 47 | /* IEEE-488 bus */ |
| 48 | int address; /* device address - 8 */ |
| 49 | int rfdo; /* not ready for data output */ |
| 50 | int daco; /* not data accepted output */ |
| 51 | int atna; /* attention acknowledge */ |
| 52 | |
| 53 | /* devices */ |
| 54 | running_device *cpu_dos; |
| 55 | running_device *cpu_hdc; |
| 56 | running_device *riot0; |
| 57 | running_device *riot1; |
| 58 | running_device *via; |
| 59 | running_device *bus; |
| 60 | }; |
| 61 | |
| 62 | /*************************************************************************** |
| 63 | INLINE FUNCTIONS |
| 64 | ***************************************************************************/ |
| 65 | |
| 66 | INLINE c9060_t *get_safe_token(running_device *device) |
| 67 | { |
| 68 | assert(device != NULL); |
| 69 | assert(device->token != NULL); |
| 70 | assert((device->type == C9060) || (device->type == C9090)); |
| 71 | return (c9060_t *)device->token; |
| 72 | } |
| 73 | |
| 74 | INLINE c9060_config *get_safe_config(running_device *device) |
| 75 | { |
| 76 | assert(device != NULL); |
| 77 | assert((device->type == C9060) || (device->type == C9090)); |
| 78 | return (c9060_config *)device->baseconfig().inline_config; |
| 79 | } |
| 80 | |
| 81 | INLINE void update_ieee_signals(running_device *device) |
| 82 | { |
| 83 | c9060_t *c9060 = get_safe_token(device); |
| 84 | |
| 85 | int atn = ieee488_atn_r(c9060->bus); |
| 86 | int atna = c9060->atna; |
| 87 | int rfdo = c9060->rfdo; |
| 88 | int daco = c9060->daco; |
| 89 | |
| 90 | int nrfd = !(!(!(atn&atna)&rfdo)|!(atn|atna)); |
| 91 | int ndac = !(daco|!(atn|atna)); |
| 92 | |
| 93 | ieee488_nrfd_w(c9060->bus, device, nrfd); |
| 94 | ieee488_ndac_w(c9060->bus, device, ndac); |
| 95 | } |
| 96 | |
| 97 | /*************************************************************************** |
| 98 | IMPLEMENTATION |
| 99 | ***************************************************************************/ |
| 100 | |
| 101 | /*------------------------------------------------- |
| 102 | c9060_ieee488_atn_w - IEEE-488 bus attention |
| 103 | -------------------------------------------------*/ |
| 104 | |
| 105 | WRITE_LINE_DEVICE_HANDLER( c9060_ieee488_atn_w ) |
| 106 | { |
| 107 | c9060_t *c9060 = get_safe_token(device); |
| 108 | |
| 109 | update_ieee_signals(device); |
| 110 | |
| 111 | /* set RIOT PA7 */ |
| 112 | riot6532_porta_in_set(c9060->riot1, !state << 7, 0x80); |
| 113 | } |
| 114 | |
| 115 | /*------------------------------------------------- |
| 116 | c9060_ieee488_ifc_w - IEEE-488 bus reset |
| 117 | -------------------------------------------------*/ |
| 118 | |
| 119 | WRITE_LINE_DEVICE_HANDLER( c9060_ieee488_ifc_w ) |
| 120 | { |
| 121 | if (!state) |
| 122 | { |
| 123 | device->reset(); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | /*------------------------------------------------- |
| 128 | ADDRESS_MAP( c9060_dos_map ) |
| 129 | -------------------------------------------------*/ |
| 130 | |
| 131 | static ADDRESS_MAP_START( c9060_dos_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 132 | AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x0100) AM_RAM // 6532 #1 |
| 133 | AM_RANGE(0x0080, 0x00ff) AM_MIRROR(0x0100) AM_RAM // 6532 #2 |
| 134 | AM_RANGE(0x0200, 0x021f) AM_MIRROR(0x0d60) AM_DEVREADWRITE(M6532_0_TAG, riot6532_r, riot6532_w) |
| 135 | AM_RANGE(0x0280, 0x029f) AM_MIRROR(0x0d60) AM_DEVREADWRITE(M6532_1_TAG, riot6532_r, riot6532_w) |
| 136 | AM_RANGE(0x1000, 0x13ff) AM_MIRROR(0x0c00) AM_RAM AM_SHARE("share1") |
| 137 | AM_RANGE(0x2000, 0x23ff) AM_MIRROR(0x0c00) AM_RAM AM_SHARE("share2") |
| 138 | AM_RANGE(0x3000, 0x33ff) AM_MIRROR(0x0c00) AM_RAM AM_SHARE("share3") |
| 139 | AM_RANGE(0x4000, 0x43ff) AM_MIRROR(0x0c00) AM_RAM AM_SHARE("share4") |
| 140 | AM_RANGE(0xc000, 0xffff) AM_ROM AM_REGION(C9060_REGION, 0x0000) |
| 141 | ADDRESS_MAP_END |
| 142 | |
| 143 | /*------------------------------------------------- |
| 144 | ADDRESS_MAP( c9060_fdc_map ) |
| 145 | -------------------------------------------------*/ |
| 146 | |
| 147 | static ADDRESS_MAP_START( c9060_fdc_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 148 | ADDRESS_MAP_GLOBAL_MASK(0x1fff) |
| 149 | AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_RAM // 6530 |
| 150 | AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6522_TAG, via_r, via_w) |
| 151 | AM_RANGE(0x0400, 0x07ff) AM_RAM AM_SHARE("share1") |
| 152 | AM_RANGE(0x0800, 0x0bff) AM_RAM AM_SHARE("share2") |
| 153 | AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("share3") |
| 154 | AM_RANGE(0x1000, 0x13ff) AM_RAM AM_SHARE("share4") |
| 155 | AM_RANGE(0x1800, 0x1fff) AM_ROM AM_REGION(C9060_REGION, 0x2000) // 6530 |
| 156 | ADDRESS_MAP_END |
| 157 | |
| 158 | /*------------------------------------------------- |
| 159 | riot6532_interface riot0_intf 7f |
| 160 | -------------------------------------------------*/ |
| 161 | |
| 162 | static READ8_DEVICE_HANDLER( dio_r ) |
| 163 | { |
| 164 | /* |
| 165 | |
| 166 | bit description |
| 167 | |
| 168 | PA0 DI0 |
| 169 | PA1 DI1 |
| 170 | PA2 DI2 |
| 171 | PA3 DI3 |
| 172 | PA4 DI4 |
| 173 | PA5 DI5 |
| 174 | PA6 DI6 |
| 175 | PA7 DI7 |
| 176 | |
| 177 | */ |
| 178 | |
| 179 | c9060_t *c9060 = get_safe_token(device->owner); |
| 180 | |
| 181 | return ieee488_dio_r(c9060->bus, 0); |
| 182 | } |
| 183 | |
| 184 | static WRITE8_DEVICE_HANDLER( dio_w ) |
| 185 | { |
| 186 | /* |
| 187 | |
| 188 | bit description |
| 189 | |
| 190 | PB0 DO0 |
| 191 | PB1 DO1 |
| 192 | PB2 DO2 |
| 193 | PB3 DO3 |
| 194 | PB4 DO4 |
| 195 | PB5 DO5 |
| 196 | PB6 DO6 |
| 197 | PB7 DO7 |
| 198 | |
| 199 | */ |
| 200 | |
| 201 | c9060_t *c9060 = get_safe_token(device->owner); |
| 202 | |
| 203 | ieee488_dio_w(c9060->bus, device->owner, data); |
| 204 | } |
| 205 | |
| 206 | static const riot6532_interface riot0_intf = |
| 207 | { |
| 208 | DEVCB_HANDLER(dio_r), |
| 209 | DEVCB_NULL, |
| 210 | DEVCB_NULL, |
| 211 | DEVCB_HANDLER(dio_w), |
| 212 | DEVCB_NULL |
| 213 | }; |
| 214 | |
| 215 | /*------------------------------------------------- |
| 216 | riot6532_interface riot1_intf ue1 |
| 217 | -------------------------------------------------*/ |
| 218 | |
| 219 | static READ8_DEVICE_HANDLER( riot1_pa_r ) |
| 220 | { |
| 221 | /* |
| 222 | |
| 223 | bit description |
| 224 | |
| 225 | PA0 ATNA |
| 226 | PA1 DACO |
| 227 | PA2 RFDO |
| 228 | PA3 EOIO |
| 229 | PA4 DAVO |
| 230 | PA5 EOII |
| 231 | PA6 DAVI |
| 232 | PA7 _ATN |
| 233 | |
| 234 | */ |
| 235 | |
| 236 | c9060_t *c9060 = get_safe_token(device->owner); |
| 237 | |
| 238 | UINT8 data = 0; |
| 239 | |
| 240 | /* end or identify in */ |
| 241 | data |= ieee488_eoi_r(c9060->bus) << 5; |
| 242 | |
| 243 | /* data valid in */ |
| 244 | data |= ieee488_dav_r(c9060->bus) << 6; |
| 245 | |
| 246 | /* attention */ |
| 247 | data |= !ieee488_atn_r(c9060->bus) << 7; |
| 248 | |
| 249 | return data; |
| 250 | } |
| 251 | |
| 252 | static WRITE8_DEVICE_HANDLER( riot1_pa_w ) |
| 253 | { |
| 254 | /* |
| 255 | |
| 256 | bit description |
| 257 | |
| 258 | PA0 ATNA |
| 259 | PA1 DACO |
| 260 | PA2 RFDO |
| 261 | PA3 EOIO |
| 262 | PA4 DAVO |
| 263 | PA5 EOII |
| 264 | PA6 DAVI |
| 265 | PA7 _ATN |
| 266 | |
| 267 | */ |
| 268 | |
| 269 | c9060_t *c9060 = get_safe_token(device->owner); |
| 270 | |
| 271 | /* attention acknowledge */ |
| 272 | c9060->atna = BIT(data, 0); |
| 273 | |
| 274 | /* data accepted out */ |
| 275 | c9060->daco = BIT(data, 1); |
| 276 | |
| 277 | /* not ready for data out */ |
| 278 | c9060->rfdo = BIT(data, 2); |
| 279 | |
| 280 | /* end or identify out */ |
| 281 | ieee488_eoi_w(c9060->bus, device->owner, BIT(data, 3)); |
| 282 | |
| 283 | /* data valid out */ |
| 284 | ieee488_dav_w(c9060->bus, device->owner, BIT(data, 4)); |
| 285 | |
| 286 | update_ieee_signals(device->owner); |
| 287 | } |
| 288 | |
| 289 | static READ8_DEVICE_HANDLER( riot1_pb_r ) |
| 290 | { |
| 291 | /* |
| 292 | |
| 293 | bit description |
| 294 | |
| 295 | PB0 |
| 296 | PB1 |
| 297 | PB2 |
| 298 | PB3 |
| 299 | PB4 DRIVE RDY |
| 300 | PB5 PWR ON AND NO ERRORS |
| 301 | PB6 DACI |
| 302 | PB7 RFDI |
| 303 | |
| 304 | */ |
| 305 | |
| 306 | c9060_t *c9060 = get_safe_token(device->owner); |
| 307 | |
| 308 | UINT8 data = 0; |
| 309 | |
| 310 | /* data accepted in */ |
| 311 | data |= ieee488_ndac_r(c9060->bus) << 6; |
| 312 | |
| 313 | /* ready for data in */ |
| 314 | data |= ieee488_nrfd_r(c9060->bus) << 7; |
| 315 | |
| 316 | return data; |
| 317 | } |
| 318 | |
| 319 | static WRITE8_DEVICE_HANDLER( riot1_pb_w ) |
| 320 | { |
| 321 | /* |
| 322 | |
| 323 | bit description |
| 324 | |
| 325 | PB0 |
| 326 | PB1 |
| 327 | PB2 |
| 328 | PB3 |
| 329 | PB4 DRIVE RDY |
| 330 | PB5 PWR ON AND NO ERRORS |
| 331 | PB6 DACI |
| 332 | PB7 RFDI |
| 333 | |
| 334 | */ |
| 335 | } |
| 336 | |
| 337 | static WRITE_LINE_DEVICE_HANDLER( riot1_irq_w ) |
| 338 | { |
| 339 | c9060_t *c9060 = get_safe_token(device->owner); |
| 340 | |
| 341 | cpu_set_input_line(c9060->cpu_dos, M6502_IRQ_LINE, state); |
| 342 | } |
| 343 | |
| 344 | static const riot6532_interface riot1_intf = |
| 345 | { |
| 346 | DEVCB_HANDLER(riot1_pa_r), |
| 347 | DEVCB_HANDLER(riot1_pb_r), |
| 348 | DEVCB_HANDLER(riot1_pa_w), |
| 349 | DEVCB_HANDLER(riot1_pb_w), |
| 350 | DEVCB_LINE(riot1_irq_w) |
| 351 | }; |
| 352 | |
| 353 | /*------------------------------------------------- |
| 354 | via6522_interface via_intf 4b |
| 355 | -------------------------------------------------*/ |
| 356 | |
| 357 | static READ8_DEVICE_HANDLER( via_pa_r ) |
| 358 | { |
| 359 | /* |
| 360 | |
| 361 | bit description |
| 362 | |
| 363 | PA0 DB0 |
| 364 | PA1 DB1 |
| 365 | PA2 DB2 |
| 366 | PA3 DB3 |
| 367 | PA4 DB4 |
| 368 | PA5 DB5 |
| 369 | PA6 DB6 |
| 370 | PA7 DB7 |
| 371 | |
| 372 | */ |
| 373 | |
| 374 | return 0; |
| 375 | } |
| 376 | |
| 377 | static WRITE8_DEVICE_HANDLER( via_pa_w ) |
| 378 | { |
| 379 | /* |
| 380 | |
| 381 | bit description |
| 382 | |
| 383 | PA0 DB0 |
| 384 | PA1 DB1 |
| 385 | PA2 DB2 |
| 386 | PA3 DB3 |
| 387 | PA4 DB4 |
| 388 | PA5 DB5 |
| 389 | PA6 DB6 |
| 390 | PA7 DB7 |
| 391 | |
| 392 | */ |
| 393 | } |
| 394 | |
| 395 | static READ8_DEVICE_HANDLER( via_pb_r ) |
| 396 | { |
| 397 | /* |
| 398 | |
| 399 | bit description |
| 400 | |
| 401 | PB0 SEL |
| 402 | PB1 RST |
| 403 | PB2 C/D |
| 404 | PB3 BUSY |
| 405 | PB4 J14 |
| 406 | PB5 J14 |
| 407 | PB6 I/O |
| 408 | PB7 MSG |
| 409 | |
| 410 | */ |
| 411 | |
| 412 | return 0; |
| 413 | } |
| 414 | |
| 415 | static WRITE8_DEVICE_HANDLER( via_pb_w ) |
| 416 | { |
| 417 | /* |
| 418 | |
| 419 | bit description |
| 420 | |
| 421 | PB0 SEL |
| 422 | PB1 RST |
| 423 | PB2 C/D |
| 424 | PB3 BUSY |
| 425 | PB4 J14 |
| 426 | PB5 J14 |
| 427 | PB6 I/O |
| 428 | PB7 MSG |
| 429 | |
| 430 | */ |
| 431 | } |
| 432 | |
| 433 | static const via6522_interface via_intf = |
| 434 | { |
| 435 | DEVCB_HANDLER(via_pa_r), |
| 436 | DEVCB_HANDLER(via_pb_r), |
| 437 | DEVCB_NULL, // ACK |
| 438 | DEVCB_NULL, |
| 439 | DEVCB_NULL, // MSG |
| 440 | DEVCB_NULL, // ? |
| 441 | |
| 442 | DEVCB_HANDLER(via_pa_w), |
| 443 | DEVCB_HANDLER(via_pb_w), |
| 444 | DEVCB_NULL, |
| 445 | DEVCB_NULL, |
| 446 | DEVCB_NULL, |
| 447 | DEVCB_NULL, |
| 448 | |
| 449 | DEVCB_NULL |
| 450 | }; |
| 451 | |
| 452 | /*------------------------------------------------- |
| 453 | MACHINE_DRIVER( c9060 ) |
| 454 | -------------------------------------------------*/ |
| 455 | |
| 456 | static MACHINE_DRIVER_START( c9060 ) |
| 457 | /* DOS */ |
| 458 | MDRV_CPU_ADD(M6502_TAG, M6502, XTAL_16MHz/16) |
| 459 | MDRV_CPU_PROGRAM_MAP(c9060_dos_map) |
| 460 | |
| 461 | MDRV_RIOT6532_ADD(M6532_0_TAG, XTAL_16MHz/16, riot0_intf) |
| 462 | MDRV_RIOT6532_ADD(M6532_1_TAG, XTAL_16MHz/16, riot1_intf) |
| 463 | |
| 464 | /* controller */ |
| 465 | MDRV_CPU_ADD(M6504_TAG, M6502, XTAL_16MHz/16) |
| 466 | MDRV_CPU_PROGRAM_MAP(c9060_fdc_map) |
| 467 | |
| 468 | MDRV_VIA6522_ADD(M6522_TAG, XTAL_16MHz/16, via_intf) |
| 469 | |
| 470 | // Tandon TM602S |
| 471 | MACHINE_DRIVER_END |
| 472 | |
| 473 | /*------------------------------------------------- |
| 474 | MACHINE_DRIVER( c9090 ) |
| 475 | -------------------------------------------------*/ |
| 476 | |
| 477 | static MACHINE_DRIVER_START( c9090 ) |
| 478 | MDRV_IMPORT_FROM(c9060) |
| 479 | |
| 480 | // Tandon TM603S |
| 481 | MACHINE_DRIVER_END |
| 482 | |
| 483 | /*------------------------------------------------- |
| 484 | ROM( c9060 ) |
| 485 | -------------------------------------------------*/ |
| 486 | |
| 487 | ROM_START( c9060 ) // schematic 300010 |
| 488 | ROM_REGION( 0x4800, C9060_REGION, ROMREGION_LOADBYNAME ) |
| 489 | ROM_LOAD( "300516-revb.7c", 0x0000, 0x2000, CRC(2d758a14) SHA1(c959cc9dde84fc3d64e95e58a0a096a26d8107fd) ) |
| 490 | ROM_LOAD( "300516-revc.7c", 0x0000, 0x2000, CRC(d6a3e88f) SHA1(bb1ddb5da94a86266012eca54818aa21dc4cef6a) ) |
| 491 | ROM_LOAD( "300517-reva.7d", 0x2000, 0x2000, CRC(566df630) SHA1(b1602dfff408b165ee52a6a4ca3e2ec27e689ba9) ) |
| 492 | ROM_LOAD( "300517-revb.7d", 0x2000, 0x2000, CRC(f0382bc3) SHA1(0b0a8dc520f5b41ffa832e4a636b3d226ccbb7f1) ) |
| 493 | ROM_LOAD( "300517-revc.7d", 0x2000, 0x2000, CRC(2a9ad4ad) SHA1(4c17d014de48c906871b9b6c7d037d8736b1fd52) ) |
| 494 | |
| 495 | ROM_LOAD( "300515-reva.4c", 0x4000, 0x0800, CRC(99e096f7) SHA1(a3d1deb27bf5918b62b89c27fa3e488eb8f717a4) ) |
| 496 | ROM_LOAD( "300515-revb.4c", 0x4000, 0x0800, CRC(49adf4fb) SHA1(59dafbd4855083074ba8dc96a04d4daa5b76e0d6) ) |
| 497 | ROM_END |
| 498 | |
| 499 | /*------------------------------------------------- |
| 500 | DEVICE_START( c9060 ) |
| 501 | -------------------------------------------------*/ |
| 502 | |
| 503 | static DEVICE_START( c9060 ) |
| 504 | { |
| 505 | c9060_t *c9060 = get_safe_token(device); |
| 506 | const c9060_config *config = get_safe_config(device); |
| 507 | |
| 508 | /* find our CPU */ |
| 509 | c9060->cpu_dos = device->subdevice(M6502_TAG); |
| 510 | c9060->cpu_hdc = device->subdevice(M6504_TAG); |
| 511 | |
| 512 | /* find devices */ |
| 513 | c9060->riot0 = device->subdevice(M6532_0_TAG); |
| 514 | c9060->riot1 = device->subdevice(M6532_1_TAG); |
| 515 | c9060->via = device->subdevice(M6522_TAG); |
| 516 | c9060->bus = devtag_get_device(device->machine, config->bus_tag); |
| 517 | |
| 518 | /* register for state saving */ |
| 519 | // state_save_register_device_item(device, 0, c9060->); |
| 520 | } |
| 521 | |
| 522 | /*------------------------------------------------- |
| 523 | DEVICE_RESET( c9060 ) |
| 524 | -------------------------------------------------*/ |
| 525 | |
| 526 | static DEVICE_RESET( c9060 ) |
| 527 | { |
| 528 | c9060_t *c9060 = get_safe_token(device); |
| 529 | |
| 530 | /* reset devices */ |
| 531 | c9060->cpu_dos->reset(); |
| 532 | c9060->cpu_hdc->reset(); |
| 533 | c9060->riot0->reset(); |
| 534 | c9060->riot1->reset(); |
| 535 | c9060->via->reset(); |
| 536 | |
| 537 | /* toggle M6502 SO */ |
| 538 | cpu_set_input_line(c9060->cpu_dos, M6502_SET_OVERFLOW, ASSERT_LINE); |
| 539 | cpu_set_input_line(c9060->cpu_dos, M6502_SET_OVERFLOW, CLEAR_LINE); |
| 540 | } |
| 541 | |
| 542 | /*------------------------------------------------- |
| 543 | DEVICE_GET_INFO( c9060 ) |
| 544 | -------------------------------------------------*/ |
| 545 | |
| 546 | DEVICE_GET_INFO( c9060 ) |
| 547 | { |
| 548 | switch (state) |
| 549 | { |
| 550 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 551 | case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(c9060_t); break; |
| 552 | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(c9060_config); break; |
| 553 | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break; |
| 554 | |
| 555 | /* --- the following bits of info are returned as pointers --- */ |
| 556 | case DEVINFO_PTR_ROM_REGION: info->romregion = ROM_NAME(c9060); break; |
| 557 | case DEVINFO_PTR_MACHINE_CONFIG: info->machine_config = MACHINE_DRIVER_NAME(c9060); break; |
| 558 | |
| 559 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 560 | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(c9060); break; |
| 561 | case DEVINFO_FCT_STOP: /* Nothing */ break; |
| 562 | case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(c9060); break; |
| 563 | |
| 564 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 565 | case DEVINFO_STR_NAME: strcpy(info->s, "Commodore 9060"); break; |
| 566 | case DEVINFO_STR_FAMILY: strcpy(info->s, "Commodore PET"); break; |
| 567 | case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; |
| 568 | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; |
| 569 | case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MESS Team"); break; |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | /*------------------------------------------------- |
| 574 | DEVICE_GET_INFO( c9090 ) |
| 575 | -------------------------------------------------*/ |
| 576 | |
| 577 | DEVICE_GET_INFO( c9090 ) |
| 578 | { |
| 579 | switch (state) |
| 580 | { |
| 581 | /* --- the following bits of info are returned as pointers --- */ |
| 582 | case DEVINFO_PTR_MACHINE_CONFIG: info->machine_config = MACHINE_DRIVER_NAME(c9090); break; |
| 583 | |
| 584 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 585 | case DEVINFO_STR_NAME: strcpy(info->s, "Commodore 9090"); break; |
| 586 | |
| 587 | default: DEVICE_GET_INFO_CALL(c9060); break; |
| 588 | } |
| 589 | } |
src/mess/drivers/vic20.c
| r7571 | r7572 | |
| 1 | | /*
|
| 2 | | |
| 3 | | [CBM systems which belong to this driver (info to be moved to sysinfo.dat soon)]
|
| 4 | | (most of the informations are taken from http://www.zimmers.net/cbmpics/ )
|
| 5 | | |
| 6 | | |
| 7 | | * VIC-1001 (1981, Japan)
|
| 8 | | |
| 9 | | The first model released was the Japanese one. It featured support for the
|
| 10 | | Japanese katakana character.
|
| 11 | | |
| 12 | | CPU: MOS Technology 6502 (1.01 MHz)
|
| 13 | | RAM: 5 kilobytes (Expanded to 21k though an external 16k unit)
|
| 14 | | ROM: 20 kilobytes
|
| 15 | | Video: MOS Technology 6560 "VIC"(Text: 22 columns, 23 rows; Hires: 176x184
|
| 16 | | pixels bitmapped; 8 text colors, 16 background colors)
|
| 17 | | Sound: MOS Technology 6560 "VIC" (3 voices -square wave-, noise and volume)
|
| 18 | | Ports: 6522 VIA x2 (1 Joystick/Mouse port; CBM Serial port; 'Cartridge /
|
| 19 | | Game / Expansion' port; CBM Monitor port; CBM 'USER' port; Power and
|
| 20 | | reset switches; Power connector)
|
| 21 | | Keyboard: Full-sized QWERTY 66 key (8 programmable function keys; 2 sets of
|
| 22 | | Keyboardable graphic characters; 2 key direction cursor-pad)
|
| 23 | | |
| 24 | | |
| 25 | | * VIC 20 (1981)
|
| 26 | | |
| 27 | | This system was the first computer to sell more than one million units
|
| 28 | | worldwide. It was sold both in Europe and in the US. In Germany the
|
| 29 | | computer was renamed as VC 20 (apparently, it stands for 'VolksComputer'
|
| 30 | | |
| 31 | | CPU: MOS Technology 6502A (1.01 MHz)
|
| 32 | | RAM: 5 kilobytes (Expanded to 32k)
|
| 33 | | ROM: 20 kilobytes
|
| 34 | | Video: MOS Technology 6560 "VIC"(Text: 22 columns, 23 rows; Hires: 176x184
|
| 35 | | pixels bitmapped; 8 text colors, 16 background colors)
|
| 36 | | Sound: MOS Technology 6560 "VIC" (3 voices -square wave-, noise and volume)
|
| 37 | | Ports: 6522 VIA x2 (1 Joystick/Mouse port; CBM Serial port; 'Cartridge /
|
| 38 | | Game / Expansion' port; CBM Monitor port; CBM 'USER' port; Power and
|
| 39 | | reset switches; Power connector)
|
| 40 | | Keyboard: Full-sized QWERTY 66 key (8 programmable function keys; 2 sets of
|
| 41 | | Keyboardable graphic characters; 2 key direction cursor-pad)
|
| 42 | | |
| 43 | | |
| 44 | | * VIC 21 (1983)
|
| 45 | | |
| 46 | | It consists of a VIC 20 with built-in RAM expansion, to reach a RAM
|
| 47 | | capability of 21 kilobytes.
|
| 48 | | |
| 49 | | |
| 50 | | * VIC 20CR
|
| 51 | | |
| 52 | | CR stands for Cost Reduced, as it consisted of a board with only 2 (larger)
|
| 53 | | block of RAM instead of 8.
|
| 54 | | |
| 55 | | *******************************************************************************
|
| 56 | | |
| 57 | | TODO:
|
| 58 | | |
| 59 | | - C1540 is unreliable (VIA timing issues?)
|
| 60 | | - clean up inputs
|
| 61 | | - clean up VIA interface
|
| 62 | | - access violation in mos6560.c
|
| 63 | | * In the Chips (Japan, USA).60
|
| 64 | | * K-Star Patrol (Europe).60
|
| 65 | | * Seafox (Japan, USA).60
|
| 66 | | - SHIFT LOCK
|
| 67 | | - restore key
|
| 68 | | - light pen
|
| 69 | | - VIC21 (built in 21K ram)
|
| 70 | | - new cart system (rpk)
|
| 71 | | |
| 72 | | */
|
| 73 | | |
| 74 | | #include "emu.h"
|
| 75 | | #include "includes/vic20.h"
|
| 76 | | #include "includes/cbm.h"
|
| 77 | | #include "cpu/m6502/m6502.h"
|
| 78 | | #include "devices/cartslot.h"
|
| 79 | | #include "devices/messram.h"
|
| 80 | | #include "machine/6522via.h"
|
| 81 | | #include "machine/c1541.h"
|
| 82 | | #include "machine/cbmiec.h"
|
| 83 | | #include "machine/ieee488.h"
|
| 84 | | #include "machine/vic1112.h"
|
| 85 | | #include "machine/cbmipt.h"
|
| 86 | | #include "sound/mos6560.h"
|
| 87 | | #include "sound/dac.h"
|
| 88 | | |
| 89 | | /* Memory Maps */
|
| 90 | | |
| 91 | | static ADDRESS_MAP_START( vic20_mem, ADDRESS_SPACE_PROGRAM, 8 )
|
| 92 | | AM_RANGE(0x0000, 0x03ff) AM_RAM
|
| 93 | | // AM_RANGE(0x0400, 0x07ff) RAM1
|
| 94 | | // AM_RANGE(0x0800, 0x0bff) RAM2
|
| 95 | | // AM_RANGE(0x0c00, 0x0fff) RAM3
|
| 96 | | AM_RANGE(0x1000, 0x1fff) AM_RAM
|
| 97 | | // AM_RANGE(0x2000, 0x3fff) BLK1
|
| 98 | | // AM_RANGE(0x4000, 0x5fff) BLK2
|
| 99 | | // AM_RANGE(0x6000, 0x7fff) BLK3
|
| 100 | | AM_RANGE(0x8000, 0x8fff) AM_ROM
|
| 101 | | AM_RANGE(0x9000, 0x900f) AM_DEVREADWRITE(M6560_TAG, mos6560_port_r, mos6560_port_w)
|
| 102 | | AM_RANGE(0x9110, 0x911f) AM_DEVREADWRITE(M6522_0_TAG, via_r, via_w)
|
| 103 | | AM_RANGE(0x9120, 0x912f) AM_DEVREADWRITE(M6522_1_TAG, via_r, via_w)
|
| 104 | | AM_RANGE(0x9400, 0x97ff) AM_RAM
|
| 105 | | // AM_RANGE(0x9800, 0x9bff) I/O2
|
| 106 | | // AM_RANGE(0x9c00, 0x9fff) I/O3
|
| 107 | | // AM_RANGE(0xa000, 0xbfff) BLK5
|
| 108 | | AM_RANGE(0xc000, 0xffff) AM_ROM
|
| 109 | | ADDRESS_MAP_END
|
| 110 | | |
| 111 | | /* Input Ports */
|
| 112 | | |
| 113 | | #ifdef UNUSED_FUNCTION
|
| 114 | | static INPUT_PORTS_START( vic_lightpen_6560 )
|
| 115 | | PORT_START( "LIGHTX" )
|
| 116 | | PORT_BIT( 0xff, 0, IPT_PADDLE ) PORT_NAME("Lightpen X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(2) PORT_MINMAX(0,(MOS6560_MAME_XSIZE - 1)) PORT_CATEGORY(12) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH)
|
| 117 | | |
| 118 | | PORT_START( "LIGHTY" )
|
| 119 | | PORT_BIT( 0xff, 0, IPT_PADDLE ) PORT_NAME("Lightpen Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(2) PORT_MINMAX(0,(MOS6560_MAME_YSIZE - 1)) PORT_CATEGORY(12) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH)
|
| 120 | | INPUT_PORTS_END
|
| 121 | | |
| 122 | | |
| 123 | | static INPUT_PORTS_START( vic_lightpen_6561 )
|
| 124 | | PORT_START( "LIGHTX" )
|
| 125 | | PORT_BIT( 0xff, 0, IPT_PADDLE ) PORT_NAME("Lightpen X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(2) PORT_MINMAX(0,(MOS6560_MAME_XSIZE - 1)) PORT_CATEGORY(12) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH)
|
| 126 | | |
| 127 | | PORT_START( "LIGHTY" )
|
| 128 | | PORT_BIT( 0x1ff, 0, IPT_PADDLE ) PORT_NAME("Lightpen Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(2) PORT_MINMAX(0,(MOS6561_MAME_YSIZE - 1)) PORT_CATEGORY(12) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH)
|
| 129 | | INPUT_PORTS_END
|
| 130 | | #endif
|
| 131 | | |
| 132 | | static INPUT_PORTS_START( vic20 )
|
| 133 | | PORT_INCLUDE( vic_keyboard ) /* ROW0 -> ROW7 */
|
| 134 | | |
| 135 | | PORT_INCLUDE( vic_special ) /* SPECIAL */
|
| 136 | | |
| 137 | | PORT_INCLUDE( vic_controls ) /* CTRLSEL, JOY, FAKE0, FAKE1, PADDLE0, PADDLE1 */
|
| 138 | | INPUT_PORTS_END
|
| 139 | | |
| 140 | | |
| 141 | | static INPUT_PORTS_START( vic1001 )
|
| 142 | | PORT_INCLUDE( vic20 )
|
| 143 | | |
| 144 | | PORT_MODIFY( "ROW0" )
|
| 145 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('\xA5')
|
| 146 | | INPUT_PORTS_END
|
| 147 | | |
| 148 | | |
| 149 | | static INPUT_PORTS_START( vic20s )
|
| 150 | | PORT_INCLUDE( vic20 )
|
| 151 | | |
| 152 | | PORT_MODIFY( "ROW0" )
|
| 153 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(':') PORT_CHAR('*')
|
| 154 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
|
| 155 | | PORT_MODIFY( "ROW1" )
|
| 156 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('@')
|
| 157 | | PORT_MODIFY( "ROW2" )
|
| 158 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(0x00C4)
|
| 159 | | PORT_MODIFY( "ROW5" )
|
| 160 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(';') PORT_CHAR('+')
|
| 161 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(0x00D6)
|
| 162 | | PORT_MODIFY( "ROW6" )
|
| 163 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(0x00C5)
|
| 164 | | PORT_MODIFY( "ROW7" )
|
| 165 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=')
|
| 166 | | INPUT_PORTS_END
|
| 167 | | |
| 168 | | /* VIA 0 Interface */
|
| 169 | | |
| 170 | | static READ8_DEVICE_HANDLER( via0_pa_r )
|
| 171 | | {
|
| 172 | | /*
|
| 173 | | |
| 174 | | bit description
|
| 175 | | |
| 176 | | PA0 SERIAL CLK IN
|
| 177 | | PA1 SERIAL DATA IN
|
| 178 | | PA2 JOY 0
|
| 179 | | PA3 JOY 1
|
| 180 | | PA4 JOY 2
|
| 181 | | PA5 LITE PEN
|
| 182 | | PA6 CASS SWITCH
|
| 183 | | PA7 SERIAL ATN OUT
|
| 184 | | |
| 185 | | */
|
| 186 | | |
| 187 | | vic20_state *state = (vic20_state *)device->machine->driver_data;
|
| 188 | | UINT8 data = 0xfc;
|
| 189 | | |
| 190 | | /* serial clock in */
|
| 191 | | data |= cbm_iec_clk_r(state->iec);
|
| 192 | | |
| 193 | | /* serial data in */
|
| 194 | | data |= cbm_iec_data_r(state->iec) << 1;
|
| 195 | | |
| 196 | | /* joystick */
|
| 197 | | data &= ~(input_port_read(device->machine, "JOY") & 0x3c);
|
| 198 | | |
| 199 | | /* cassette switch */
|
| 200 | | if ((cassette_get_state(state->cassette) & CASSETTE_MASK_UISTATE) != CASSETTE_STOPPED)
|
| 201 | | data &= ~0x40;
|
| 202 | | else
|
| 203 | | data |= 0x40;
|
| 204 | | |
| 205 | | return data;
|
| 206 | | }
|
| 207 | | |
| 208 | | static WRITE8_DEVICE_HANDLER( via0_pa_w )
|
| 209 | | {
|
| 210 | | /*
|
| 211 | | |
| 212 | | bit description
|
| 213 | | |
| 214 | | PA0 SERIAL CLK IN
|
| 215 | | PA1 SERIAL DATA IN
|
| 216 | | PA2 JOY 0
|
| 217 | | PA3 JOY 1
|
| 218 | | PA4 JOY 2
|
| 219 | | PA5 LITE PEN
|
| 220 | | PA6 CASS SWITCH
|
| 221 | | PA7 SERIAL ATN OUT
|
| 222 | | |
| 223 | | */
|
| 224 | | |
| 225 | | vic20_state *state = (vic20_state *)device->machine->driver_data;
|
| 226 | | |
| 227 | | /* serial attention out */
|
| 228 | | cbm_iec_atn_w(state->iec, device, !BIT(data, 7));
|
| 229 | | }
|
| 230 | | |
| 231 | | static READ8_DEVICE_HANDLER( via0_pb_r )
|
| 232 | | {
|
| 233 | | /*
|
| 234 | | |
| 235 | | bit description
|
| 236 | | |
| 237 | | PB0 USER PORT C
|
| 238 | | PB1 USER PORT D
|
| 239 | | PB2 USER PORT E
|
| 240 | | PB3 USER PORT F
|
| 241 | | PB4 USER PORT H
|
| 242 | | PB5 USER PORT J
|
| 243 | | PB6 USER PORT K
|
| 244 | | PB7 USER PORT L
|
| 245 | | |
| 246 | | */
|
| 247 | | |
| 248 | | return 0;
|
| 249 | | }
|
| 250 | | |
| 251 | | static WRITE8_DEVICE_HANDLER( via0_pb_w )
|
| 252 | | {
|
| 253 | | /*
|
| 254 | | |
| 255 | | bit description
|
| 256 | | |
| 257 | | PB0 USER PORT C
|
| 258 | | PB1 USER PORT D
|
| 259 | | PB2 USER PORT E
|
| 260 | | PB3 USER PORT F
|
| 261 | | PB4 USER PORT H
|
| 262 | | PB5 USER PORT J
|
| 263 | | PB6 USER PORT K
|
| 264 | | PB7 USER PORT L
|
| 265 | | |
| 266 | | */
|
| 267 | | }
|
| 268 | | |
| 269 | | static WRITE8_DEVICE_HANDLER( via0_ca2_w )
|
| 270 | | {
|
| 271 | | vic20_state *state = (vic20_state *)device->machine->driver_data;
|
| 272 | | |
| 273 | | if (!BIT(data, 0))
|
| 274 | | {
|
| 275 | | cassette_change_state(state->cassette, CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
|
| 276 | | timer_device_adjust_periodic(state->cassette_timer, attotime_zero, 0, ATTOTIME_IN_HZ(44100));
|
| 277 | | }
|
| 278 | | else
|
| 279 | | {
|
| 280 | | cassette_change_state(state->cassette, CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
|
| 281 | | timer_device_reset(state->cassette_timer);
|
| 282 | | }
|
| 283 | | }
|
| 284 | | |
| 285 | | static const via6522_interface vic20_via0_intf =
|
| 286 | | {
|
| 287 | | DEVCB_HANDLER(via0_pa_r),
|
| 288 | | DEVCB_HANDLER(via0_pb_r),
|
| 289 | | DEVCB_NULL, // RESTORE
|
| 290 | | DEVCB_NULL,
|
| 291 | | DEVCB_NULL,
|
| 292 | | DEVCB_NULL,
|
| 293 | | DEVCB_HANDLER(via0_pa_w),
|
| 294 | | DEVCB_HANDLER(via0_pb_w),
|
| 295 | | DEVCB_NULL,
|
| 296 | | DEVCB_NULL,
|
| 297 | | DEVCB_HANDLER(via0_ca2_w), // CASS MOTOR
|
| 298 | | DEVCB_NULL,
|
| 299 | | DEVCB_CPU_INPUT_LINE(M6502_TAG, INPUT_LINE_NMI)
|
| 300 | | };
|
| 301 | | |
| 302 | | /* VIA 1 Interface */
|
| 303 | | |
| 304 | | static READ8_DEVICE_HANDLER( via1_pa_r )
|
| 305 | | {
|
| 306 | | /*
|
| 307 | | |
| 308 | | bit description
|
| 309 | | |
| 310 | | PA0 ROW 0
|
| 311 | | PA1 ROW 1
|
| 312 | | PA2 ROW 2
|
| 313 | | PA3 ROW 3
|
| 314 | | PA4 ROW 4
|
| 315 | | PA5 ROW 5
|
| 316 | | PA6 ROW 6
|
| 317 | | PA7 ROW 7
|
| 318 | | |
| 319 | | */
|
| 320 | | |
| 321 | | vic20_state *state = (vic20_state *)device->machine->driver_data;
|
| 322 | | UINT8 data = 0xff;
|
| 323 | | |
| 324 | | if (!BIT(state->key_col, 0)) data &= input_port_read(device->machine, "ROW0");
|
| 325 | | if (!BIT(state->key_col, 1)) data &= input_port_read(device->machine, "ROW1");
|
| 326 | | if (!BIT(state->key_col, 2)) data &= input_port_read(device->machine, "ROW2");
|
| 327 | | if (!BIT(state->key_col, 3)) data &= input_port_read(device->machine, "ROW3");
|
| 328 | | if (!BIT(state->key_col, 4)) data &= input_port_read(device->machine, "ROW4");
|
| 329 | | if (!BIT(state->key_col, 5)) data &= input_port_read(device->machine, "ROW5");
|
| 330 | | if (!BIT(state->key_col, 6)) data &= input_port_read(device->machine, "ROW6");
|
| 331 | | if (!BIT(state->key_col, 7)) data &= input_port_read(device->machine, "ROW7");
|
| 332 | | |
| 333 | | return data;
|
| 334 | | }
|
| 335 | | |
| 336 | | static READ8_DEVICE_HANDLER( via1_pb_r )
|
| 337 | | {
|
| 338 | | /*
|
| 339 | | |
| 340 | | bit description
|
| 341 | | |
| 342 | | PB0 COL 0
|
| 343 | | PB1 COL 1
|
| 344 | | PB2 COL 2
|
| 345 | | PB3 COL 3, CASS WRITE
|
| 346 | | PB4 COL 4
|
| 347 | | PB5 COL 5
|
| 348 | | PB6 COL 6
|
| 349 | | PB7 COL 7, JOY 3
|
| 350 | | |
| 351 | | */
|
| 352 | | |
| 353 | | UINT8 data = 0xff;
|
| 354 | | |
| 355 | | /* joystick */
|
| 356 | | data &= ~(input_port_read(device->machine, "JOY") & 0x80);
|
| 357 | | |
| 358 | | return data;
|
| 359 | | }
|
| 360 | | |
| 361 | | static WRITE8_DEVICE_HANDLER( via1_pb_w )
|
| 362 | | {
|
| 363 | | /*
|
| 364 | | |
| 365 | | bit description
|
| 366 | | |
| 367 | | PB0 COL 0
|
| 368 | | PB1 COL 1
|
| 369 | | PB2 COL 2
|
| 370 | | PB3 COL 3, CASS WRITE
|
| 371 | | PB4 COL 4
|
| 372 | | PB5 COL 5
|
| 373 | | PB6 COL 6
|
| 374 | | PB7 COL 7, JOY 3
|
| 375 | | |
| 376 | | */
|
| 377 | | |
| 378 | | vic20_state *state = (vic20_state *)device->machine->driver_data;
|
| 379 | | |
| 380 | | /* cassette write */
|
| 381 | | cassette_output(devtag_get_device(device->machine, "cassette"), BIT(data, 3) ? -(0x5a9e >> 1) : +(0x5a9e >> 1));
|
| 382 | | |
| 383 | | /* keyboard column */
|
| 384 | | state->key_col = data;
|
| 385 | | }
|
| 386 | | |
| 387 | | static WRITE_LINE_DEVICE_HANDLER( via1_ca2_w )
|
| 388 | | {
|
| 389 | | vic20_state *driver_state = (vic20_state *)device->machine->driver_data;
|
| 390 | | |
| 391 | | /* serial clock out */
|
| 392 | | cbm_iec_clk_w(driver_state->iec, device, !state);
|
| 393 | | }
|
| 394 | | |
| 395 | | static WRITE_LINE_DEVICE_HANDLER( via1_cb2_w )
|
| 396 | | {
|
| 397 | | vic20_state *driver_state = (vic20_state *)device->machine->driver_data;
|
| 398 | | |
| 399 | | /* serial data out */
|
| 400 | | cbm_iec_data_w(driver_state->iec, device, !state);
|
| 401 | | }
|
| 402 | | |
| 403 | | static const via6522_interface vic20_via1_intf =
|
| 404 | | {
|
| 405 | | DEVCB_HANDLER(via1_pa_r),
|
| 406 | | DEVCB_HANDLER(via1_pb_r),
|
| 407 | | DEVCB_NULL, /* CASS READ */
|
| 408 | | DEVCB_NULL,
|
| 409 | | DEVCB_NULL,
|
| 410 | | DEVCB_NULL,
|
| 411 | | |
| 412 | | DEVCB_NULL,
|
| 413 | | DEVCB_HANDLER(via1_pb_w),
|
| 414 | | DEVCB_NULL,
|
| 415 | | DEVCB_NULL,
|
| 416 | | DEVCB_LINE(via1_ca2_w),
|
| 417 | | DEVCB_LINE(via1_cb2_w),
|
| 418 | | |
| 419 | | DEVCB_CPU_INPUT_LINE(M6502_TAG, M6502_IRQ_LINE)
|
| 420 | | };
|
| 421 | | |
| 422 | | /* Cassette Interface */
|
| 423 | | |
| 424 | | static TIMER_DEVICE_CALLBACK( cassette_tick )
|
| 425 | | {
|
| 426 | | vic20_state *state = (vic20_state *)timer->machine->driver_data;
|
| 427 | | int data = (cassette_input(state->cassette) > +0.0) ? 1 : 0;
|
| 428 | | |
| 429 | | via_ca1_w(state->via1, data);
|
| 430 | | }
|
| 431 | | |
| 432 | | /* IEC Serial Bus */
|
| 433 | | |
| 434 | | static CBM_IEC_DAISY( cbm_iec_daisy )
|
| 435 | | {
|
| 436 | | { M6522_0_TAG },
|
| 437 | | { M6522_1_TAG, DEVCB_DEVICE_LINE(M6522_1_TAG, via_cb1_w) },
|
| 438 | | { C1541_IEC(C1540_TAG) },
|
| 439 | | { NULL}
|
| 440 | | };
|
| 441 | | |
| 442 | | /* IEEE-488 Bus */
|
| 443 | | |
| 444 | | static IEEE488_DAISY( ieee488_daisy )
|
| 445 | | {
|
| 446 | | { VIC1112_IEEE488 },
|
| 447 | | { C2031_IEEE488(C2031_TAG) },
|
| 448 | | { NULL}
|
| 449 | | };
|
| 450 | | |
| 451 | | /* MOS6560 Interface */
|
| 452 | | |
| 453 | | #define VC20ADDR2MOS6560ADDR(a) (((a) > 0x8000) ? ((a) & 0x1fff) : ((a) | 0x2000))
|
| 454 | | #define MOS6560ADDR2VC20ADDR(a) (((a) > 0x2000) ? ((a) & 0x1fff) : ((a) | 0x8000))
|
| 455 | | |
| 456 | | static int vic20_dma_read_color( running_machine *machine, int offset )
|
| 457 | | {
|
| 458 | | const address_space *program = cputag_get_address_space(machine, M6502_TAG, ADDRESS_SPACE_PROGRAM);
|
| 459 | | |
| 460 | | return memory_read_byte(program, 0x9400 | (offset & 0x3ff));
|
| 461 | | }
|
| 462 | | |
| 463 | | static int vic20_dma_read( running_machine *machine, int offset )
|
| 464 | | {
|
| 465 | | const address_space *program = cputag_get_address_space(machine, M6502_TAG, ADDRESS_SPACE_PROGRAM);
|
| 466 | | |
| 467 | | return memory_read_byte(program, MOS6560ADDR2VC20ADDR(offset));
|
| 468 | | }
|
| 469 | | |
| 470 | | static UINT8 vic20_lightx_cb( running_machine *machine )
|
| 471 | | {
|
| 472 | | return (input_port_read_safe(machine, "LIGHTX", 0) & ~0x01);
|
| 473 | | }
|
| 474 | | |
| 475 | | static UINT8 vic20_lighty_cb( running_machine *machine )
|
| 476 | | {
|
| 477 | | return (input_port_read_safe(machine, "LIGHTY", 0) & ~0x01);
|
| 478 | | }
|
| 479 | | |
| 480 | | static UINT8 vic20_lightbut_cb( running_machine *machine )
|
| 481 | | {
|
| 482 | | return (((input_port_read(machine, "CTRLSEL") & 0xf0) == 0x20) && (input_port_read(machine, "JOY") & 0x40));
|
| 483 | | }
|
| 484 | | |
| 485 | | static UINT8 vic20_paddle0_cb( running_machine *machine )
|
| 486 | | {
|
| 487 | | return input_port_read(machine, "PADDLE0");
|
| 488 | | }
|
| 489 | | |
| 490 | | static UINT8 vic20_paddle1_cb( running_machine *machine )
|
| 491 | | {
|
| 492 | | return input_port_read(machine, "PADDLE1");
|
| 493 | | }
|
| 494 | | |
| 495 | | static const mos6560_interface vic20_6560_intf =
|
| 496 | | {
|
| 497 | | "screen", /* screen */
|
| 498 | | MOS6560,
|
| 499 | | vic20_lightx_cb, vic20_lighty_cb, vic20_lightbut_cb, /* lightgun cb */
|
| 500 | | vic20_paddle0_cb, vic20_paddle1_cb, /* paddle cb */
|
| 501 | | vic20_dma_read, vic20_dma_read_color /* DMA */
|
| 502 | | };
|
| 503 | | |
| 504 | | static const mos6560_interface vic20_6561_intf =
|
| 505 | | {
|
| 506 | | "screen", /* screen */
|
| 507 | | MOS6561,
|
| 508 | | vic20_lightx_cb, vic20_lighty_cb, vic20_lightbut_cb, /* lightgun cb */
|
| 509 | | vic20_paddle0_cb, vic20_paddle1_cb, /* paddle cb */
|
| 510 | | vic20_dma_read, vic20_dma_read_color /* DMA */
|
| 511 | | };
|
| 512 | | |
| 513 | | |
| 514 | | /* Machine Initialization */
|
| 515 | | |
| 516 | | static MACHINE_START( vic20 )
|
| 517 | | {
|
| 518 | | vic20_state *state = (vic20_state *)machine->driver_data;
|
| 519 | | const address_space *program = cputag_get_address_space(machine, M6502_TAG, ADDRESS_SPACE_PROGRAM);
|
| 520 | | |
| 521 | | /* find devices */
|
| 522 | | state->via0 = devtag_get_device(machine, M6522_0_TAG);
|
| 523 | | state->via1 = devtag_get_device(machine, M6522_1_TAG);
|
| 524 | | state->iec = devtag_get_device(machine, IEC_TAG);
|
| 525 | | state->cassette = devtag_get_device(machine, CASSETTE_TAG);
|
| 526 | | state->cassette_timer = devtag_get_device(machine, TIMER_C1530_TAG);
|
| 527 | | state->mos6560 = devtag_get_device(machine, M6560_TAG);
|
| 528 | | |
| 529 | | /* set VIA clocks */
|
| 530 | | state->via0->set_clock(cputag_get_clock(machine, M6502_TAG));
|
| 531 | | state->via1->set_clock(cputag_get_clock(machine, M6502_TAG));
|
| 532 | | |
| 533 | | /* memory expansions */
|
| 534 | | switch (messram_get_size(devtag_get_device(machine, "messram")))
|
| 535 | | {
|
| 536 | | case 32*1024:
|
| 537 | | memory_install_ram(program, 0x6000, 0x7fff, 0, 0, NULL);
|
| 538 | | /* fallthru */
|
| 539 | | case 24*1024:
|
| 540 | | memory_install_ram(program, 0x4000, 0x5fff, 0, 0, NULL);
|
| 541 | | /* fallthru */
|
| 542 | | case 16*1024:
|
| 543 | | memory_install_ram(program, 0x2000, 0x3fff, 0, 0, NULL);
|
| 544 | | /* fallthru */
|
| 545 | | case 8*1024:
|
| 546 | | memory_install_ram(program, 0x0400, 0x0fff, 0, 0, NULL);
|
| 547 | | }
|
| 548 | | |
| 549 | | /* register for state saving */
|
| 550 | | state_save_register_global(machine, state->key_col);
|
| 551 | | }
|
| 552 | | |
| 553 | | |
| 554 | | /* Cartridge */
|
| 555 | | |
| 556 | | static DEVICE_IMAGE_LOAD( vic20_cart )
|
| 557 | | {
|
| 558 | | const address_space *program = cputag_get_address_space(image->machine, M6502_TAG, ADDRESS_SPACE_PROGRAM);
|
| 559 | | const char *filetype = image_filetype(image);
|
| 560 | | int address = 0;
|
| 561 | | int size = image_length(image);
|
| 562 | | UINT8 *ptr;
|
| 563 | | |
| 564 | | if (!mame_stricmp(filetype, "20"))
|
| 565 | | address = 0x2000;
|
| 566 | | else if (!mame_stricmp(filetype, "40"))
|
| 567 | | address = 0x4000;
|
| 568 | | else if (!mame_stricmp(filetype, "60"))
|
| 569 | | address = 0x6000;
|
| 570 | | else if (!mame_stricmp(filetype, "70"))
|
| 571 | | address = 0x7000;
|
| 572 | | else if (!mame_stricmp(filetype, "a0"))
|
| 573 | | address = 0xa000;
|
| 574 | | else if (!mame_stricmp(filetype, "b0"))
|
| 575 | | address = 0xb000;
|
| 576 | | |
| 577 | | ptr = memory_region(image->machine, M6502_TAG);
|
| 578 | | |
| 579 | | if (size == 0x4000 && address != 0x4000)
|
| 580 | | {
|
| 581 | | image_fread(image, ptr + address, 0x2000);
|
| 582 | | image_fread(image, ptr + 0xa000, 0x2000);
|
| 583 | | |
| 584 | | memory_install_rom(program, address, address + 0x1fff, 0, 0, ptr + address);
|
| 585 | | memory_install_rom(program, 0xa000, 0xbfff, 0, 0, ptr + 0xa000);
|
| 586 | | }
|
| 587 | | else
|
| 588 | | {
|
| 589 | | image_fread(image, ptr + address, size);
|
| 590 | | |
| 591 | | memory_install_rom(program, address, (address + size) - 1, 0, 0, ptr + address);
|
| 592 | | }
|
| 593 | | |
| 594 | | return INIT_PASS;
|
| 595 | | }
|
| 596 | | |
| 597 | | /* Graphics Definitions and Video Emulation */
|
| 598 | | |
| 599 | | static const unsigned char mos6560_palette[] =
|
| 600 | | {
|
| 601 | | /* ripped from vice, a very excellent emulator */
|
| 602 | | /* black, white, red, cyan */
|
| 603 | | 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0xf0,
|
| 604 | | /* purple, green, blue, yellow */
|
| 605 | | 0x60, 0x00, 0x60, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xf0, 0xd0, 0xd0, 0x00,
|
| 606 | | /* orange, light orange, pink, light cyan, */
|
| 607 | | 0xc0, 0xa0, 0x00, 0xff, 0xa0, 0x00, 0xf0, 0x80, 0x80, 0x00, 0xff, 0xff,
|
| 608 | | /* light violett, light green, light blue, light yellow */
|
| 609 | | 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xa0, 0xff, 0xff, 0xff, 0x00
|
| 610 | | };
|
| 611 | | |
| 612 | | static PALETTE_INIT( vic20 )
|
| 613 | | {
|
| 614 | | int i;
|
| 615 | | |
| 616 | | for (i = 0; i < sizeof(mos6560_palette) / 3; i++)
|
| 617 | | {
|
| 618 | | palette_set_color_rgb(machine, i, mos6560_palette[i * 3], mos6560_palette[i * 3 + 1], mos6560_palette[i * 3 + 2]);
|
| 619 | | }
|
| 620 | | }
|
| 621 | | |
| 622 | | static VIDEO_UPDATE( vic20 )
|
| 623 | | {
|
| 624 | | vic20_state *state = (vic20_state *)screen->machine->driver_data;
|
| 625 | | mos6560_video_update(state->mos6560, bitmap, cliprect);
|
| 626 | | return 0;
|
| 627 | | }
|
| 628 | | |
| 629 | | /* Machine Driver */
|
| 630 | | |
| 631 | | static INTERRUPT_GEN( vic20_raster_interrupt )
|
| 632 | | {
|
| 633 | | vic20_state *state = (vic20_state *)device->machine->driver_data;
|
| 634 | | mos6560_raster_interrupt_gen(state->mos6560);
|
| 635 | | }
|
| 636 | | |
| 637 | | static MACHINE_DRIVER_START( vic20_common )
|
| 638 | | MDRV_DRIVER_DATA(vic20_state)
|
| 639 | | |
| 640 | | MDRV_TIMER_ADD_PERIODIC(TIMER_C1530_TAG, cassette_tick, HZ(44100))
|
| 641 | | |
| 642 | | /* devices */
|
| 643 | | MDRV_VIA6522_ADD(M6522_0_TAG, 0, vic20_via0_intf)
|
| 644 | | MDRV_VIA6522_ADD(M6522_1_TAG, 0, vic20_via1_intf)
|
| 645 | | |
| 646 | | MDRV_QUICKLOAD_ADD("quickload", cbm_vc20, "p00,prg", 0)
|
| 647 | | MDRV_CASSETTE_ADD(CASSETTE_TAG, cbm_cassette_config )
|
| 648 | | MDRV_CBM_IEC_ADD(IEC_TAG, cbm_iec_daisy)
|
| 649 | | MDRV_C1540_ADD(C1540_TAG, IEC_TAG, 8)
|
| 650 | | /*
|
| 651 | | MDRV_IEEE488_ADD(IEEE488_TAG, ieee488_daisy)
|
| 652 | | MDRV_VIC1112_ADD(IEEE488_TAG)
|
| 653 | | MDRV_C2031_ADD(C2031_TAG, IEEE488_TAG, 9)
|
| 654 | | */
|
| 655 | | MDRV_CARTSLOT_ADD("cart")
|
| 656 | | MDRV_CARTSLOT_EXTENSION_LIST("20,40,60,70,a0,b0")
|
| 657 | | MDRV_CARTSLOT_NOT_MANDATORY
|
| 658 | | MDRV_CARTSLOT_LOAD(vic20_cart)
|
| 659 | | |
| 660 | | /* internal ram */
|
| 661 | | MDRV_RAM_ADD("messram")
|
| 662 | | MDRV_RAM_DEFAULT_SIZE("5K")
|
| 663 | | MDRV_RAM_EXTRA_OPTIONS("8K,16K,24K,32K")
|
| 664 | | MACHINE_DRIVER_END
|
| 665 | | |
| 666 | | static MACHINE_DRIVER_START( vic20_ntsc )
|
| 667 | | MDRV_IMPORT_FROM( vic20_common )
|
| 668 | | |
| 669 | | /* basic machine hardware */
|
| 670 | | MDRV_CPU_ADD(M6502_TAG, M6502, MOS6560_CLOCK)
|
| 671 | | MDRV_CPU_PROGRAM_MAP(vic20_mem)
|
| 672 | | MDRV_CPU_PERIODIC_INT(vic20_raster_interrupt, MOS656X_HRETRACERATE)
|
| 673 | | |
| 674 | | MDRV_MACHINE_START(vic20)
|
| 675 | | |
| 676 | | /* video hardware */
|
| 677 | | MDRV_SCREEN_ADD("screen", RASTER)
|
| 678 | | MDRV_SCREEN_REFRESH_RATE(MOS6560_VRETRACERATE)
|
| 679 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
| 680 | | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
| 681 | | MDRV_SCREEN_SIZE((MOS6560_XSIZE + 7) & ~7, MOS6560_YSIZE)
|
| 682 | | MDRV_SCREEN_VISIBLE_AREA(MOS6560_MAME_XPOS, MOS6560_MAME_XPOS + MOS6560_MAME_XSIZE - 1, MOS6560_MAME_YPOS, MOS6560_MAME_YPOS + MOS6560_MAME_YSIZE - 1)
|
| 683 | | |
| 684 | | MDRV_PALETTE_LENGTH(16)
|
| 685 | | MDRV_PALETTE_INIT( vic20 )
|
| 686 | | |
| 687 | | MDRV_VIDEO_UPDATE( vic20 )
|
| 688 | | |
| 689 | | /* sound hardware */
|
| 690 | | MDRV_SPEAKER_STANDARD_MONO("mono")
|
| 691 | | MDRV_MOS656X_ADD(M6560_TAG, vic20_6560_intf)
|
| 692 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
| 693 | | MDRV_SOUND_ADD("dac", DAC, 0)
|
| 694 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
| 695 | | MACHINE_DRIVER_END
|
| 696 | | |
| 697 | | static MACHINE_DRIVER_START( vic20_pal )
|
| 698 | | MDRV_IMPORT_FROM( vic20_common )
|
| 699 | | |
| 700 | | /* basic machine hardware */
|
| 701 | | MDRV_CPU_ADD(M6502_TAG, M6502, MOS6561_CLOCK)
|
| 702 | | MDRV_CPU_PROGRAM_MAP(vic20_mem)
|
| 703 | | MDRV_CPU_PERIODIC_INT(vic20_raster_interrupt, MOS656X_HRETRACERATE)
|
| 704 | | |
| 705 | | MDRV_MACHINE_START(vic20)
|
| 706 | | |
| 707 | | /* video hardware */
|
| 708 | | MDRV_SCREEN_ADD("screen", RASTER)
|
| 709 | | MDRV_SCREEN_REFRESH_RATE(MOS6561_VRETRACERATE)
|
| 710 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
| 711 | | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
| 712 | | MDRV_SCREEN_SIZE((MOS6561_XSIZE + 7) & ~7, MOS6561_YSIZE)
|
| 713 | | MDRV_SCREEN_VISIBLE_AREA(MOS6561_MAME_XPOS, MOS6561_MAME_XPOS + MOS6561_MAME_XSIZE - 1, MOS6561_MAME_YPOS, MOS6561_MAME_YPOS + MOS6561_MAME_YSIZE - 1)
|
| 714 | | |
| 715 | | MDRV_PALETTE_LENGTH(16)
|
| 716 | | MDRV_PALETTE_INIT( vic20 )
|
| 717 | | |
| 718 | | MDRV_VIDEO_UPDATE( vic20 )
|
| 719 | | |
| 720 | | /* sound hardware */
|
| 721 | | MDRV_SPEAKER_STANDARD_MONO("mono")
|
| 722 | | MDRV_MOS656X_ADD(M6560_TAG, vic20_6561_intf)
|
| 723 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
| 724 | | MDRV_SOUND_ADD("dac", DAC, 0)
|
| 725 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
| 726 | | MACHINE_DRIVER_END
|
| 727 | | |
| 728 | | /* ROMs */
|
| 729 | | |
| 730 | | ROM_START( vic1001 )
|
| 731 | | ROM_REGION( 0x10000, M6502_TAG, 0 )
|
| 732 | | ROM_LOAD( "901460-02", 0x8000, 0x1000, CRC(fcfd8a4b) SHA1(dae61ac03065aa2904af5c123ce821855898c555) )
|
| 733 | | ROM_LOAD( "901486-01", 0xc000, 0x2000, CRC(db4c43c1) SHA1(587d1e90950675ab6b12d91248a3f0d640d02e8d) )
|
| 734 | | ROM_LOAD( "901486-02", 0xe000, 0x2000, CRC(336900d7) SHA1(c9ead45e6674d1042ca6199160e8583c23aeac22) )
|
| 735 | | ROM_END
|
| 736 | | |
| 737 | | ROM_START( vic20 )
|
| 738 | | ROM_REGION( 0x10000, M6502_TAG, 0 )
|
| 739 | | ROM_LOAD( "901460-03.ud7", 0x8000, 0x1000, CRC(83e032a6) SHA1(4fd85ab6647ee2ac7ba40f729323f2472d35b9b4) )
|
| 740 | | ROM_LOAD( "901486-01.ue11", 0xc000, 0x2000, CRC(db4c43c1) SHA1(587d1e90950675ab6b12d91248a3f0d640d02e8d) )
|
| 741 | | ROM_LOAD( "901486-06.ue12", 0xe000, 0x2000, CRC(e5e7c174) SHA1(06de7ec017a5e78bd6746d89c2ecebb646efeb19) )
|
| 742 | | ROM_END
|
| 743 | | |
| 744 | | ROM_START( vic20p )
|
| 745 | | ROM_REGION( 0x10000, M6502_TAG, 0 )
|
| 746 | | ROM_LOAD( "901460-03.ud7", 0x8000, 0x1000, CRC(83e032a6) SHA1(4fd85ab6647ee2ac7ba40f729323f2472d35b9b4) )
|
| 747 | | ROM_LOAD( "901486-01.ue11", 0xc000, 0x2000, CRC(db4c43c1) SHA1(587d1e90950675ab6b12d91248a3f0d640d02e8d) )
|
| 748 | | ROM_LOAD( "901486-07.ue12", 0xe000, 0x2000, CRC(4be07cb4) SHA1(ce0137ed69f003a299f43538fa9eee27898e621e) )
|
| 749 | | ROM_END
|
| 750 | | |
| 751 | | ROM_START( vic20s )
|
| 752 | | ROM_REGION( 0x10000, M6502_TAG, 0 )
|
| 753 | | ROM_LOAD( "nec22101.207", 0x8000, 0x1000, CRC(d808551d) SHA1(f403f0b0ce5922bd61bbd768bdd6f0b38e648c9f) )
|
| 754 | | ROM_LOAD( "901486-01.ue11", 0xc000, 0x2000, CRC(db4c43c1) SHA1(587d1e90950675ab6b12d91248a3f0d640d02e8d) )
|
| 755 | | ROM_LOAD( "nec22081.206", 0xe000, 0x2000, CRC(b2a60662) SHA1(cb3e2f6e661ea7f567977751846ce9ad524651a3) )
|
| 756 | | ROM_END
|
| 757 | | |
| 758 | | /* System Drivers */
|
| 759 | | |
| 760 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
| 761 | | COMP( 1980, vic1001, 0, 0, vic20_ntsc, vic1001, 0, "Commodore Business Machines", "VIC-1001 (Japan)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
|
| 762 | | COMP( 1981, vic20, vic1001, 0, vic20_ntsc, vic20, 0, "Commodore Business Machines", "VIC-20 (NTSC)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
|
| 763 | | COMP( 1981, vic20p, vic1001, 0, vic20_pal, vic20, 0, "Commodore Business Machines", "VIC-20 / VC-20 (PAL)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
|
| 764 | | COMP( 1981, vic20s, vic1001, 0, vic20_pal, vic20s, 0, "Commodore Business Machines", "VIC-20 (Sweden/Finland)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
|
| 1 | /* |
| 2 | |
| 3 | [CBM systems which belong to this driver (info to be moved to sysinfo.dat soon)] |
| 4 | (most of the informations are taken from http://www.zimmers.net/cbmpics/ ) |
| 5 | |
| 6 | |
| 7 | * VIC-1001 (1981, Japan) |
| 8 | |
| 9 | The first model released was the Japanese one. It featured support for the |
| 10 | Japanese katakana character. |
| 11 | |
| 12 | CPU: MOS Technology 6502 (1.01 MHz) |
| 13 | RAM: 5 kilobytes (Expanded to 21k though an external 16k unit) |
| 14 | ROM: 20 kilobytes |
| 15 | Video: MOS Technology 6560 "VIC"(Text: 22 columns, 23 rows; Hires: 176x184 |
| 16 | pixels bitmapped; 8 text colors, 16 background colors) |
| 17 | Sound: MOS Technology 6560 "VIC" (3 voices -square wave-, noise and volume) |
| 18 | Ports: 6522 VIA x2 (1 Joystick/Mouse port; CBM Serial port; 'Cartridge / |
| 19 | Game / Expansion' port; CBM Monitor port; CBM 'USER' port; Power and |
| 20 | reset switches; Power connector) |
| 21 | Keyboard: Full-sized QWERTY 66 key (8 programmable function keys; 2 sets of |
| 22 | Keyboardable graphic characters; 2 key direction cursor-pad) |
| 23 | |
| 24 | |
| 25 | * VIC 20 (1981) |
| 26 | |
| 27 | This system was the first computer to sell more than one million units |
| 28 | worldwide. It was sold both in Europe and in the US. In Germany the |
| 29 | computer was renamed as VC 20 (apparently, it stands for 'VolksComputer' |
| 30 | |
| 31 | CPU: MOS Technology 6502A (1.01 MHz) |
| 32 | RAM: 5 kilobytes (Expanded to 32k) |
| 33 | ROM: 20 kilobytes |
| 34 | Video: MOS Technology 6560 "VIC"(Text: 22 columns, 23 rows; Hires: 176x184 |
| 35 | pixels bitmapped; 8 text colors, 16 background colors) |
| 36 | Sound: MOS Technology 6560 "VIC" (3 voices -square wave-, noise and volume) |
| 37 | Ports: 6522 VIA x2 (1 Joystick/Mouse port; CBM Serial port; 'Cartridge / |
| 38 | Game / Expansion' port; CBM Monitor port; CBM 'USER' port; Power and |
| 39 | reset switches; Power connector) |
| 40 | Keyboard: Full-sized QWERTY 66 key (8 programmable function keys; 2 sets of |
| 41 | Keyboardable graphic characters; 2 key direction cursor-pad) |
| 42 | |
| 43 | |
| 44 | * VIC 21 (1983) |
| 45 | |
| 46 | It consists of a VIC 20 with built-in RAM expansion, to reach a RAM |
| 47 | capability of 21 kilobytes. |
| 48 | |
| 49 | |
| 50 | * VIC 20CR |
| 51 | |
| 52 | CR stands for Cost Reduced, as it consisted of a board with only 2 (larger) |
| 53 | block of RAM instead of 8. |
| 54 | |
| 55 | ******************************************************************************* |
| 56 | |
| 57 | TODO: |
| 58 | |
| 59 | - C1540 is unreliable (VIA timing issues?) |
| 60 | - clean up inputs |
| 61 | - clean up VIA interface |
| 62 | - access violation in mos6560.c |
| 63 | * In the Chips (Japan, USA).60 |
| 64 | * K-Star Patrol (Europe).60 |
| 65 | * Seafox (Japan, USA).60 |
| 66 | - SHIFT LOCK |
| 67 | - restore key |
| 68 | - light pen |
| 69 | - VIC21 (built in 21K ram) |
| 70 | - new cart system (rpk) |
| 71 | |
| 72 | */ |
| 73 | |
| 74 | #include "emu.h" |
| 75 | #include "includes/vic20.h" |
| 76 | #include "includes/cbm.h" |
| 77 | #include "cpu/m6502/m6502.h" |
| 78 | #include "devices/cartslot.h" |
| 79 | #include "devices/messram.h" |
| 80 | #include "machine/6522via.h" |
| 81 | #include "machine/c1541.h" |
| 82 | #include "machine/cbmiec.h" |
| 83 | #include "machine/ieee488.h" |
| 84 | #include "machine/vic1112.h" |
| 85 | #include "machine/cbmipt.h" |
| 86 | #include "sound/mos6560.h" |
| 87 | #include "sound/dac.h" |
| 88 | |
| 89 | /* Memory Maps */ |
| 90 | |
| 91 | static ADDRESS_MAP_START( vic20_mem, ADDRESS_SPACE_PROGRAM, 8 ) |
| 92 | AM_RANGE(0x0000, 0x03ff) AM_RAM |
| 93 | // AM_RANGE(0x0400, 0x07ff) RAM1 |
| 94 | // AM_RANGE(0x0800, 0x0bff) RAM2 |
| 95 | // AM_RANGE(0x0c00, 0x0fff) RAM3 |
| 96 | AM_RANGE(0x1000, 0x1fff) AM_RAM |
| 97 | // AM_RANGE(0x2000, 0x3fff) BLK1 |
| 98 | // AM_RANGE(0x4000, 0x5fff) BLK2 |
| 99 | // AM_RANGE(0x6000, 0x7fff) BLK3 |
| 100 | AM_RANGE(0x8000, 0x8fff) AM_ROM |
| 101 | AM_RANGE(0x9000, 0x900f) AM_DEVREADWRITE(M6560_TAG, mos6560_port_r, mos6560_port_w) |
| 102 | AM_RANGE(0x9110, 0x911f) AM_DEVREADWRITE(M6522_0_TAG, via_r, via_w) |
| 103 | AM_RANGE(0x9120, 0x912f) AM_DEVREADWRITE(M6522_1_TAG, via_r, via_w) |
| 104 | AM_RANGE(0x9400, 0x97ff) AM_RAM |
| 105 | // AM_RANGE(0x9800, 0x9bff) I/O2 |
| 106 | // AM_RANGE(0x9c00, 0x9fff) I/O3 |
| 107 | // AM_RANGE(0xa000, 0xbfff) BLK5 |
| 108 | AM_RANGE(0xc000, 0xffff) AM_ROM |
| 109 | ADDRESS_MAP_END |
| 110 | |
| 111 | /* Input Ports */ |
| 112 | |
| 113 | #ifdef UNUSED_FUNCTION |
| 114 | static INPUT_PORTS_START( vic_lightpen_6560 ) |
| 115 | PORT_START( "LIGHTX" ) |
| 116 | PORT_BIT( 0xff, 0, IPT_PADDLE ) PORT_NAME("Lightpen X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(2) PORT_MINMAX(0,(MOS6560_MAME_XSIZE - 1)) PORT_CATEGORY(12) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) |
| 117 | |
| 118 | PORT_START( "LIGHTY" ) |
| 119 | PORT_BIT( 0xff, 0, IPT_PADDLE ) PORT_NAME("Lightpen Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(2) PORT_MINMAX(0,(MOS6560_MAME_YSIZE - 1)) PORT_CATEGORY(12) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) |
| 120 | INPUT_PORTS_END |
| 121 | |
| 122 | |
| 123 | static INPUT_PORTS_START( vic_lightpen_6561 ) |
| 124 | PORT_START( "LIGHTX" ) |
| 125 | PORT_BIT( 0xff, 0, IPT_PADDLE ) PORT_NAME("Lightpen X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(2) PORT_MINMAX(0,(MOS6560_MAME_XSIZE - 1)) PORT_CATEGORY(12) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) |
| 126 | |
| 127 | PORT_START( "LIGHTY" ) |
| 128 | PORT_BIT( 0x1ff, 0, IPT_PADDLE ) PORT_NAME("Lightpen Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(2) PORT_MINMAX(0,(MOS6561_MAME_YSIZE - 1)) PORT_CATEGORY(12) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) |
| 129 | INPUT_PORTS_END |
| 130 | #endif |
| 131 | |
| 132 | static INPUT_PORTS_START( vic20 ) |
| 133 | PORT_INCLUDE( vic_keyboard ) /* ROW0 -> ROW7 */ |
| 134 | |
| 135 | PORT_INCLUDE( vic_special ) /* SPECIAL */ |
| 136 | |
| 137 | PORT_INCLUDE( vic_controls ) /* CTRLSEL, JOY, FAKE0, FAKE1, PADDLE0, PADDLE1 */ |
| 138 | INPUT_PORTS_END |
| 139 | |
| 140 | |
| 141 | static INPUT_PORTS_START( vic1001 ) |
| 142 | PORT_INCLUDE( vic20 ) |
| 143 | |
| 144 | PORT_MODIFY( "ROW0" ) |
| 145 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('\xA5') |
| 146 | INPUT_PORTS_END |
| 147 | |
| 148 | |
| 149 | static INPUT_PORTS_START( vic20s ) |
| 150 | PORT_INCLUDE( vic20 ) |
| 151 | |
| 152 | PORT_MODIFY( "ROW0" ) |
| 153 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(':') PORT_CHAR('*') |
| 154 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') |
| 155 | PORT_MODIFY( "ROW1" ) |
| 156 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('@') |
| 157 | PORT_MODIFY( "ROW2" ) |
| 158 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(0x00C4) |
| 159 | PORT_MODIFY( "ROW5" ) |
| 160 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(';') PORT_CHAR('+') |
| 161 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(0x00D6) |
| 162 | PORT_MODIFY( "ROW6" ) |
| 163 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(0x00C5) |
| 164 | PORT_MODIFY( "ROW7" ) |
| 165 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') |
| 166 | INPUT_PORTS_END |
| 167 | |
| 168 | /* VIA 0 Interface */ |
| 169 | |
| 170 | static READ8_DEVICE_HANDLER( via0_pa_r ) |
| 171 | { |
| 172 | /* |
| 173 | |
| 174 | bit description |
| 175 | |
| 176 | PA0 SERIAL CLK IN |
| 177 | PA1 SERIAL DATA IN |
| 178 | PA2 JOY 0 |
| 179 | PA3 JOY 1 |
| 180 | PA4 JOY 2 |
| 181 | PA5 LITE PEN |
| 182 | PA6 CASS SWITCH |
| 183 | PA7 SERIAL ATN OUT |
| 184 | |
| 185 | */ |
| 186 | |
| 187 | vic20_state *state = (vic20_state *)device->machine->driver_data; |
| 188 | UINT8 data = 0xfc; |
| 189 | |
| 190 | /* serial clock in */ |
| 191 | data |= cbm_iec_clk_r(state->iec); |
| 192 | |
| 193 | /* serial data in */ |
| 194 | data |= cbm_iec_data_r(state->iec) << 1; |
| 195 | |
| 196 | /* joystick */ |
| 197 | data &= ~(input_port_read(device->machine, "JOY") & 0x3c); |
| 198 | |
| 199 | /* cassette switch */ |
| 200 | if ((cassette_get_state(state->cassette) & CASSETTE_MASK_UISTATE) != CASSETTE_STOPPED) |
| 201 | data &= ~0x40; |
| 202 | else |
| 203 | data |= 0x40; |
| 204 | |
| 205 | return data; |
| 206 | } |
| 207 | |
| 208 | static WRITE8_DEVICE_HANDLER( via0_pa_w ) |
| 209 | { |
| 210 | /* |
| 211 | |
| 212 | bit description |
| 213 | |
| 214 | PA0 SERIAL CLK IN |
| 215 | PA1 SERIAL DATA IN |
| 216 | PA2 JOY 0 |
| 217 | PA3 JOY 1 |
| 218 | PA4 JOY 2 |
| 219 | PA5 LITE PEN |
| 220 | PA6 CASS SWITCH |
| 221 | PA7 SERIAL ATN OUT |
| 222 | |
| 223 | */ |
| 224 | |
| 225 | vic20_state *state = (vic20_state *)device->machine->driver_data; |
| 226 | |
| 227 | /* serial attention out */ |
| 228 | cbm_iec_atn_w(state->iec, device, !BIT(data, 7)); |
| 229 | } |
| 230 | |
| 231 | static READ8_DEVICE_HANDLER( via0_pb_r ) |
| 232 | { |
| 233 | /* |
| 234 | |
| 235 | bit description |
| 236 | |
| 237 | PB0 USER PORT C |
| 238 | PB1 USER PORT D |
| 239 | PB2 USER PORT E |
| 240 | PB3 USER PORT F |
| 241 | PB4 USER PORT H |
| 242 | PB5 USER PORT J |
| 243 | PB6 USER PORT K |
| 244 | PB7 USER PORT L |
| 245 | |
| 246 | */ |
| 247 | |
| 248 | return 0; |
| 249 | } |
| 250 | |
| 251 | static WRITE8_DEVICE_HANDLER( via0_pb_w ) |
| 252 | { |
| 253 | /* |
| 254 | |
| 255 | bit description |
| 256 | |
| 257 | PB0 USER PORT C |
| 258 | PB1 USER PORT D |
| 259 | PB2 USER PORT E |
| 260 | PB3 USER PORT F |
| 261 | PB4 USER PORT H |
| 262 | PB5 USER PORT J |
| 263 | PB6 USER PORT K |
| 264 | PB7 USER PORT L |
| 265 | |
| 266 | */ |
| 267 | } |
| 268 | |
| 269 | static WRITE8_DEVICE_HANDLER( via0_ca2_w ) |
| 270 | { |
| 271 | vic20_state *state = (vic20_state *)device->machine->driver_data; |
| 272 | |
| 273 | if (!BIT(data, 0)) |
| 274 | { |
| 275 | cassette_change_state(state->cassette, CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); |
| 276 | timer_device_adjust_periodic(state->cassette_timer, attotime_zero, 0, ATTOTIME_IN_HZ(44100)); |
| 277 | } |
| 278 | else |
| 279 | { |
| 280 | cassette_change_state(state->cassette, CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); |
| 281 | timer_device_reset(state->cassette_timer); |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | static const via6522_interface vic20_via0_intf = |
| 286 | { |
| 287 | DEVCB_HANDLER(via0_pa_r), |
| 288 | DEVCB_HANDLER(via0_pb_r), |
| 289 | DEVCB_NULL, // RESTORE |
| 290 | DEVCB_NULL, |
| 291 | DEVCB_NULL, |
| 292 | DEVCB_NULL, |
| 293 | DEVCB_HANDLER(via0_pa_w), |
| 294 | DEVCB_HANDLER(via0_pb_w), |
| 295 | DEVCB_NULL, |
| 296 | DEVCB_NULL, |
| 297 | DEVCB_HANDLER(via0_ca2_w), // CASS MOTOR |
| 298 | DEVCB_NULL, |
| 299 | DEVCB_CPU_INPUT_LINE(M6502_TAG, INPUT_LINE_NMI) |
| 300 | }; |
| 301 | |
| 302 | /* VIA 1 Interface */ |
| 303 | |
| 304 | static READ8_DEVICE_HANDLER( via1_pa_r ) |
| 305 | { |
| 306 | /* |
| 307 | |
| 308 | bit description |
| 309 | |
| 310 | PA0 ROW 0 |
| 311 | PA1 ROW 1 |
| 312 | PA2 ROW 2 |
| 313 | PA3 ROW 3 |
| 314 | PA4 ROW 4 |
| 315 | PA5 ROW 5 |
| 316 | PA6 ROW 6 |
| 317 | PA7 ROW 7 |
| 318 | |
| 319 | */ |
| 320 | |
| 321 | vic20_state *state = (vic20_state *)device->machine->driver_data; |
| 322 | UINT8 data = 0xff; |
| 323 | |
| 324 | if (!BIT(state->key_col, 0)) data &= input_port_read(device->machine, "ROW0"); |
| 325 | if (!BIT(state->key_col, 1)) data &= input_port_read(device->machine, "ROW1"); |
| 326 | if (!BIT(state->key_col, 2)) data &= input_port_read(device->machine, "ROW2"); |
| 327 | if (!BIT(state->key_col, 3)) data &= input_port_read(device->machine, "ROW3"); |
| 328 | if (!BIT(state->key_col, 4)) data &= input_port_read(device->machine, "ROW4"); |
| 329 | if (!BIT(state->key_col, 5)) data &= input_port_read(device->machine, "ROW5"); |
| 330 | if (!BIT(state->key_col, 6)) data &= input_port_read(device->machine, "ROW6"); |
| 331 | if (!BIT(state->key_col, 7)) data &= input_port_read(device->machine, "ROW7"); |
| 332 | |
| 333 | return data; |
| 334 | } |
| 335 | |
| 336 | static READ8_DEVICE_HANDLER( via1_pb_r ) |
| 337 | { |
| 338 | /* |
| 339 | |
| 340 | bit description |
| 341 | |
| 342 | PB0 COL 0 |
| 343 | PB1 COL 1 |
| 344 | PB2 COL 2 |
| 345 | PB3 COL 3, CASS WRITE |
| 346 | PB4 COL 4 |
| 347 | PB5 COL 5 |
| 348 | PB6 COL 6 |
| 349 | PB7 COL 7, JOY 3 |
| 350 | |
| 351 | */ |
| 352 | |
| 353 | UINT8 data = 0xff; |
| 354 | |
| 355 | /* joystick */ |
| 356 | data &= ~(input_port_read(device->machine, "JOY") & 0x80); |
| 357 | |
| 358 | return data; |
| 359 | } |
| 360 | |
| 361 | static WRITE8_DEVICE_HANDLER( via1_pb_w ) |
| 362 | { |
| 363 | /* |
| 364 | |
| 365 | bit description |
| 366 | |
| 367 | PB0 COL 0 |
| 368 | PB1 COL 1 |
| 369 | PB2 COL 2 |
| 370 | PB3 COL 3, CASS WRITE |
| 371 | PB4 COL 4 |
| 372 | PB5 COL 5 |
| 373 | PB6 COL 6 |
| 374 | PB7 COL 7, JOY 3 |
| 375 | |
| 376 | */ |
| 377 | |
| 378 | vic20_state *state = (vic20_state *)device->machine->driver_data; |
| 379 | |
| 380 | /* cassette write */ |
| 381 | cassette_output(devtag_get_device(device->machine, "cassette"), BIT(data, 3) ? -(0x5a9e >> 1) : +(0x5a9e >> 1)); |
| 382 | |
| 383 | /* keyboard column */ |
| 384 | state->key_col = data; |
| 385 | } |
| 386 | |
| 387 | static WRITE_LINE_DEVICE_HANDLER( via1_ca2_w ) |
| 388 | { |
| 389 | vic20_state *driver_state = (vic20_state *)device->machine->driver_data; |
| 390 | |
| 391 | /* serial clock out */ |
| 392 | cbm_iec_clk_w(driver_state->iec, device, !state); |
| 393 | } |
| 394 | |
| 395 | static WRITE_LINE_DEVICE_HANDLER( via1_cb2_w ) |
| 396 | { |
| 397 | vic20_state *driver_state = (vic20_state *)device->machine->driver_data; |
| 398 | |
| 399 | /* serial data out */ |
| 400 | cbm_iec_data_w(driver_state->iec, device, !state); |
| 401 | } |
| 402 | |
| 403 | static const via6522_interface vic20_via1_intf = |
| 404 | { |
| 405 | DEVCB_HANDLER(via1_pa_r), |
| 406 | DEVCB_HANDLER(via1_pb_r), |
| 407 | DEVCB_NULL, /* CASS READ */ |
| 408 | DEVCB_NULL, |
| 409 | DEVCB_NULL, |
| 410 | DEVCB_NULL, |
| 411 | |
| 412 | DEVCB_NULL, |
| 413 | DEVCB_HANDLER(via1_pb_w), |
| 414 | DEVCB_NULL, |
| 415 | DEVCB_NULL, |
| 416 | DEVCB_LINE(via1_ca2_w), |
| 417 | DEVCB_LINE(via1_cb2_w), |
| 418 | |
| 419 | DEVCB_CPU_INPUT_LINE(M6502_TAG, M6502_IRQ_LINE) |
| 420 | }; |
| 421 | |
| 422 | /* Cassette Interface */ |
| 423 | |
| 424 | static TIMER_DEVICE_CALLBACK( cassette_tick ) |
| 425 | { |
| 426 | vic20_state *state = (vic20_state *)timer->machine->driver_data; |
| 427 | int data = (cassette_input(state->cassette) > +0.0) ? 1 : 0; |
| 428 | |
| 429 | via_ca1_w(state->via1, data); |
| 430 | } |
| 431 | |
| 432 | /* IEC Serial Bus */ |
| 433 | |
| 434 | static CBM_IEC_DAISY( cbm_iec_daisy ) |
| 435 | { |
| 436 | { M6522_0_TAG }, |
| 437 | { M6522_1_TAG, DEVCB_DEVICE_LINE(M6522_1_TAG, via_cb1_w) }, |
| 438 | { C1541_IEC(C1540_TAG) }, |
| 439 | { NULL} |
| 440 | }; |
| 441 | |
| 442 | /* IEEE-488 Bus */ |
| 443 | |
| 444 | static IEEE488_DAISY( ieee488_daisy ) |
| 445 | { |
| 446 | { VIC1112_IEEE488 }, |
| 447 | { C2031_IEEE488(C2031_TAG) }, |
| 448 | { NULL} |
| 449 | }; |
| 450 | |
| 451 | /* MOS6560 Interface */ |
| 452 | |
| 453 | #define VC20ADDR2MOS6560ADDR(a) (((a) > 0x8000) ? ((a) & 0x1fff) : ((a) | 0x2000)) |
| 454 | #define MOS6560ADDR2VC20ADDR(a) (((a) > 0x2000) ? ((a) & 0x1fff) : ((a) | 0x8000)) |
| 455 | |
| 456 | static int vic20_dma_read_color( running_machine *machine, int offset ) |
| 457 | { |
| 458 | const address_space *program = cputag_get_address_space(machine, M6502_TAG, ADDRESS_SPACE_PROGRAM); |
| 459 | |
| 460 | return memory_read_byte(program, 0x9400 | (offset & 0x3ff)); |
| 461 | } |
| 462 | |
| 463 | static int vic20_dma_read( running_machine *machine, int offset ) |
| 464 | { |
| 465 | const address_space *program = cputag_get_address_space(machine, M6502_TAG, ADDRESS_SPACE_PROGRAM); |
| 466 | |
| 467 | return memory_read_byte(program, MOS6560ADDR2VC20ADDR(offset)); |
| 468 | } |
| 469 | |
| 470 | static UINT8 vic20_lightx_cb( running_machine *machine ) |
| 471 | { |
| 472 | return (input_port_read_safe(machine, "LIGHTX", 0) & ~0x01); |
| 473 | } |
| 474 | |
| 475 | static UINT8 vic20_lighty_cb( running_machine *machine ) |
| 476 | { |
| 477 | return (input_port_read_safe(machine, "LIGHTY", 0) & ~0x01); |
| 478 | } |
| 479 | |
| 480 | static UINT8 vic20_lightbut_cb( running_machine *machine ) |
| 481 | { |
| 482 | return (((input_port_read(machine, "CTRLSEL") & 0xf0) == 0x20) && (input_port_read(machine, "JOY") & 0x40)); |
| 483 | } |
| 484 | |
| 485 | static UINT8 vic20_paddle0_cb( running_machine *machine ) |
| 486 | { |
| 487 | return input_port_read(machine, "PADDLE0"); |
| 488 | } |
| 489 | |
| 490 | static UINT8 vic20_paddle1_cb( running_machine *machine ) |
| 491 | { |
| 492 | return input_port_read(machine, "PADDLE1"); |
| 493 | } |
| 494 | |
| 495 | static const mos6560_interface vic20_6560_intf = |
| 496 | { |
| 497 | "screen", /* screen */ |
| 498 | MOS6560, |
| 499 | vic20_lightx_cb, vic20_lighty_cb, vic20_lightbut_cb, /* lightgun cb */ |
| 500 | vic20_paddle0_cb, vic20_paddle1_cb, /* paddle cb */ |
| 501 | vic20_dma_read, vic20_dma_read_color /* DMA */ |
| 502 | }; |
| 503 | |
| 504 | static const mos6560_interface vic20_6561_intf = |
| 505 | { |
| 506 | "screen", /* screen */ |
| 507 | MOS6561, |
| 508 | vic20_lightx_cb, vic20_lighty_cb, vic20_lightbut_cb, /* lightgun cb */ |
| 509 | vic20_paddle0_cb, vic20_paddle1_cb, /* paddle cb */ |
| 510 | vic20_dma_read, vic20_dma_read_color /* DMA */ |
| 511 | }; |
| 512 | |
| 513 | |
| 514 | /* Machine Initialization */ |
| 515 | |
| 516 | static MACHINE_START( vic20 ) |
| 517 | { |
| 518 | vic20_state *state = (vic20_state *)machine->driver_data; |
| 519 | const address_space *program = cputag_get_address_space(machine, M6502_TAG, ADDRESS_SPACE_PROGRAM); |
| 520 | |
| 521 | /* find devices */ |
| 522 | state->via0 = devtag_get_device(machine, M6522_0_TAG); |
| 523 | state->via1 = devtag_get_device(machine, M6522_1_TAG); |
| 524 | state->iec = devtag_get_device(machine, IEC_TAG); |
| 525 | state->cassette = devtag_get_device(machine, CASSETTE_TAG); |
| 526 | state->cassette_timer = devtag_get_device(machine, TIMER_C1530_TAG); |
| 527 | state->mos6560 = devtag_get_device(machine, M6560_TAG); |
| 528 | |
| 529 | /* set VIA clocks */ |
| 530 | state->via0->set_clock(cputag_get_clock(machine, M6502_TAG)); |
| 531 | state->via1->set_clock(cputag_get_clock(machine, M6502_TAG)); |
| 532 | |
| 533 | /* memory expansions */ |
| 534 | switch (messram_get_size(devtag_get_device(machine, "messram"))) |
| 535 | { |
| 536 | case 32*1024: |
| 537 | memory_install_ram(program, 0x6000, 0x7fff, 0, 0, NULL); |
| 538 | /* fallthru */ |
| 539 | case 24*1024: |
| 540 | memory_install_ram(program, 0x4000, 0x5fff, 0, 0, NULL); |
| 541 | /* fallthru */ |
| 542 | case 16*1024: |
| 543 | memory_install_ram(program, 0x2000, 0x3fff, 0, 0, NULL); |
| 544 | /* fallthru */ |
| 545 | case 8*1024: |
| 546 | memory_install_ram(program, 0x0400, 0x0fff, 0, 0, NULL); |
| 547 | } |
| 548 | |
| 549 | /* register for state saving */ |
| 550 | state_save_register_global(machine, state->key_col); |
| 551 | } |
| 552 | |
| 553 | |
| 554 | /* Cartridge */ |
| 555 | |
| 556 | static DEVICE_IMAGE_LOAD( vic20_cart ) |
| 557 | { |
| 558 | const address_space *program = cputag_get_address_space(image->machine, M6502_TAG, ADDRESS_SPACE_PROGRAM); |
| 559 | const char *filetype = image_filetype(image); |
| 560 | int address = 0; |
| 561 | int size = image_length(image); |
| 562 | UINT8 *ptr; |
| 563 | |
| 564 | if (!mame_stricmp(filetype, "20")) |
| 565 | address = 0x2000; |
| 566 | else if (!mame_stricmp(filetype, "40")) |
| 567 | address = 0x4000; |
| 568 | else if (!mame_stricmp(filetype, "60")) |
| 569 | address = 0x6000; |
| 570 | else if (!mame_stricmp(filetype, "70")) |
| 571 | address = 0x7000; |
| 572 | else if (!mame_stricmp(filetype, "a0")) |
| 573 | address = 0xa000; |
| 574 | else if (!mame_stricmp(filetype, "b0")) |
| 575 | address = 0xb000; |
| 576 | |
| 577 | ptr = memory_region(image->machine, M6502_TAG); |
| 578 | |
| 579 | if (size == 0x4000 && address != 0x4000) |
| 580 | { |
| 581 | image_fread(image, ptr + address, 0x2000); |
| 582 | image_fread(image, ptr + 0xa000, 0x2000); |
| 583 | |
| 584 | memory_install_rom(program, address, address + 0x1fff, 0, 0, ptr + address); |
| 585 | memory_install_rom(program, 0xa000, 0xbfff, 0, 0, ptr + 0xa000); |
| 586 | } |
| 587 | else |
| 588 | { |
| 589 | image_fread(image, ptr + address, size); |
| 590 | |
| 591 | memory_install_rom(program, address, (address + size) - 1, 0, 0, ptr + address); |
| 592 | } |
| 593 | |
| 594 | return INIT_PASS; |
| 595 | } |
| 596 | |
| 597 | /* Graphics Definitions and Video Emulation */ |
| 598 | |
| 599 | static const unsigned char mos6560_palette[] = |
| 600 | { |
| 601 | /* ripped from vice, a very excellent emulator */ |
| 602 | /* black, white, red, cyan */ |
| 603 | 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0xf0, |
| 604 | /* purple, green, blue, yellow */ |
| 605 | 0x60, 0x00, 0x60, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xf0, 0xd0, 0xd0, 0x00, |
| 606 | /* orange, light orange, pink, light cyan, */ |
| 607 | 0xc0, 0xa0, 0x00, 0xff, 0xa0, 0x00, 0xf0, 0x80, 0x80, 0x00, 0xff, 0xff, |
| 608 | /* light violett, light green, light blue, light yellow */ |
| 609 | 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xa0, 0xff, 0xff, 0xff, 0x00 |
| 610 | }; |
| 611 | |
| 612 | static PALETTE_INIT( vic20 ) |
| 613 | { |
| 614 | int i; |
| 615 | |
| 616 | for (i = 0; i < sizeof(mos6560_palette) / 3; i++) |
| 617 | { |
| 618 | palette_set_color_rgb(machine, i, mos6560_palette[i * 3], mos6560_palette[i * 3 + 1], mos6560_palette[i * 3 + 2]); |
| 619 | } |
| 620 | } |
| 621 | |
| 622 | static VIDEO_UPDATE( vic20 ) |
| 623 | { |
| 624 | vic20_state *state = (vic20_state *)screen->machine->driver_data; |
| 625 | mos6560_video_update(state->mos6560, bitmap, cliprect); |
| 626 | return 0; |
| 627 | } |
| 628 | |
| 629 | /* Machine Driver */ |
| 630 | |
| 631 | static INTERRUPT_GEN( vic20_raster_interrupt ) |
| 632 | { |
| 633 | vic20_state *state = (vic20_state *)device->machine->driver_data; |
| 634 | mos6560_raster_interrupt_gen(state->mos6560); |
| 635 | } |
| 636 | |
| 637 | static MACHINE_DRIVER_START( vic20_common ) |
| 638 | MDRV_DRIVER_DATA(vic20_state) |
| 639 | |
| 640 | MDRV_TIMER_ADD_PERIODIC(TIMER_C1530_TAG, cassette_tick, HZ(44100)) |
| 641 | |
| 642 | /* devices */ |
| 643 | MDRV_VIA6522_ADD(M6522_0_TAG, 0, vic20_via0_intf) |
| 644 | MDRV_VIA6522_ADD(M6522_1_TAG, 0, vic20_via1_intf) |
| 645 | |
| 646 | MDRV_QUICKLOAD_ADD("quickload", cbm_vc20, "p00,prg", 0) |
| 647 | MDRV_CASSETTE_ADD(CASSETTE_TAG, cbm_cassette_config ) |
| 648 | MDRV_CBM_IEC_ADD(IEC_TAG, cbm_iec_daisy) |
| 649 | MDRV_C1540_ADD(C1540_TAG, IEC_TAG, 8) |
| 650 | /* |
| 651 | MDRV_IEEE488_ADD(IEEE488_TAG, ieee488_daisy) |
| 652 | MDRV_VIC1112_ADD(IEEE488_TAG) |
| 653 | MDRV_C2031_ADD(C2031_TAG, IEEE488_TAG, 9) |
| 654 | */ |
| 655 | MDRV_CARTSLOT_ADD("cart") |
| 656 | MDRV_CARTSLOT_EXTENSION_LIST("20,40,60,70,a0,b0") |
| 657 | MDRV_CARTSLOT_NOT_MANDATORY |
| 658 | MDRV_CARTSLOT_LOAD(vic20_cart) |
| 659 | |
| 660 | /* internal ram */ |
| 661 | MDRV_RAM_ADD("messram") |
| 662 | MDRV_RAM_DEFAULT_SIZE("5K") |
| 663 | MDRV_RAM_EXTRA_OPTIONS("8K,16K,24K,32K") |
| 664 | MACHINE_DRIVER_END |
| 665 | |
| 666 | static MACHINE_DRIVER_START( vic20_ntsc ) |
| 667 | MDRV_IMPORT_FROM( vic20_common ) |
| 668 | |
| 669 | /* basic machine hardware */ |
| 670 | MDRV_CPU_ADD(M6502_TAG, M6502, MOS6560_CLOCK) |
| 671 | MDRV_CPU_PROGRAM_MAP(vic20_mem) |
| 672 | MDRV_CPU_PERIODIC_INT(vic20_raster_interrupt, MOS656X_HRETRACERATE) |
| 673 | |
| 674 | MDRV_MACHINE_START(vic20) |
| 675 | |
| 676 | /* video hardware */ |
| 677 | MDRV_SCREEN_ADD("screen", RASTER) |
| 678 | MDRV_SCREEN_REFRESH_RATE(MOS6560_VRETRACERATE) |
| 679 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 680 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 681 | MDRV_SCREEN_SIZE((MOS6560_XSIZE + 7) & ~7, MOS6560_YSIZE) |
| 682 | MDRV_SCREEN_VISIBLE_AREA(MOS6560_MAME_XPOS, MOS6560_MAME_XPOS + MOS6560_MAME_XSIZE - 1, MOS6560_MAME_YPOS, MOS6560_MAME_YPOS + MOS6560_MAME_YSIZE - 1) |
| 683 | |
| 684 | MDRV_PALETTE_LENGTH(16) |
| 685 | MDRV_PALETTE_INIT( vic20 ) |
| 686 | |
| 687 | MDRV_VIDEO_UPDATE( vic20 ) |
| 688 | |
| 689 | /* sound hardware */ |
| 690 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 691 | MDRV_MOS656X_ADD(M6560_TAG, vic20_6560_intf) |
| 692 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 693 | MDRV_SOUND_ADD("dac", DAC, 0) |
| 694 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 695 | MACHINE_DRIVER_END |
| 696 | |
| 697 | static MACHINE_DRIVER_START( vic20_pal ) |
| 698 | MDRV_IMPORT_FROM( vic20_common ) |
| 699 | |
| 700 | /* basic machine hardware */ |
| 701 | MDRV_CPU_ADD(M6502_TAG, M6502, MOS6561_CLOCK) |
| 702 | MDRV_CPU_PROGRAM_MAP(vic20_mem) |
| 703 | MDRV_CPU_PERIODIC_INT(vic20_raster_interrupt, MOS656X_HRETRACERATE) |
| 704 | |
| 705 | MDRV_MACHINE_START(vic20) |
| 706 | |
| 707 | /* video hardware */ |
| 708 | MDRV_SCREEN_ADD("screen", RASTER) |
| 709 | MDRV_SCREEN_REFRESH_RATE(MOS6561_VRETRACERATE) |
| 710 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 711 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 712 | MDRV_SCREEN_SIZE((MOS6561_XSIZE + 7) & ~7, MOS6561_YSIZE) |
| 713 | MDRV_SCREEN_VISIBLE_AREA(MOS6561_MAME_XPOS, MOS6561_MAME_XPOS + MOS6561_MAME_XSIZE - 1, MOS6561_MAME_YPOS, MOS6561_MAME_YPOS + MOS6561_MAME_YSIZE - 1) |
| 714 | |
| 715 | MDRV_PALETTE_LENGTH(16) |
| 716 | MDRV_PALETTE_INIT( vic20 ) |
| 717 | |
| 718 | MDRV_VIDEO_UPDATE( vic20 ) |
| 719 | |
| 720 | /* sound hardware */ |
| 721 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 722 | MDRV_MOS656X_ADD(M6560_TAG, vic20_6561_intf) |
| 723 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 724 | MDRV_SOUND_ADD("dac", DAC, 0) |
| 725 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 726 | MACHINE_DRIVER_END |
| 727 | |
| 728 | /* ROMs */ |
| 729 | |
| 730 | ROM_START( vic1001 ) |
| 731 | ROM_REGION( 0x10000, M6502_TAG, 0 ) |
| 732 | ROM_LOAD( "901460-02", 0x8000, 0x1000, CRC(fcfd8a4b) SHA1(dae61ac03065aa2904af5c123ce821855898c555) ) |
| 733 | ROM_LOAD( "901486-01", 0xc000, 0x2000, CRC(db4c43c1) SHA1(587d1e90950675ab6b12d91248a3f0d640d02e8d) ) |
| 734 | ROM_LOAD( "901486-02", 0xe000, 0x2000, CRC(336900d7) SHA1(c9ead45e6674d1042ca6199160e8583c23aeac22) ) |
| 735 | ROM_END |
| 736 | |
| 737 | ROM_START( vic20 ) |
| 738 | ROM_REGION( 0x10000, M6502_TAG, 0 ) |
| 739 | ROM_LOAD( "901460-03.ud7", 0x8000, 0x1000, CRC(83e032a6) SHA1(4fd85ab6647ee2ac7ba40f729323f2472d35b9b4) ) |
| 740 | ROM_LOAD( "901486-01.ue11", 0xc000, 0x2000, CRC(db4c43c1) SHA1(587d1e90950675ab6b12d91248a3f0d640d02e8d) ) |
| 741 | ROM_LOAD( "901486-06.ue12", 0xe000, 0x2000, CRC(e5e7c174) SHA1(06de7ec017a5e78bd6746d89c2ecebb646efeb19) ) |
| 742 | ROM_END |
| 743 | |
| 744 | ROM_START( vic20p ) |
| 745 | ROM_REGION( 0x10000, M6502_TAG, 0 ) |
| 746 | ROM_LOAD( "901460-03.ud7", 0x8000, 0x1000, CRC(83e032a6) SHA1(4fd85ab6647ee2ac7ba40f729323f2472d35b9b4) ) |
| 747 | ROM_LOAD( "901486-01.ue11", 0xc000, 0x2000, CRC(db4c43c1) SHA1(587d1e90950675ab6b12d91248a3f0d640d02e8d) ) |
| 748 | ROM_LOAD( "901486-07.ue12", 0xe000, 0x2000, CRC(4be07cb4) SHA1(ce0137ed69f003a299f43538fa9eee27898e621e) ) |
| 749 | ROM_END |
| 750 | |
| 751 | ROM_START( vic20s ) |
| 752 | ROM_REGION( 0x10000, M6502_TAG, 0 ) |
| 753 | ROM_LOAD( "nec22101.207", 0x8000, 0x1000, CRC(d808551d) SHA1(f403f0b0ce5922bd61bbd768bdd6f0b38e648c9f) ) |
| 754 | ROM_LOAD( "901486-01.ue11", 0xc000, 0x2000, CRC(db4c43c1) SHA1(587d1e90950675ab6b12d91248a3f0d640d02e8d) ) |
| 755 | ROM_LOAD( "nec22081.206", 0xe000, 0x2000, CRC(b2a60662) SHA1(cb3e2f6e661ea7f567977751846ce9ad524651a3) ) |
| 756 | ROM_END |
| 757 | |
| 758 | /* System Drivers */ |
| 759 | |
| 760 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 761 | COMP( 1980, vic1001, 0, 0, vic20_ntsc, vic1001, 0, "Commodore Business Machines", "VIC-1001 (Japan)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) |
| 762 | COMP( 1981, vic20, vic1001, 0, vic20_ntsc, vic20, 0, "Commodore Business Machines", "VIC-20 (NTSC)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) |
| 763 | COMP( 1981, vic20p, vic1001, 0, vic20_pal, vic20, 0, "Commodore Business Machines", "VIC-20 / VC-20 (PAL)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) |
| 764 | COMP( 1981, vic20s, vic1001, 0, vic20_pal, vic20s, 0, "Commodore Business Machines", "VIC-20 (Sweden/Finland)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) |
src/mess/drivers/phc25.c
| r7571 | r7572 | |
| 1 | | /***************************************************************************
|
| 2 | | |
| 3 | | Sanyo PHC-25
|
| 4 | | |
| 5 | | Skeleton driver.
|
| 6 | | |
| 7 | | ****************************************************************************/
|
| 8 | | |
| 9 | | /*
|
| 10 | | |
| 11 | | http://www.geocities.jp/sanyo_phc_25/
|
| 12 | | |
| 13 | | Z80 @ 4 MHz
|
| 14 | | MC6847 video
|
| 15 | | 3x 8KB bios ROM
|
| 16 | | 1x 4KB chargen ROM
|
| 17 | | 16KB RAM
|
| 18 | | 6KB video RAM
|
| 19 | | |
| 20 | | */
|
| 21 | | |
| 22 | | /*
|
| 23 | | |
| 24 | | TODO:
|
| 25 | | |
| 26 | | - MC6847 mode selection lines
|
| 27 | | - tune cassette trigger level
|
| 28 | | - accurate video timing
|
| 29 | | |
| 30 | | */
|
| 31 | | |
| 32 | | #include "emu.h"
|
| 33 | | #include "includes/phc25.h"
|
| 34 | | #include "cpu/z80/z80.h"
|
| 35 | | #include "devices/cassette.h"
|
| 36 | | #include "devices/messram.h"
|
| 37 | | #include "machine/ctronics.h"
|
| 38 | | #include "video/m6847.h"
|
| 39 | | #include "sound/ay8910.h"
|
| 40 | | |
| 41 | | /* Read/Write Handlers */
|
| 42 | | |
| 43 | | static READ8_HANDLER( port40_r )
|
| 44 | | {
|
| 45 | | /*
|
| 46 | | |
| 47 | | bit description
|
| 48 | | |
| 49 | | 0 |
| 50 | | 1 |
| 51 | | 2 |
| 52 | | 3 |
| 53 | | 4 vertical sync
|
| 54 | | 5 cassette read
|
| 55 | | 6 centronics busy
|
| 56 | | 7 horizontal sync
|
| 57 | | |
| 58 | | */
|
| 59 | | |
| 60 | | phc25_state *state = (phc25_state *)space->machine->driver_data;
|
| 61 | | |
| 62 | | UINT8 data = 0;
|
| 63 | | |
| 64 | | /* vertical sync */
|
| 65 | | data |= !mc6847_fs_r(state->mc6847) << 4;
|
| 66 | | |
| 67 | | /* cassette read */
|
| 68 | | data |= (cassette_input(state->cassette) < +0.3) << 5;
|
| 69 | | |
| 70 | | /* centronics busy */
|
| 71 | | data |= centronics_busy_r(state->centronics) << 6;
|
| 72 | | |
| 73 | | /* horizontal sync */
|
| 74 | | data |= !mc6847_hs_r(state->mc6847) << 7;
|
| 75 | | |
| 76 | | return data;
|
| 77 | | }
|
| 78 | | |
| 79 | | static WRITE8_HANDLER( port40_w )
|
| 80 | | {
|
| 81 | | /*
|
| 82 | | |
| 83 | | bit description
|
| 84 | | |
| 85 | | 0 cassette output
|
| 86 | | 1 cassette motor
|
| 87 | | 2 MC6847 INT/EXT
|
| 88 | | 3 centronics strobe
|
| 89 | | 4 |
| 90 | | 5 MC6847 |
| 91 | | 6 MC6847 |
| 92 | | 7 MC6847 A/G
|
| 93 | | |
| 94 | | */
|
| 95 | | |
| 96 | | phc25_state *state = (phc25_state *)space->machine->driver_data;
|
| 97 | | |
| 98 | | /* cassette output */
|
| 99 | | cassette_output(state->cassette, BIT(data, 0) ? -1.0 : +1.0);
|
| 100 | | |
| 101 | | /* internal/external character generator */
|
| 102 | | mc6847_intext_w(state->mc6847, BIT(data, 2));
|
| 103 | | |
| 104 | | /* cassette motor */
|
| 105 | | cassette_change_state(state->cassette, BIT(data, 1) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
|
| 106 | | |
| 107 | | /* centronics strobe */
|
| 108 | | centronics_strobe_w(state->centronics, BIT(data, 3));
|
| 109 | | |
| 110 | | /* alphanumerics/graphics */
|
| 111 | | mc6847_ag_w(state->mc6847, BIT(data, 7));
|
| 112 | | }
|
| 113 | | |
| 114 | | /* Memory Maps */
|
| 115 | | |
| 116 | | static ADDRESS_MAP_START( phc25_mem, ADDRESS_SPACE_PROGRAM, 8 )
|
| 117 | | ADDRESS_MAP_UNMAP_HIGH
|
| 118 | | AM_RANGE(0x0000, 0x5fff) AM_ROM AM_REGION(Z80_TAG, 0)
|
| 119 | | AM_RANGE(0x6000, 0x77ff) AM_RAM AM_BASE_MEMBER(phc25_state, video_ram)
|
| 120 | | AM_RANGE(0xc000, 0xffff) AM_RAM
|
| 121 | | ADDRESS_MAP_END
|
| 122 | | |
| 123 | | static ADDRESS_MAP_START( phc25_io, ADDRESS_SPACE_IO, 8 )
|
| 124 | | ADDRESS_MAP_UNMAP_HIGH
|
| 125 | | ADDRESS_MAP_GLOBAL_MASK(0xff)
|
| 126 | | AM_RANGE(0x00, 0x00) AM_DEVWRITE(CENTRONICS_TAG, centronics_data_w)
|
| 127 | | AM_RANGE(0x40, 0x40) AM_READWRITE(port40_r, port40_w)
|
| 128 | | AM_RANGE(0x80, 0x80) AM_READ_PORT("KEY0")
|
| 129 | | AM_RANGE(0x81, 0x81) AM_READ_PORT("KEY1")
|
| 130 | | AM_RANGE(0x82, 0x82) AM_READ_PORT("KEY2")
|
| 131 | | AM_RANGE(0x83, 0x83) AM_READ_PORT("KEY3")
|
| 132 | | AM_RANGE(0x84, 0x84) AM_READ_PORT("KEY4")
|
| 133 | | AM_RANGE(0x85, 0x85) AM_READ_PORT("KEY5")
|
| 134 | | AM_RANGE(0x86, 0x86) AM_READ_PORT("KEY6")
|
| 135 | | AM_RANGE(0x87, 0x87) AM_READ_PORT("KEY7")
|
| 136 | | AM_RANGE(0x88, 0x88) AM_READ_PORT("KEY8")
|
| 137 | | AM_RANGE(0xc0, 0xc0) AM_DEVWRITE(AY8910_TAG, ay8910_address_w)
|
| 138 | | AM_RANGE(0xc1, 0xc1) AM_DEVREADWRITE(AY8910_TAG, ay8910_r, ay8910_data_w)
|
| 139 | | ADDRESS_MAP_END
|
| 140 | | |
| 141 | | /* Input Ports */
|
| 142 | | |
| 143 | | INPUT_PORTS_START( phc25 )
|
| 144 | | PORT_START("KEY0")
|
| 145 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
|
| 146 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
|
| 147 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
|
| 148 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
|
| 149 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
|
| 150 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
|
| 151 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*')
|
| 152 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) // unlabeled key
|
| 153 | | |
| 154 | | PORT_START("KEY1")
|
| 155 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
|
| 156 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
|
| 157 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
|
| 158 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
|
| 159 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x93") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
|
| 160 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
|
| 161 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
|
| 162 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
|
| 163 | | |
| 164 | | PORT_START("KEY2")
|
| 165 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
|
| 166 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
|
| 167 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
|
| 168 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
|
| 169 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x90") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
|
| 170 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('~')
|
| 171 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[')
|
| 172 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 173 | | |
| 174 | | PORT_START("KEY3")
|
| 175 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
|
| 176 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
|
| 177 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
|
| 178 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
|
| 179 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x92") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
|
| 180 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('|')
|
| 181 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']')
|
| 182 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
|
| 183 | | |
| 184 | | PORT_START("KEY4")
|
| 185 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
|
| 186 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
|
| 187 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
|
| 188 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
|
| 189 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3))
|
| 190 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
|
| 191 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
|
| 192 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 193 | | |
| 194 | | PORT_START("KEY5")
|
| 195 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
|
| 196 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
|
| 197 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
|
| 198 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
|
| 199 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4))
|
| 200 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=')
|
| 201 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@')
|
| 202 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 203 | | |
| 204 | | PORT_START("KEY6")
|
| 205 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
|
| 206 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
|
| 207 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
|
| 208 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
|
| 209 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2))
|
| 210 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
|
| 211 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
|
| 212 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 213 | | |
| 214 | | PORT_START("KEY7")
|
| 215 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
|
| 216 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
|
| 217 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
|
| 218 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') |
| 219 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))
|
| 220 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
|
| 221 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
|
| 222 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
|
| 223 | | |
| 224 | | PORT_START("KEY8")
|
| 225 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 226 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GRAPH") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT))
|
| 227 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
|
| 228 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
|
| 229 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 230 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK))
|
| 231 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 232 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 233 | | |
| 234 | | PORT_START("JOY0")
|
| 235 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
|
| 236 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
|
| 237 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
|
| 238 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
|
| 239 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
|
| 240 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 241 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 242 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 243 | | |
| 244 | | PORT_START("JOY1")
|
| 245 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
|
| 246 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
|
| 247 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
|
| 248 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
|
| 249 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
|
| 250 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 251 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 252 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 253 | | INPUT_PORTS_END
|
| 254 | | |
| 255 | | INPUT_PORTS_START( phc25j )
|
| 256 | | PORT_INCLUDE( phc25 )
|
| 257 | | INPUT_PORTS_END
|
| 258 | | |
| 259 | | /* Video */
|
| 260 | | |
| 261 | | static READ8_DEVICE_HANDLER( phc25_video_ram_r )
|
| 262 | | {
|
| 263 | | phc25_state *state = (phc25_state *)device->machine->driver_data;
|
| 264 | | |
| 265 | | return state->video_ram[offset & 0x17ff];
|
| 266 | | }
|
| 267 | | |
| 268 | | static UINT8 phc25_char_rom_r(running_machine *machine, UINT8 ch, int line)
|
| 269 | | {
|
| 270 | | phc25_state *state = (phc25_state *)machine->driver_data;
|
| 271 | | |
| 272 | | return state->char_rom[((ch - 2) * 12) + line + 4];
|
| 273 | | }
|
| 274 | | |
| 275 | | static const mc6847_interface mc6847_intf =
|
| 276 | | {
|
| 277 | | DEVCB_HANDLER(phc25_video_ram_r),
|
| 278 | | DEVCB_NULL,
|
| 279 | | DEVCB_NULL,
|
| 280 | | DEVCB_NULL,
|
| 281 | | DEVCB_NULL,
|
| 282 | | DEVCB_NULL,
|
| 283 | | DEVCB_NULL,
|
| 284 | | DEVCB_NULL,
|
| 285 | | DEVCB_NULL,
|
| 286 | | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0),
|
| 287 | | DEVCB_NULL,
|
| 288 | | DEVCB_NULL
|
| 289 | | };
|
| 290 | | |
| 291 | | static VIDEO_START( pal )
|
| 292 | | {
|
| 293 | | phc25_state *state = (phc25_state *)machine->driver_data;
|
| 294 | | |
| 295 | | /* find memory regions */
|
| 296 | | state->char_rom = memory_region(machine, Z80_TAG) + 0x5000;
|
| 297 | | }
|
| 298 | | |
| 299 | | static VIDEO_START( ntsc )
|
| 300 | | {
|
| 301 | | phc25_state *state = (phc25_state *)machine->driver_data;
|
| 302 | | |
| 303 | | /* find memory regions */
|
| 304 | | state->char_rom = memory_region(machine, "chargen");
|
| 305 | | }
|
| 306 | | |
| 307 | | static VIDEO_UPDATE( phc25 )
|
| 308 | | {
|
| 309 | | phc25_state *state = (phc25_state *)screen->machine->driver_data;
|
| 310 | | |
| 311 | | return mc6847_update(state->mc6847, bitmap, cliprect);
|
| 312 | | }
|
| 313 | | |
| 314 | | /* AY-3-8910 Interface */
|
| 315 | | |
| 316 | | static const ay8910_interface ay8910_intf =
|
| 317 | | {
|
| 318 | | AY8910_LEGACY_OUTPUT,
|
| 319 | | AY8910_DEFAULT_LOADS,
|
| 320 | | DEVCB_INPUT_PORT("JOY0"),
|
| 321 | | DEVCB_INPUT_PORT("JOY1"),
|
| 322 | | DEVCB_NULL,
|
| 323 | | DEVCB_NULL
|
| 324 | | };
|
| 325 | | |
| 326 | | /* Cassette Configuration */
|
| 327 | | |
| 328 | | static const cassette_config phc25_cassette_config =
|
| 329 | | {
|
| 330 | | cassette_default_formats,
|
| 331 | | NULL,
|
| 332 | | (cassette_state)(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED)
|
| 333 | | };
|
| 334 | | |
| 335 | | /* Machine Initialization */
|
| 336 | | |
| 337 | | static MACHINE_START( phc25 )
|
| 338 | | {
|
| 339 | | phc25_state *state = (phc25_state *)machine->driver_data;
|
| 340 | | |
| 341 | | /* find devices */
|
| 342 | | state->mc6847 = devtag_get_device(machine, MC6847_TAG);
|
| 343 | | state->centronics = devtag_get_device(machine, CENTRONICS_TAG);
|
| 344 | | state->cassette = devtag_get_device(machine, CASSETTE_TAG);
|
| 345 | | |
| 346 | | /* register for state saving */
|
| 347 | | // state_save_register_global(machine, state->);
|
| 348 | | }
|
| 349 | | |
| 350 | | /* Machine Driver */
|
| 351 | | |
| 352 | | static MACHINE_DRIVER_START( phc25 )
|
| 353 | | MDRV_DRIVER_DATA(phc25_state)
|
| 354 | | |
| 355 | | /* basic machine hardware */
|
| 356 | | MDRV_CPU_ADD(Z80_TAG, Z80, 4000000)
|
| 357 | | MDRV_CPU_PROGRAM_MAP(phc25_mem)
|
| 358 | | MDRV_CPU_IO_MAP(phc25_io)
|
| 359 | | |
| 360 | | MDRV_MACHINE_START(phc25)
|
| 361 | | |
| 362 | | /* video hardware */
|
| 363 | | MDRV_VIDEO_UPDATE(phc25)
|
| 364 | | |
| 365 | | /* sound hardware */
|
| 366 | | MDRV_SPEAKER_STANDARD_MONO("mono")
|
| 367 | | MDRV_SOUND_ADD(AY8910_TAG, AY8910, 1996750)
|
| 368 | | MDRV_SOUND_CONFIG(ay8910_intf)
|
| 369 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
| 370 | | |
| 371 | | /* devices */
|
| 372 | | MDRV_CASSETTE_ADD(CASSETTE_TAG, phc25_cassette_config)
|
| 373 | | MDRV_CENTRONICS_ADD(CENTRONICS_TAG, standard_centronics)
|
| 374 | |
|
| 375 | | /* internal ram */
|
| 376 | | MDRV_RAM_ADD("messram")
|
| 377 | | MDRV_RAM_DEFAULT_SIZE("16K")
|
| 378 | | MACHINE_DRIVER_END
|
| 379 | | |
| 380 | | static MACHINE_DRIVER_START( pal )
|
| 381 | | MDRV_IMPORT_FROM(phc25)
|
| 382 | | |
| 383 | | /* video hardware */
|
| 384 | | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
|
| 385 | | MDRV_SCREEN_REFRESH_RATE(M6847_PAL_FRAMES_PER_SECOND)
|
| 386 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
| 387 | | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
|
| 388 | | MDRV_SCREEN_SIZE(320, 25+192+26)
|
| 389 | | MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)
|
| 390 | | |
| 391 | | MDRV_PALETTE_LENGTH(16)
|
| 392 | | |
| 393 | | MDRV_MC6847_ADD(MC6847_TAG, mc6847_intf)
|
| 394 | | MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_PAL)
|
| 395 | | MDRV_MC6847_CHAR_ROM(phc25_char_rom_r)
|
| 396 | | |
| 397 | | MDRV_VIDEO_START(pal)
|
| 398 | | MACHINE_DRIVER_END
|
| 399 | | |
| 400 | | static MACHINE_DRIVER_START( ntsc )
|
| 401 | | MDRV_IMPORT_FROM(phc25)
|
| 402 | | |
| 403 | | /* video hardware */
|
| 404 | | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
|
| 405 | | MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)
|
| 406 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
| 407 | | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
|
| 408 | | MDRV_SCREEN_SIZE(320, 25+192+26)
|
| 409 | | MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)
|
| 410 | | |
| 411 | | MDRV_PALETTE_LENGTH(16)
|
| 412 | | |
| 413 | | MDRV_MC6847_ADD(MC6847_TAG, mc6847_intf)
|
| 414 | | MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_NTSC)
|
| 415 | | MDRV_MC6847_CHAR_ROM(phc25_char_rom_r)
|
| 416 | | |
| 417 | | MDRV_VIDEO_START(ntsc)
|
| 418 | | MACHINE_DRIVER_END
|
| 419 | | |
| 420 | | /* ROMs */
|
| 421 | | |
| 422 | | ROM_START( phc25 )
|
| 423 | | ROM_REGION( 0x6000, Z80_TAG, 0 )
|
| 424 | | ROM_LOAD( "phc25rom.0", 0x0000, 0x2000, CRC(fa28336b) SHA1(582376bee455e124de24ba4ac02326c8a592fa5a) )
|
| 425 | | ROM_LOAD( "phc25rom.1", 0x2000, 0x2000, CRC(38fd578b) SHA1(dc3db78c0cdc89f1605200d39535be65a4091705) )
|
| 426 | | ROM_LOAD( "phc25rom.2", 0x4000, 0x2000, CRC(54392b27) SHA1(1587827fe9438780b50164727ce3fdea1b98078a) )
|
| 427 | | ROM_END
|
| 428 | | |
| 429 | | ROM_START( phc25j )
|
| 430 | | ROM_REGION( 0x6000, Z80_TAG, 0 )
|
| 431 | | ROM_LOAD( "022 00aa.ic", 0x0000, 0x2000, NO_DUMP )
|
| 432 | | ROM_LOAD( "022 01aa.ic", 0x2000, 0x2000, NO_DUMP )
|
| 433 | | ROM_LOAD( "022 02aa.ic", 0x4000, 0x2000, NO_DUMP )
|
| 434 | | |
| 435 | | ROM_REGION( 0x1000, "chargen", 0 )
|
| 436 | | ROM_LOAD( "022 04a.ic", 0x0000, 0x1000, NO_DUMP )
|
| 437 | | ROM_END
|
| 438 | | |
| 439 | | /* Driver */
|
| 440 | | |
| 441 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
| 442 | | COMP( 1983, phc25, 0, 0, pal, phc25, 0, "Sanyo", "PHC-25 (Europe)", GAME_NOT_WORKING )
|
| 443 | | COMP( 1983, phc25j, phc25, 0, ntsc, phc25j, 0, "Sanyo", "PHC-25 (Japan)", GAME_NOT_WORKING )
|
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Sanyo PHC-25 |
| 4 | |
| 5 | Skeleton driver. |
| 6 | |
| 7 | ****************************************************************************/ |
| 8 | |
| 9 | /* |
| 10 | |
| 11 | http://www.geocities.jp/sanyo_phc_25/ |
| 12 | |
| 13 | Z80 @ 4 MHz |
| 14 | MC6847 video |
| 15 | 3x 8KB bios ROM |
| 16 | 1x 4KB chargen ROM |
| 17 | 16KB RAM |
| 18 | 6KB video RAM |
| 19 | |
| 20 | */ |
| 21 | |
| 22 | /* |
| 23 | |
| 24 | TODO: |
| 25 | |
| 26 | - MC6847 mode selection lines |
| 27 | - tune cassette trigger level |
| 28 | - accurate video timing |
| 29 | |
| 30 | */ |
| 31 | |
| 32 | #include "emu.h" |
| 33 | #include "includes/phc25.h" |
| 34 | #include "cpu/z80/z80.h" |
| 35 | #include "devices/cassette.h" |
| 36 | #include "devices/messram.h" |
| 37 | #include "machine/ctronics.h" |
| 38 | #include "video/m6847.h" |
| 39 | #include "sound/ay8910.h" |
| 40 | |
| 41 | /* Read/Write Handlers */ |
| 42 | |
| 43 | static READ8_HANDLER( port40_r ) |
| 44 | { |
| 45 | /* |
| 46 | |
| 47 | bit description |
| 48 | |
| 49 | 0 |
| 50 | 1 |
| 51 | 2 |
| 52 | 3 |
| 53 | 4 vertical sync |
| 54 | 5 cassette read |
| 55 | 6 centronics busy |
| 56 | 7 horizontal sync |
| 57 | |
| 58 | */ |
| 59 | |
| 60 | phc25_state *state = (phc25_state *)space->machine->driver_data; |
| 61 | |
| 62 | UINT8 data = 0; |
| 63 | |
| 64 | /* vertical sync */ |
| 65 | data |= !mc6847_fs_r(state->mc6847) << 4; |
| 66 | |
| 67 | /* cassette read */ |
| 68 | data |= (cassette_input(state->cassette) < +0.3) << 5; |
| 69 | |
| 70 | /* centronics busy */ |
| 71 | data |= centronics_busy_r(state->centronics) << 6; |
| 72 | |
| 73 | /* horizontal sync */ |
| 74 | data |= !mc6847_hs_r(state->mc6847) << 7; |
| 75 | |
| 76 | return data; |
| 77 | } |
| 78 | |
| 79 | static WRITE8_HANDLER( port40_w ) |
| 80 | { |
| 81 | /* |
| 82 | |
| 83 | bit description |
| 84 | |
| 85 | 0 cassette output |
| 86 | 1 cassette motor |
| 87 | 2 MC6847 INT/EXT |
| 88 | 3 centronics strobe |
| 89 | 4 |
| 90 | 5 MC6847 |
| 91 | 6 MC6847 |
| 92 | 7 MC6847 A/G |
| 93 | |
| 94 | */ |
| 95 | |
| 96 | phc25_state *state = (phc25_state *)space->machine->driver_data; |
| 97 | |
| 98 | /* cassette output */ |
| 99 | cassette_output(state->cassette, BIT(data, 0) ? -1.0 : +1.0); |
| 100 | |
| 101 | /* internal/external character generator */ |
| 102 | mc6847_intext_w(state->mc6847, BIT(data, 2)); |
| 103 | |
| 104 | /* cassette motor */ |
| 105 | cassette_change_state(state->cassette, BIT(data, 1) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); |
| 106 | |
| 107 | /* centronics strobe */ |
| 108 | centronics_strobe_w(state->centronics, BIT(data, 3)); |
| 109 | |
| 110 | /* alphanumerics/graphics */ |
| 111 | mc6847_ag_w(state->mc6847, BIT(data, 7)); |
| 112 | } |
| 113 | |
| 114 | /* Memory Maps */ |
| 115 | |
| 116 | static ADDRESS_MAP_START( phc25_mem, ADDRESS_SPACE_PROGRAM, 8 ) |
| 117 | ADDRESS_MAP_UNMAP_HIGH |
| 118 | AM_RANGE(0x0000, 0x5fff) AM_ROM AM_REGION(Z80_TAG, 0) |
| 119 | AM_RANGE(0x6000, 0x77ff) AM_RAM AM_BASE_MEMBER(phc25_state, video_ram) |
| 120 | AM_RANGE(0xc000, 0xffff) AM_RAM |
| 121 | ADDRESS_MAP_END |
| 122 | |
| 123 | static ADDRESS_MAP_START( phc25_io, ADDRESS_SPACE_IO, 8 ) |
| 124 | ADDRESS_MAP_UNMAP_HIGH |
| 125 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 126 | AM_RANGE(0x00, 0x00) AM_DEVWRITE(CENTRONICS_TAG, centronics_data_w) |
| 127 | AM_RANGE(0x40, 0x40) AM_READWRITE(port40_r, port40_w) |
| 128 | AM_RANGE(0x80, 0x80) AM_READ_PORT("KEY0") |
| 129 | AM_RANGE(0x81, 0x81) AM_READ_PORT("KEY1") |
| 130 | AM_RANGE(0x82, 0x82) AM_READ_PORT("KEY2") |
| 131 | AM_RANGE(0x83, 0x83) AM_READ_PORT("KEY3") |
| 132 | AM_RANGE(0x84, 0x84) AM_READ_PORT("KEY4") |
| 133 | AM_RANGE(0x85, 0x85) AM_READ_PORT("KEY5") |
| 134 | AM_RANGE(0x86, 0x86) AM_READ_PORT("KEY6") |
| 135 | AM_RANGE(0x87, 0x87) AM_READ_PORT("KEY7") |
| 136 | AM_RANGE(0x88, 0x88) AM_READ_PORT("KEY8") |
| 137 | AM_RANGE(0xc0, 0xc0) AM_DEVWRITE(AY8910_TAG, ay8910_address_w) |
| 138 | AM_RANGE(0xc1, 0xc1) AM_DEVREADWRITE(AY8910_TAG, ay8910_r, ay8910_data_w) |
| 139 | ADDRESS_MAP_END |
| 140 | |
| 141 | /* Input Ports */ |
| 142 | |
| 143 | INPUT_PORTS_START( phc25 ) |
| 144 | PORT_START("KEY0") |
| 145 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') |
| 146 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') |
| 147 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') |
| 148 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') |
| 149 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) |
| 150 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) |
| 151 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') |
| 152 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) // unlabeled key |
| 153 | |
| 154 | PORT_START("KEY1") |
| 155 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) |
| 156 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') |
| 157 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') |
| 158 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') |
| 159 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x93") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) |
| 160 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 161 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') |
| 162 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') |
| 163 | |
| 164 | PORT_START("KEY2") |
| 165 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') |
| 166 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') |
| 167 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') |
| 168 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') |
| 169 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x90") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) |
| 170 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('~') |
| 171 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') |
| 172 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 173 | |
| 174 | PORT_START("KEY3") |
| 175 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') |
| 176 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') |
| 177 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') |
| 178 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') |
| 179 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x92") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) |
| 180 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('|') |
| 181 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') |
| 182 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') |
| 183 | |
| 184 | PORT_START("KEY4") |
| 185 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') |
| 186 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') |
| 187 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') |
| 188 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') |
| 189 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) |
| 190 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') |
| 191 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') |
| 192 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 193 | |
| 194 | PORT_START("KEY5") |
| 195 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') |
| 196 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') |
| 197 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') |
| 198 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') |
| 199 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) |
| 200 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') |
| 201 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') |
| 202 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 203 | |
| 204 | PORT_START("KEY6") |
| 205 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') |
| 206 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') |
| 207 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') |
| 208 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') |
| 209 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) |
| 210 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') |
| 211 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') |
| 212 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 213 | |
| 214 | PORT_START("KEY7") |
| 215 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') |
| 216 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') |
| 217 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') |
| 218 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') |
| 219 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) |
| 220 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') |
| 221 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') |
| 222 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') |
| 223 | |
| 224 | PORT_START("KEY8") |
| 225 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 226 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GRAPH") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) |
| 227 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) |
| 228 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) |
| 229 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 230 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) |
| 231 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 232 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 233 | |
| 234 | PORT_START("JOY0") |
| 235 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) |
| 236 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) |
| 237 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) |
| 238 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) |
| 239 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) |
| 240 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 241 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 242 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 243 | |
| 244 | PORT_START("JOY1") |
| 245 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) |
| 246 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) |
| 247 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) |
| 248 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) |
| 249 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) |
| 250 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 251 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 252 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 253 | INPUT_PORTS_END |
| 254 | |
| 255 | INPUT_PORTS_START( phc25j ) |
| 256 | PORT_INCLUDE( phc25 ) |
| 257 | INPUT_PORTS_END |
| 258 | |
| 259 | /* Video */ |
| 260 | |
| 261 | static READ8_DEVICE_HANDLER( phc25_video_ram_r ) |
| 262 | { |
| 263 | phc25_state *state = (phc25_state *)device->machine->driver_data; |
| 264 | |
| 265 | return state->video_ram[offset & 0x17ff]; |
| 266 | } |
| 267 | |
| 268 | static UINT8 phc25_char_rom_r(running_machine *machine, UINT8 ch, int line) |
| 269 | { |
| 270 | phc25_state *state = (phc25_state *)machine->driver_data; |
| 271 | |
| 272 | return state->char_rom[((ch - 2) * 12) + line + 4]; |
| 273 | } |
| 274 | |
| 275 | static const mc6847_interface mc6847_intf = |
| 276 | { |
| 277 | DEVCB_HANDLER(phc25_video_ram_r), |
| 278 | DEVCB_NULL, |
| 279 | DEVCB_NULL, |
| 280 | DEVCB_NULL, |
| 281 | DEVCB_NULL, |
| 282 | DEVCB_NULL, |
| 283 | DEVCB_NULL, |
| 284 | DEVCB_NULL, |
| 285 | DEVCB_NULL, |
| 286 | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0), |
| 287 | DEVCB_NULL, |
| 288 | DEVCB_NULL |
| 289 | }; |
| 290 | |
| 291 | static VIDEO_START( pal ) |
| 292 | { |
| 293 | phc25_state *state = (phc25_state *)machine->driver_data; |
| 294 | |
| 295 | /* find memory regions */ |
| 296 | state->char_rom = memory_region(machine, Z80_TAG) + 0x5000; |
| 297 | } |
| 298 | |
| 299 | static VIDEO_START( ntsc ) |
| 300 | { |
| 301 | phc25_state *state = (phc25_state *)machine->driver_data; |
| 302 | |
| 303 | /* find memory regions */ |
| 304 | state->char_rom = memory_region(machine, "chargen"); |
| 305 | } |
| 306 | |
| 307 | static VIDEO_UPDATE( phc25 ) |
| 308 | { |
| 309 | phc25_state *state = (phc25_state *)screen->machine->driver_data; |
| 310 | |
| 311 | return mc6847_update(state->mc6847, bitmap, cliprect); |
| 312 | } |
| 313 | |
| 314 | /* AY-3-8910 Interface */ |
| 315 | |
| 316 | static const ay8910_interface ay8910_intf = |
| 317 | { |
| 318 | AY8910_LEGACY_OUTPUT, |
| 319 | AY8910_DEFAULT_LOADS, |
| 320 | DEVCB_INPUT_PORT("JOY0"), |
| 321 | DEVCB_INPUT_PORT("JOY1"), |
| 322 | DEVCB_NULL, |
| 323 | DEVCB_NULL |
| 324 | }; |
| 325 | |
| 326 | /* Cassette Configuration */ |
| 327 | |
| 328 | static const cassette_config phc25_cassette_config = |
| 329 | { |
| 330 | cassette_default_formats, |
| 331 | NULL, |
| 332 | (cassette_state)(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED) |
| 333 | }; |
| 334 | |
| 335 | /* Machine Initialization */ |
| 336 | |
| 337 | static MACHINE_START( phc25 ) |
| 338 | { |
| 339 | phc25_state *state = (phc25_state *)machine->driver_data; |
| 340 | |
| 341 | /* find devices */ |
| 342 | state->mc6847 = devtag_get_device(machine, MC6847_TAG); |
| 343 | state->centronics = devtag_get_device(machine, CENTRONICS_TAG); |
| 344 | state->cassette = devtag_get_device(machine, CASSETTE_TAG); |
| 345 | |
| 346 | /* register for state saving */ |
| 347 | // state_save_register_global(machine, state->); |
| 348 | } |
| 349 | |
| 350 | /* Machine Driver */ |
| 351 | |
| 352 | static MACHINE_DRIVER_START( phc25 ) |
| 353 | MDRV_DRIVER_DATA(phc25_state) |
| 354 | |
| 355 | /* basic machine hardware */ |
| 356 | MDRV_CPU_ADD(Z80_TAG, Z80, 4000000) |
| 357 | MDRV_CPU_PROGRAM_MAP(phc25_mem) |
| 358 | MDRV_CPU_IO_MAP(phc25_io) |
| 359 | |
| 360 | MDRV_MACHINE_START(phc25) |
| 361 | |
| 362 | /* video hardware */ |
| 363 | MDRV_VIDEO_UPDATE(phc25) |
| 364 | |
| 365 | /* sound hardware */ |
| 366 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 367 | MDRV_SOUND_ADD(AY8910_TAG, AY8910, 1996750) |
| 368 | MDRV_SOUND_CONFIG(ay8910_intf) |
| 369 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 370 | |
| 371 | /* devices */ |
| 372 | MDRV_CASSETTE_ADD(CASSETTE_TAG, phc25_cassette_config) |
| 373 | MDRV_CENTRONICS_ADD(CENTRONICS_TAG, standard_centronics) |
| 374 | |
| 375 | /* internal ram */ |
| 376 | MDRV_RAM_ADD("messram") |
| 377 | MDRV_RAM_DEFAULT_SIZE("16K") |
| 378 | MACHINE_DRIVER_END |
| 379 | |
| 380 | static MACHINE_DRIVER_START( pal ) |
| 381 | MDRV_IMPORT_FROM(phc25) |
| 382 | |
| 383 | /* video hardware */ |
| 384 | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER) |
| 385 | MDRV_SCREEN_REFRESH_RATE(M6847_PAL_FRAMES_PER_SECOND) |
| 386 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 387 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) |
| 388 | MDRV_SCREEN_SIZE(320, 25+192+26) |
| 389 | MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239) |
| 390 | |
| 391 | MDRV_PALETTE_LENGTH(16) |
| 392 | |
| 393 | MDRV_MC6847_ADD(MC6847_TAG, mc6847_intf) |
| 394 | MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_PAL) |
| 395 | MDRV_MC6847_CHAR_ROM(phc25_char_rom_r) |
| 396 | |
| 397 | MDRV_VIDEO_START(pal) |
| 398 | MACHINE_DRIVER_END |
| 399 | |
| 400 | static MACHINE_DRIVER_START( ntsc ) |
| 401 | MDRV_IMPORT_FROM(phc25) |
| 402 | |
| 403 | /* video hardware */ |
| 404 | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER) |
| 405 | MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND) |
| 406 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 407 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) |
| 408 | MDRV_SCREEN_SIZE(320, 25+192+26) |
| 409 | MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239) |
| 410 | |
| 411 | MDRV_PALETTE_LENGTH(16) |
| 412 | |
| 413 | MDRV_MC6847_ADD(MC6847_TAG, mc6847_intf) |
| 414 | MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_NTSC) |
| 415 | MDRV_MC6847_CHAR_ROM(phc25_char_rom_r) |
| 416 | |
| 417 | MDRV_VIDEO_START(ntsc) |
| 418 | MACHINE_DRIVER_END |
| 419 | |
| 420 | /* ROMs */ |
| 421 | |
| 422 | ROM_START( phc25 ) |
| 423 | ROM_REGION( 0x6000, Z80_TAG, 0 ) |
| 424 | ROM_LOAD( "phc25rom.0", 0x0000, 0x2000, CRC(fa28336b) SHA1(582376bee455e124de24ba4ac02326c8a592fa5a) ) |
| 425 | ROM_LOAD( "phc25rom.1", 0x2000, 0x2000, CRC(38fd578b) SHA1(dc3db78c0cdc89f1605200d39535be65a4091705) ) |
| 426 | ROM_LOAD( "phc25rom.2", 0x4000, 0x2000, CRC(54392b27) SHA1(1587827fe9438780b50164727ce3fdea1b98078a) ) |
| 427 | ROM_END |
| 428 | |
| 429 | ROM_START( phc25j ) |
| 430 | ROM_REGION( 0x6000, Z80_TAG, 0 ) |
| 431 | ROM_LOAD( "022 00aa.ic", 0x0000, 0x2000, NO_DUMP ) |
| 432 | ROM_LOAD( "022 01aa.ic", 0x2000, 0x2000, NO_DUMP ) |
| 433 | ROM_LOAD( "022 02aa.ic", 0x4000, 0x2000, NO_DUMP ) |
| 434 | |
| 435 | ROM_REGION( 0x1000, "chargen", 0 ) |
| 436 | ROM_LOAD( "022 04a.ic", 0x0000, 0x1000, NO_DUMP ) |
| 437 | ROM_END |
| 438 | |
| 439 | /* Driver */ |
| 440 | |
| 441 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 442 | COMP( 1983, phc25, 0, 0, pal, phc25, 0, "Sanyo", "PHC-25 (Europe)", GAME_NOT_WORKING ) |
| 443 | COMP( 1983, phc25j, phc25, 0, ntsc, phc25j, 0, "Sanyo", "PHC-25 (Japan)", GAME_NOT_WORKING ) |
src/mess/drivers/tandy2k.c
| r7571 | r7572 | |
| 1 | | /***************************************************************************
|
| 2 | | |
| 3 | | Tandy 2000
|
| 4 | | |
| 5 | | Skeleton driver.
|
| 6 | | |
| 7 | | ****************************************************************************/
|
| 8 | | |
| 9 | | /*
|
| 10 | | |
| 11 | | TODO:
|
| 12 | | |
| 13 | | - 80186
|
| 14 | | - CRT9007
|
| 15 | | - keyboard ROM
|
| 16 | | - hires graphics board
|
| 17 | | - floppy 720K DSQD
|
| 18 | | - DMA
|
| 19 | | - WD1010
|
| 20 | | - hard disk
|
| 21 | | - mouse
|
| 22 | | - save state
|
| 23 | | |
| 24 | | */
|
| 25 | | |
| 26 | | #include "emu.h"
|
| 27 | | #include "includes/tandy2k.h"
|
| 28 | | #include "cpu/i86/i86.h"
|
| 29 | | #include "cpu/mcs48/mcs48.h"
|
| 30 | | #include "devices/flopdrv.h"
|
| 31 | | #include "devices/messram.h"
|
| 32 | | #include "machine/ctronics.h"
|
| 33 | | #include "machine/i8255a.h"
|
| 34 | | #include "machine/msm8251.h"
|
| 35 | | #include "machine/pit8253.h"
|
| 36 | | #include "machine/pic8259.h"
|
| 37 | | #include "machine/upd765.h"
|
| 38 | | #include "sound/speaker.h"
|
| 39 | | #include "video/crt9007.h"
|
| 40 | | |
| 41 | | /* Read/Write Handlers */
|
| 42 | | |
| 43 | | static void speaker_update(tandy2k_state *state)
|
| 44 | | {
|
| 45 | | int level = !(state->spkrdata & state->outspkr);
|
| 46 | | |
| 47 | | speaker_level_w(state->speaker, level);
|
| 48 | | }
|
| 49 | | |
| 50 | | static READ8_HANDLER( enable_r )
|
| 51 | | {
|
| 52 | | /*
|
| 53 | | |
| 54 | | bit signal description
|
| 55 | | |
| 56 | | 0 RS-232 ring indicator
|
| 57 | | 1 RS-232 carrier detect
|
| 58 | | 2
|
| 59 | | 3
|
| 60 | | 4
|
| 61 | | 5
|
| 62 | | 6
|
| 63 | | 7 _ACLOW
|
| 64 | | |
| 65 | | */
|
| 66 | | |
| 67 | | return 0x80;
|
| 68 | | }
|
| 69 | | |
| 70 | | static WRITE8_HANDLER( enable_w )
|
| 71 | | {
|
| 72 | | /*
|
| 73 | | |
| 74 | | bit signal description
|
| 75 | | |
| 76 | | 0 KBEN keyboard enable
|
| 77 | | 1 EXTCLK external baud rate clock
|
| 78 | | 2 SPKRGATE enable periodic speaker output
|
| 79 | | 3 SPKRDATA direct output to speaker
|
| 80 | | 4 RFRQGATE enable refresh and baud rate clocks
|
| 81 | | 5 _FDCRESET reset 8272
|
| 82 | | 6 TMRIN0 enable 80186 timer 0
|
| 83 | | 7 TMRIN1 enable 80186 timer 1
|
| 84 | | |
| 85 | | */
|
| 86 | | |
| 87 | | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data;
|
| 88 | | |
| 89 | | /* keyboard enable */
|
| 90 | | state->kben = BIT(data, 0);
|
| 91 | | |
| 92 | | /* external baud rate clock */
|
| 93 | | state->extclk = BIT(data, 1);
|
| 94 | | |
| 95 | | /* speaker gate */
|
| 96 | | pit8253_gate0_w(state->pit, BIT(data, 2));
|
| 97 | | |
| 98 | | /* speaker data */
|
| 99 | | state->spkrdata = BIT(data, 3);
|
| 100 | | speaker_update(state);
|
| 101 | | |
| 102 | | /* refresh and baud rate clocks */
|
| 103 | | pit8253_gate1_w(state->pit, BIT(data, 4));
|
| 104 | | pit8253_gate2_w(state->pit, BIT(data, 4));
|
| 105 | | |
| 106 | | /* FDC reset */
|
| 107 | | upd765_reset_w(state->fdc, BIT(data, 5));
|
| 108 | | |
| 109 | | /* TODO timer 0 enable */
|
| 110 | | |
| 111 | | /* TODO timer 1 enable */
|
| 112 | | }
|
| 113 | | |
| 114 | | static WRITE8_HANDLER( dma_mux_w )
|
| 115 | | {
|
| 116 | | /*
|
| 117 | | |
| 118 | | bit description
|
| 119 | | |
| 120 | | 0 DMA channel 0 enable
|
| 121 | | 1 DMA channel 1 enable
|
| 122 | | 2 DMA channel 2 enable
|
| 123 | | 3 DMA channel 3 enable
|
| 124 | | 4 DMA channel 0 select
|
| 125 | | 5 DMA channel 1 select
|
| 126 | | 6 DMA channel 2 select
|
| 127 | | 7 DMA channel 3 select
|
| 128 | | |
| 129 | | */
|
| 130 | | }
|
| 131 | | |
| 132 | | static READ8_DEVICE_HANDLER( fldtc_r )
|
| 133 | | {
|
| 134 | | upd765_tc_w(device, 1);
|
| 135 | | upd765_tc_w(device, 0);
|
| 136 | | |
| 137 | | return 0;
|
| 138 | | }
|
| 139 | | |
| 140 | | static WRITE8_DEVICE_HANDLER( fldtc_w )
|
| 141 | | {
|
| 142 | | upd765_tc_w(device, 1);
|
| 143 | | upd765_tc_w(device, 0);
|
| 144 | | }
|
| 145 | | |
| 146 | | static WRITE8_HANDLER( addr_ctrl_w )
|
| 147 | | {
|
| 148 | | /*
|
| 149 | | |
| 150 | | bit signal description
|
| 151 | | |
| 152 | | 8 A15 A15 of video access
|
| 153 | | 9 A16 A16 of video access
|
| 154 | | 10 A17 A17 of video access
|
| 155 | | 11 A18 A18 of video access
|
| 156 | | 12 A19 A19 of video access
|
| 157 | | 13 CLKSPD clock speed (0 = 22.4 MHz, 1 = 28 MHz)
|
| 158 | | 14 CLKCNT dots/char (0 = 10 [800x400], 1 = 8 [640x400])
|
| 159 | | 15 VIDOUTS selects the video source for display on monochrome monitor
|
| 160 | | |
| 161 | | */
|
| 162 | | |
| 163 | | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data;
|
| 164 | | |
| 165 | | /* video access */
|
| 166 | | state->vram_base = data << 15;
|
| 167 | | |
| 168 | | /* video clock speed */
|
| 169 | | crt9007_set_clock(state->vpac, BIT(data, 5) ? XTAL_16MHz*28/16 : XTAL_16MHz*28/20);
|
| 170 | | |
| 171 | | /* dots per char */
|
| 172 | | crt9007_set_hpixels_per_column(state->vpac, BIT(data, 6) ? 8 : 10);
|
| 173 | | |
| 174 | | /* video source select */
|
| 175 | | state->vidouts = BIT(data, 7);
|
| 176 | | |
| 177 | | logerror("Address Control %02x\n", data);
|
| 178 | | }
|
| 179 | | |
| 180 | | static READ8_HANDLER( keyboard_x0_r )
|
| 181 | | {
|
| 182 | | /*
|
| 183 | | |
| 184 | | bit description
|
| 185 | | |
| 186 | | 0 X0
|
| 187 | | 1 X1
|
| 188 | | 2 X2
|
| 189 | | 3 X3
|
| 190 | | 4 X4
|
| 191 | | 5 X5
|
| 192 | | 6 X6
|
| 193 | | 7 X7
|
| 194 | | |
| 195 | | */
|
| 196 | | |
| 197 | | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data;
|
| 198 | | |
| 199 | | UINT8 data = 0xff;
|
| 200 | | |
| 201 | | if (!BIT(state->keylatch, 0)) data &= input_port_read(space->machine, "Y0");
|
| 202 | | if (!BIT(state->keylatch, 1)) data &= input_port_read(space->machine, "Y1");
|
| 203 | | if (!BIT(state->keylatch, 2)) data &= input_port_read(space->machine, "Y2");
|
| 204 | | if (!BIT(state->keylatch, 3)) data &= input_port_read(space->machine, "Y3");
|
| 205 | | if (!BIT(state->keylatch, 4)) data &= input_port_read(space->machine, "Y4");
|
| 206 | | if (!BIT(state->keylatch, 5)) data &= input_port_read(space->machine, "Y5");
|
| 207 | | if (!BIT(state->keylatch, 6)) data &= input_port_read(space->machine, "Y6");
|
| 208 | | if (!BIT(state->keylatch, 7)) data &= input_port_read(space->machine, "Y7");
|
| 209 | | if (!BIT(state->keylatch, 8)) data &= input_port_read(space->machine, "Y8");
|
| 210 | | if (!BIT(state->keylatch, 9)) data &= input_port_read(space->machine, "Y9");
|
| 211 | | if (!BIT(state->keylatch, 10)) data &= input_port_read(space->machine, "Y10");
|
| 212 | | if (!BIT(state->keylatch, 11)) data &= input_port_read(space->machine, "Y11");
|
| 213 | | |
| 214 | | return ~data;
|
| 215 | | }
|
| 216 | | |
| 217 | | static WRITE8_HANDLER( keyboard_y0_w )
|
| 218 | | {
|
| 219 | | /*
|
| 220 | | |
| 221 | | bit description
|
| 222 | | |
| 223 | | 0 Y0
|
| 224 | | 1 Y1
|
| 225 | | 2 Y2
|
| 226 | | 3 Y3
|
| 227 | | 4 Y4
|
| 228 | | 5 Y5
|
| 229 | | 6 Y6
|
| 230 | | 7 Y7
|
| 231 | | |
| 232 | | */
|
| 233 | | |
| 234 | | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data;
|
| 235 | | |
| 236 | | /* keyboard row select */
|
| 237 | | state->keylatch = (state->keylatch & 0xff00) | data;
|
| 238 | | }
|
| 239 | | |
| 240 | | static WRITE8_HANDLER( keyboard_y8_w )
|
| 241 | | {
|
| 242 | | /*
|
| 243 | | |
| 244 | | bit description
|
| 245 | | |
| 246 | | 0 Y8
|
| 247 | | 1 Y9
|
| 248 | | 2 Y10
|
| 249 | | 3 Y11
|
| 250 | | 4 LED 2
|
| 251 | | 5 LED 1
|
| 252 | | 6
|
| 253 | | 7
|
| 254 | | |
| 255 | | */
|
| 256 | | |
| 257 | | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data;
|
| 258 | | |
| 259 | | /* keyboard row select */
|
| 260 | | state->keylatch = ((data & 0x0f) << 8) | (state->keylatch & 0xff);
|
| 261 | | }
|
| 262 | | |
| 263 | | /* Memory Maps */
|
| 264 | | |
| 265 | | static ADDRESS_MAP_START( tandy2k_mem, ADDRESS_SPACE_PROGRAM, 16 )
|
| 266 | | ADDRESS_MAP_UNMAP_HIGH
|
| 267 | | // AM_RANGE(0x00000, 0xdffff) AM_RAM
|
| 268 | | // AM_RANGE(0xe0000, 0xf7fff) AM_RAM // hires graphics
|
| 269 | | AM_RANGE(0xf8000, 0xfbfff) AM_RAM AM_BASE_MEMBER(tandy2k_state, char_ram)
|
| 270 | | AM_RANGE(0xfc000, 0xfdfff) AM_MIRROR(0x2000) AM_ROM AM_REGION(I80186_TAG, 0)
|
| 271 | | ADDRESS_MAP_END
|
| 272 | | |
| 273 | | static ADDRESS_MAP_START( tandy2k_io, ADDRESS_SPACE_IO, 16 )
|
| 274 | | ADDRESS_MAP_UNMAP_HIGH
|
| 275 | | AM_RANGE(0x00000, 0x00001) AM_READWRITE8(enable_r, enable_w, 0x00ff)
|
| 276 | | AM_RANGE(0x00002, 0x00003) AM_WRITE8(dma_mux_w, 0x00ff)
|
| 277 | | AM_RANGE(0x00004, 0x00005) AM_DEVREADWRITE8(I8272A_TAG, fldtc_r, fldtc_w, 0x00ff)
|
| 278 | | AM_RANGE(0x00010, 0x00013) AM_DEVREADWRITE8(I8251A_TAG, msm8251_data_r, msm8251_data_w, 0x00ff)
|
| 279 | | AM_RANGE(0x00030, 0x00031) AM_DEVREAD8(I8272A_TAG, upd765_status_r, 0x00ff)
|
| 280 | | AM_RANGE(0x00032, 0x00033) AM_DEVREADWRITE8(I8272A_TAG, upd765_data_r, upd765_data_w, 0x00ff)
|
| 281 | | AM_RANGE(0x00040, 0x00047) AM_DEVREADWRITE8(I8253_TAG, pit8253_r, pit8253_w, 0x00ff)
|
| 282 | | AM_RANGE(0x00050, 0x00057) AM_DEVREADWRITE8(I8255A_TAG, i8255a_r, i8255a_w, 0x00ff)
|
| 283 | | AM_RANGE(0x00060, 0x00063) AM_DEVREADWRITE8(I8259A_0_TAG, pic8259_r, pic8259_w, 0x00ff)
|
| 284 | | AM_RANGE(0x00070, 0x00073) AM_DEVREADWRITE8(I8259A_1_TAG, pic8259_r, pic8259_w, 0x00ff)
|
| 285 | | AM_RANGE(0x00080, 0x00081) AM_DEVREADWRITE8(I8272A_TAG, upd765_dack_r, upd765_dack_w, 0x00ff)
|
| 286 | | AM_RANGE(0x00100, 0x0017f) AM_DEVREADWRITE8(CRT9007_TAG, crt9007_r, crt9007_w, 0x00ff)
|
| 287 | | AM_RANGE(0x00100, 0x0017f) AM_WRITE8(addr_ctrl_w, 0xff00)
|
| 288 | | // AM_RANGE(0x00180, 0x00180) AM_READ8(hires_status_r, 0x00ff)
|
| 289 | | // AM_RANGE(0x00180, 0x001bf) AM_WRITE(hires_palette_w)
|
| 290 | | // AM_RANGE(0x001a0, 0x001a0) AM_READ8(hires_plane_w, 0x00ff)
|
| 291 | | // AM_RANGE(0x0ff00, 0x0ffff) AM_READWRITE(i186_internal_port_r, i186_internal_port_w)
|
| 292 | | ADDRESS_MAP_END
|
| 293 | | |
| 294 | | static ADDRESS_MAP_START( tandy2k_hd_io, ADDRESS_SPACE_IO, 16 )
|
| 295 | | AM_IMPORT_FROM(tandy2k_io)
|
| 296 | | // AM_RANGE(0x000e0, 0x000ff) AM_WRITE8(hdc_dack_w, 0x00ff)
|
| 297 | | // AM_RANGE(0x0026c, 0x0026d) AM_DEVREADWRITE8(WD1010_TAG, hdc_reset_r, hdc_reset_w, 0x00ff)
|
| 298 | | // AM_RANGE(0x0026e, 0x0027f) AM_DEVREADWRITE8(WD1010_TAG, wd1010_r, wd1010_w, 0x00ff)
|
| 299 | | ADDRESS_MAP_END
|
| 300 | | |
| 301 | | static ADDRESS_MAP_START( keyboard_io, ADDRESS_SPACE_IO, 8 )
|
| 302 | | AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(keyboard_y0_w)
|
| 303 | | AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(keyboard_y8_w)
|
| 304 | | AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READ(keyboard_x0_r)
|
| 305 | | ADDRESS_MAP_END
|
| 306 | | |
| 307 | | /* Input Ports */
|
| 308 | | |
| 309 | | static INPUT_PORTS_START( tandy2k )
|
| 310 | | PORT_START("ROW0")
|
| 311 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 312 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 313 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 314 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 315 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 316 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 317 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 318 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 319 | | |
| 320 | | PORT_START("ROW1")
|
| 321 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 322 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 323 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 324 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 325 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 326 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 327 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 328 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 329 | | |
| 330 | | PORT_START("ROW2")
|
| 331 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 332 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 333 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 334 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 335 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 336 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 337 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 338 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 339 | | |
| 340 | | PORT_START("ROW3")
|
| 341 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 342 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 343 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 344 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 345 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 346 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 347 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 348 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 349 | | |
| 350 | | PORT_START("ROW4")
|
| 351 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 352 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 353 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 354 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 355 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 356 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 357 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 358 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 359 | | |
| 360 | | PORT_START("ROW5")
|
| 361 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 362 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 363 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 364 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 365 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 366 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 367 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 368 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 369 | | |
| 370 | | PORT_START("ROW6")
|
| 371 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 372 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 373 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 374 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 375 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 376 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 377 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 378 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 379 | | |
| 380 | | PORT_START("ROW7")
|
| 381 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 382 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 383 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 384 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 385 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 386 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 387 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 388 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 389 | | |
| 390 | | PORT_START("ROW8")
|
| 391 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 392 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 393 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 394 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 395 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 396 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 397 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 398 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 399 | | |
| 400 | | PORT_START("ROW9")
|
| 401 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 402 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 403 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 404 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 405 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 406 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 407 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 408 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 409 | | |
| 410 | | PORT_START("ROW10")
|
| 411 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 412 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 413 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 414 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 415 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 416 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 417 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 418 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 419 | | |
| 420 | | PORT_START("ROW11")
|
| 421 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 422 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 423 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 424 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 425 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 426 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 427 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 428 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD )
|
| 429 | | INPUT_PORTS_END
|
| 430 | | |
| 431 | | /* Video */
|
| 432 | | |
| 433 | | static VIDEO_START( tandy2k )
|
| 434 | | {
|
| 435 | | tandy2k_state *state = (tandy2k_state *)machine->driver_data;
|
| 436 | | |
| 437 | | /* find devices */
|
| 438 | | state->vpac = devtag_get_device(machine, CRT9007_TAG);
|
| 439 | | }
|
| 440 | | |
| 441 | | static VIDEO_UPDATE( tandy2k )
|
| 442 | | {
|
| 443 | | tandy2k_state *state = (tandy2k_state *)screen->machine->driver_data;
|
| 444 | | |
| 445 | | //if (state->vidouts)
|
| 446 | | {
|
| 447 | | crt9007_update(state->vpac, bitmap, cliprect);
|
| 448 | | }
|
| 449 | | |
| 450 | | return 0;
|
| 451 | | }
|
| 452 | | |
| 453 | | static CRT9007_DRAW_SCANLINE( tandy2k_crt9007_display_pixels )
|
| 454 | | {
|
| 455 | | tandy2k_state *state = (tandy2k_state *)device->machine->driver_data;
|
| 456 | | const address_space *program = cputag_get_address_space(device->machine, I80186_TAG, ADDRESS_SPACE_PROGRAM);
|
| 457 | | |
| 458 | | for (int sx = 0; sx < x_count; sx++)
|
| 459 | | {
|
| 460 | | UINT32 videoram_addr = (state->vram_base | (va << 1)) + sx;
|
| 461 | | UINT8 videoram_data = memory_read_word(program, videoram_addr);
|
| 462 | | UINT16 charram_addr = (videoram_data << 4) | sl;
|
| 463 | | UINT8 data = state->char_ram[charram_addr] & 0xff;
|
| 464 | | |
| 465 | | for (int bit = 0; bit < 10; bit++)
|
| 466 | | {
|
| 467 | | if (BIT(data, 7))
|
| 468 | | {
|
| 469 | | *BITMAP_ADDR16(bitmap, y, x + (sx * 10) + bit) = 1;
|
| 470 | | }
|
| 471 | | |
| 472 | | data <<= 1;
|
| 473 | | }
|
| 474 | | }
|
| 475 | | }
|
| 476 | | |
| 477 | | static CRT9007_INTERFACE( crt9007_intf )
|
| 478 | | {
|
| 479 | | SCREEN_TAG,
|
| 480 | | 10,
|
| 481 | | tandy2k_crt9007_display_pixels,
|
| 482 | | DEVCB_DEVICE_LINE(I8259A_1_TAG, pic8259_ir1_w),
|
| 483 | | DEVCB_NULL,
|
| 484 | | DEVCB_NULL,
|
| 485 | | DEVCB_NULL,
|
| 486 | | DEVCB_NULL,
|
| 487 | | DEVCB_NULL
|
| 488 | | };
|
| 489 | | |
| 490 | | /* Intel 8251A Interface */
|
| 491 | | |
| 492 | | static WRITE_LINE_DEVICE_HANDLER( rxrdy_w )
|
| 493 | | {
|
| 494 | | tandy2k_state *driver_state = (tandy2k_state *)device->machine->driver_data;
|
| 495 | | |
| 496 | | driver_state->rxrdy = state;
|
| 497 | | pic8259_ir2_w(driver_state->pic0, driver_state->rxrdy | driver_state->txrdy);
|
| 498 | | }
|
| 499 | | |
| 500 | | static WRITE_LINE_DEVICE_HANDLER( txrdy_w )
|
| 501 | | {
|
| 502 | | tandy2k_state *driver_state = (tandy2k_state *)device->machine->driver_data;
|
| 503 | | |
| 504 | | driver_state->txrdy = state;
|
| 505 | | pic8259_ir2_w(driver_state->pic0, driver_state->rxrdy | driver_state->txrdy);
|
| 506 | | }
|
| 507 | | |
| 508 | | static const msm8251_interface i8251_intf =
|
| 509 | | {
|
| 510 | | txrdy_w,
|
| 511 | | NULL,
|
| 512 | | rxrdy_w
|
| 513 | | };
|
| 514 | | |
| 515 | | /* Intel 8253 Interface */
|
| 516 | | |
| 517 | | static WRITE_LINE_DEVICE_HANDLER( outspkr_w )
|
| 518 | | {
|
| 519 | | tandy2k_state *driver_state = (tandy2k_state *)device->machine->driver_data;
|
| 520 | | |
| 521 | | driver_state->outspkr = state;
|
| 522 | | speaker_update(driver_state);
|
| 523 | | }
|
| 524 | | |
| 525 | | static WRITE_LINE_DEVICE_HANDLER( intbrclk_w )
|
| 526 | | {
|
| 527 | | tandy2k_state *driver_state = (tandy2k_state *)device->machine->driver_data;
|
| 528 | | |
| 529 | | if (!driver_state->extclk && state)
|
| 530 | | {
|
| 531 | | msm8251_transmit_clock(driver_state->uart);
|
| 532 | | msm8251_receive_clock(driver_state->uart);
|
| 533 | | }
|
| 534 | | }
|
| 535 | | |
| 536 | | static WRITE_LINE_DEVICE_HANDLER( rfrqpulse_w )
|
| 537 | | {
|
| 538 | | }
|
| 539 | | |
| 540 | | static const struct pit8253_config i8253_intf =
|
| 541 | | {
|
| 542 | | {
|
| 543 | | {
|
| 544 | | XTAL_16MHz/16,
|
| 545 | | DEVCB_NULL,
|
| 546 | | DEVCB_LINE(outspkr_w)
|
| 547 | | }, {
|
| 548 | | XTAL_16MHz/8,
|
| 549 | | DEVCB_NULL,
|
| 550 | | DEVCB_LINE(intbrclk_w)
|
| 551 | | }, {
|
| 552 | | XTAL_16MHz/8,
|
| 553 | | DEVCB_NULL,
|
| 554 | | DEVCB_LINE(rfrqpulse_w)
|
| 555 | | }
|
| 556 | | }
|
| 557 | | };
|
| 558 | | |
| 559 | | /* Intel 8255A Interface */
|
| 560 | | |
| 561 | | enum
|
| 562 | | {
|
| 563 | | LPINEN = 0,
|
| 564 | | KBDINEN,
|
| 565 | | PORTINEN
|
| 566 | | };
|
| 567 | | |
| 568 | | static READ8_DEVICE_HANDLER( ppi_pb_r )
|
| 569 | | {
|
| 570 | | /*
|
| 571 | | |
| 572 | | bit signal description
|
| 573 | | |
| 574 | | 0 LPRIN0 auxiliary input 0
|
| 575 | | 1 LPRIN1 auxiliary input 1
|
| 576 | | 2 LPRIN2 auxiliary input 2
|
| 577 | | 3 _LPRACK acknowledge
|
| 578 | | 4 _LPRFLT fault
|
| 579 | | 5 _LPRSEL select
|
| 580 | | 6 LPRPAEM paper empty
|
| 581 | | 7 LPRBSY busy
|
| 582 | | |
| 583 | | */
|
| 584 | | |
| 585 | | tandy2k_state *state = (tandy2k_state *)device->machine->driver_data;
|
| 586 | | |
| 587 | | UINT8 data = 0;
|
| 588 | | |
| 589 | | switch (state->pb_sel)
|
| 590 | | {
|
| 591 | | case LPINEN:
|
| 592 | | /* printer acknowledge */
|
| 593 | | data |= centronics_ack_r(state->centronics) << 3;
|
| 594 | | |
| 595 | | /* printer fault */
|
| 596 | | data |= centronics_fault_r(state->centronics) << 4;
|
| 597 | | |
| 598 | | /* printer select */
|
| 599 | | data |= centronics_vcc_r(state->centronics) << 5;
|
| 600 | | |
| 601 | | /* paper empty */
|
| 602 | | data |= centronics_pe_r(state->centronics) << 6;
|
| 603 | | |
| 604 | | /* printer busy */
|
| 605 | | data |= centronics_busy_r(state->centronics) << 7;
|
| 606 | | break;
|
| 607 | | |
| 608 | | case KBDINEN:
|
| 609 | | /* keyboard data */
|
| 610 | | break;
|
| 611 | | |
| 612 | | case PORTINEN:
|
| 613 | | /* PCB revision */
|
| 614 | | data = 0x03;
|
| 615 | | break;
|
| 616 | | }
|
| 617 | | |
| 618 | | return data;
|
| 619 | | }
|
| 620 | | |
| 621 | | static WRITE8_DEVICE_HANDLER( ppi_pc_w )
|
| 622 | | {
|
| 623 | | /*
|
| 624 | | |
| 625 | | bit signal description
|
| 626 | | |
| 627 | | 0 port A direction
|
| 628 | | 1 port B input select bit 0
|
| 629 | | 2 port B input select bit 1
|
| 630 | | 3 LPRINT13 interrupt
|
| 631 | | 4 STROBE IN
|
| 632 | | 5 INBUFFULL
|
| 633 | | 6 _LPRACK
|
| 634 | | 7 _LPRDATSTB
|
| 635 | | |
| 636 | | */
|
| 637 | | |
| 638 | | tandy2k_state *state = (tandy2k_state *)device->machine->driver_data;
|
| 639 | | |
| 640 | | /* input select */
|
| 641 | | state->pb_sel = (data >> 1) & 0x03;
|
| 642 | | |
| 643 | | /* interrupt */
|
| 644 | | pic8259_ir3_w(state->pic1, BIT(data, 3));
|
| 645 | | |
| 646 | | /* printer strobe */
|
| 647 | | centronics_strobe_w(state->centronics, BIT(data, 7));
|
| 648 | | }
|
| 649 | | |
| 650 | | static I8255A_INTERFACE( i8255_intf )
|
| 651 | | {
|
| 652 | | DEVCB_NULL, // Port A read
|
| 653 | | DEVCB_HANDLER(ppi_pb_r), // Port B write
|
| 654 | | DEVCB_NULL, // Port C read
|
| 655 | | DEVCB_DEVICE_HANDLER(CENTRONICS_TAG, centronics_data_w), /* port A write callback */
|
| 656 | | DEVCB_NULL, // Port B write
|
| 657 | | DEVCB_HANDLER(ppi_pc_w) // Port C write
|
| 658 | | };
|
| 659 | | |
| 660 | | /* Intel 8259 Interfaces */
|
| 661 | | |
| 662 | | /*
|
| 663 | | |
| 664 | | IR0 MEMINT00
|
| 665 | | IR1 TMOINT01
|
| 666 | | IR2 SERINT02
|
| 667 | | IR3 BUSINT03
|
| 668 | | IR4 FLDINT04
|
| 669 | | IR5 BUSINT05
|
| 670 | | IR6 HDCINT06
|
| 671 | | IR7 BUSINT07
|
| 672 | | |
| 673 | | */
|
| 674 | | |
| 675 | | static const struct pic8259_interface i8259_0_intf =
|
| 676 | | {
|
| 677 | | DEVCB_CPU_INPUT_LINE(I80186_TAG, 0)
|
| 678 | | };
|
| 679 | | |
| 680 | | /*
|
| 681 | | |
| 682 | | IR0 KBDINT10
|
| 683 | | IR1 VIDINT11
|
| 684 | | IR2 RATINT12
|
| 685 | | IR3 LPRINT13
|
| 686 | | IR4 MCPINT14
|
| 687 | | IR5 MEMINT15
|
| 688 | | IR6 DMEINT16
|
| 689 | | IR7 BUSINT17
|
| 690 | | |
| 691 | | */
|
| 692 | | |
| 693 | | static const struct pic8259_interface i8259_1_intf =
|
| 694 | | {
|
| 695 | | /* TODO: INT1 is not implemented in the 80186 core */
|
| 696 | | DEVCB_CPU_INPUT_LINE(I80186_TAG, 1)
|
| 697 | | };
|
| 698 | | |
| 699 | | /* Floppy Configuration */
|
| 700 | | |
| 701 | | static const floppy_config tandy2k_floppy_config =
|
| 702 | | {
|
| 703 | | DEVCB_NULL,
|
| 704 | | DEVCB_NULL,
|
| 705 | | DEVCB_NULL,
|
| 706 | | DEVCB_NULL,
|
| 707 | | DEVCB_NULL,
|
| 708 | | FLOPPY_DRIVE_DS_80,
|
| 709 | | FLOPPY_OPTIONS_NAME(default),
|
| 710 | | DO_NOT_KEEP_GEOMETRY
|
| 711 | | };
|
| 712 | | |
| 713 | | /* Intel 8272 Interface */
|
| 714 | | |
| 715 | | static UPD765_DMA_REQUEST( busdmarq0_w )
|
| 716 | | {
|
| 717 | | }
|
| 718 | | |
| 719 | | static const struct upd765_interface i8272_intf =
|
| 720 | | {
|
| 721 | | DEVCB_DEVICE_LINE(I8259A_0_TAG, pic8259_ir4_w),
|
| 722 | | busdmarq0_w,
|
| 723 | | NULL,
|
| 724 | | UPD765_RDY_PIN_CONNECTED,
|
| 725 | | { FLOPPY_0, FLOPPY_1, NULL, NULL }
|
| 726 | | };
|
| 727 | | |
| 728 | | /* Centronics Interface */
|
| 729 | | |
| 730 | | static const centronics_interface centronics_intf =
|
| 731 | | {
|
| 732 | | 0, /* is IBM PC? */
|
| 733 | | DEVCB_DEVICE_LINE(I8255A_TAG, i8255a_pc6_w), /* ACK output */
|
| 734 | | DEVCB_NULL, /* BUSY output */
|
| 735 | | DEVCB_NULL /* NOT BUSY output */
|
| 736 | | };
|
| 737 | | |
| 738 | | /* Machine Initialization */
|
| 739 | | |
| 740 | | static MACHINE_START( tandy2k )
|
| 741 | | {
|
| 742 | | tandy2k_state *state = (tandy2k_state *)machine->driver_data;
|
| 743 | | |
| 744 | | /* find devices */
|
| 745 | | state->uart = devtag_get_device(machine, I8251A_TAG);
|
| 746 | | state->pit = devtag_get_device(machine, I8253_TAG);
|
| 747 | | state->pic0 = devtag_get_device(machine, I8259A_0_TAG);
|
| 748 | | state->pic1 = devtag_get_device(machine, I8259A_1_TAG);
|
| 749 | | state->fdc = devtag_get_device(machine, I8272A_TAG);
|
| 750 | | state->speaker = devtag_get_device(machine, SPEAKER_TAG);
|
| 751 | | state->centronics = devtag_get_device(machine, CENTRONICS_TAG);
|
| 752 | | |
| 753 | | /* memory banking */
|
| 754 | | const address_space *program = cputag_get_address_space(machine, I80186_TAG, ADDRESS_SPACE_PROGRAM);
|
| 755 | | UINT8 *ram = messram_get_ptr(devtag_get_device(machine, "messram"));
|
| 756 | | int ram_size = messram_get_size(devtag_get_device(machine, "messram"));
|
| 757 | | |
| 758 | | memory_install_ram(program, 0x00000, ram_size - 1, 0, 0, ram);
|
| 759 | | |
| 760 | | /* patch out i186 relocation register check */
|
| 761 | | UINT8 *rom = memory_region(machine, I80186_TAG);
|
| 762 | | rom[0x1f16] = 0x90;
|
| 763 | | rom[0x1f17] = 0x90;
|
| 764 | | |
| 765 | | /* register for state saving */
|
| 766 | | // state_save_register_global(machine, state->);
|
| 767 | | }
|
| 768 | | |
| 769 | | static MACHINE_RESET( tandy2k )
|
| 770 | | {
|
| 771 | | }
|
| 772 | | |
| 773 | | /* Machine Driver */
|
| 774 | | |
| 775 | | static MACHINE_DRIVER_START( tandy2k )
|
| 776 | | MDRV_DRIVER_DATA(tandy2k_state)
|
| 777 | | |
| 778 | | /* basic machine hardware */
|
| 779 | | MDRV_CPU_ADD(I80186_TAG, I80186, XTAL_16MHz)
|
| 780 | | MDRV_CPU_PROGRAM_MAP(tandy2k_mem)
|
| 781 | | MDRV_CPU_IO_MAP(tandy2k_io)
|
| 782 | | |
| 783 | | // MDRV_CPU_ADD(I8048_TAG, I8048, 1000000) // ?
|
| 784 | | // MDRV_CPU_IO_MAP(keyboard_io)
|
| 785 | | |
| 786 | | MDRV_MACHINE_START(tandy2k)
|
| 787 | | MDRV_MACHINE_RESET(tandy2k)
|
| 788 | | |
| 789 | | /* video hardware */
|
| 790 | | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
|
| 791 | | MDRV_SCREEN_REFRESH_RATE(50)
|
| 792 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
| 793 | | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
| 794 | | MDRV_SCREEN_SIZE(640, 480)
|
| 795 | | MDRV_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
|
| 796 | | |
| 797 | | MDRV_PALETTE_LENGTH(2)
|
| 798 | | MDRV_PALETTE_INIT(black_and_white)
|
| 799 | | MDRV_VIDEO_START(tandy2k)
|
| 800 | | MDRV_VIDEO_UPDATE(tandy2k)
|
| 801 | | MDRV_CRT9007_ADD(CRT9007_TAG, XTAL_16MHz*28/16, crt9007_intf)
|
| 802 | | |
| 803 | | /* sound hardware */
|
| 804 | | MDRV_SPEAKER_STANDARD_MONO("mono")
|
| 805 | | MDRV_SOUND_ADD(SPEAKER_TAG, SPEAKER, 0)
|
| 806 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
| 807 | | |
| 808 | | /* devices */
|
| 809 | | MDRV_I8255A_ADD(I8255A_TAG, i8255_intf)
|
| 810 | | MDRV_MSM8251_ADD(I8251A_TAG, i8251_intf)
|
| 811 | | MDRV_PIT8253_ADD(I8253_TAG, i8253_intf)
|
| 812 | | MDRV_PIC8259_ADD(I8259A_0_TAG, i8259_0_intf)
|
| 813 | | MDRV_PIC8259_ADD(I8259A_1_TAG, i8259_1_intf)
|
| 814 | | MDRV_UPD765A_ADD(I8272A_TAG, i8272_intf)
|
| 815 | | MDRV_FLOPPY_2_DRIVES_ADD(tandy2k_floppy_config)
|
| 816 | | MDRV_CENTRONICS_ADD(CENTRONICS_TAG, standard_centronics)
|
| 817 | | |
| 818 | | /* internal ram */
|
| 819 | | MDRV_RAM_ADD("messram")
|
| 820 | | MDRV_RAM_DEFAULT_SIZE("128K")
|
| 821 | | MDRV_RAM_EXTRA_OPTIONS("256K,384K,512K,640K,768K,896K")
|
| 822 | | MACHINE_DRIVER_END
|
| 823 | | |
| 824 | | static MACHINE_DRIVER_START( tandy2k_hd )
|
| 825 | | MDRV_IMPORT_FROM(tandy2k)
|
| 826 | | |
| 827 | | /* basic machine hardware */
|
| 828 | | MDRV_CPU_MODIFY(I80186_TAG)
|
| 829 | | MDRV_CPU_IO_MAP(tandy2k_hd_io)
|
| 830 | | |
| 831 | | /* Tandon TM502 hard disk */
|
| 832 | | //MDRV_WD1010_ADD(WD1010_TAG, wd1010_intf)
|
| 833 | | MACHINE_DRIVER_END
|
| 834 | | |
| 835 | | /* ROMs */
|
| 836 | | |
| 837 | | ROM_START( tandy2k )
|
| 838 | | ROM_REGION( 0x2000, I80186_TAG, 0 )
|
| 839 | | ROM_LOAD16_BYTE( "484a00.u48", 0x0000, 0x1000, CRC(a5ee3e90) SHA1(4b1f404a4337c67065dd272d62ff88dcdee5e34b) )
|
| 840 | | ROM_LOAD16_BYTE( "474600.u47", 0x0001, 0x1000, CRC(345701c5) SHA1(a775cbfa110b7a88f32834aaa2a9b868cbeed25b) )
|
| 841 | | |
| 842 | | ROM_REGION( 0x400, I8048_TAG, 0 )
|
| 843 | | ROM_LOAD( "keyboard.m1", 0x0000, 0x0400, NO_DUMP )
|
| 844 | | ROM_END
|
| 845 | | |
| 846 | | #define rom_tandy2khd rom_tandy2k
|
| 847 | | |
| 848 | | /* System Drivers */
|
| 849 | | |
| 850 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
| 851 | | COMP( 1983, tandy2k, 0, 0, tandy2k, tandy2k, 0, "Tandy Radio Shack", "Tandy 2000", GAME_NOT_WORKING)
|
| 852 | | COMP( 1983, tandy2khd, tandy2k, 0, tandy2k_hd, tandy2k, 0, "Tandy Radio Shack", "Tandy 2000HD", GAME_NOT_WORKING)
|
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Tandy 2000 |
| 4 | |
| 5 | Skeleton driver. |
| 6 | |
| 7 | ****************************************************************************/ |
| 8 | |
| 9 | /* |
| 10 | |
| 11 | TODO: |
| 12 | |
| 13 | - 80186 |
| 14 | - CRT9007 |
| 15 | - keyboard ROM |
| 16 | - hires graphics board |
| 17 | - floppy 720K DSQD |
| 18 | - DMA |
| 19 | - WD1010 |
| 20 | - hard disk |
| 21 | - mouse |
| 22 | - save state |
| 23 | |
| 24 | */ |
| 25 | |
| 26 | #include "emu.h" |
| 27 | #include "includes/tandy2k.h" |
| 28 | #include "cpu/i86/i86.h" |
| 29 | #include "cpu/mcs48/mcs48.h" |
| 30 | #include "devices/flopdrv.h" |
| 31 | #include "devices/messram.h" |
| 32 | #include "machine/ctronics.h" |
| 33 | #include "machine/i8255a.h" |
| 34 | #include "machine/msm8251.h" |
| 35 | #include "machine/pit8253.h" |
| 36 | #include "machine/pic8259.h" |
| 37 | #include "machine/upd765.h" |
| 38 | #include "sound/speaker.h" |
| 39 | #include "video/crt9007.h" |
| 40 | |
| 41 | /* Read/Write Handlers */ |
| 42 | |
| 43 | static void speaker_update(tandy2k_state *state) |
| 44 | { |
| 45 | int level = !(state->spkrdata & state->outspkr); |
| 46 | |
| 47 | speaker_level_w(state->speaker, level); |
| 48 | } |
| 49 | |
| 50 | static READ8_HANDLER( enable_r ) |
| 51 | { |
| 52 | /* |
| 53 | |
| 54 | bit signal description |
| 55 | |
| 56 | 0 RS-232 ring indicator |
| 57 | 1 RS-232 carrier detect |
| 58 | 2 |
| 59 | 3 |
| 60 | 4 |
| 61 | 5 |
| 62 | 6 |
| 63 | 7 _ACLOW |
| 64 | |
| 65 | */ |
| 66 | |
| 67 | return 0x80; |
| 68 | } |
| 69 | |
| 70 | static WRITE8_HANDLER( enable_w ) |
| 71 | { |
| 72 | /* |
| 73 | |
| 74 | bit signal description |
| 75 | |
| 76 | 0 KBEN keyboard enable |
| 77 | 1 EXTCLK external baud rate clock |
| 78 | 2 SPKRGATE enable periodic speaker output |
| 79 | 3 SPKRDATA direct output to speaker |
| 80 | 4 RFRQGATE enable refresh and baud rate clocks |
| 81 | 5 _FDCRESET reset 8272 |
| 82 | 6 TMRIN0 enable 80186 timer 0 |
| 83 | 7 TMRIN1 enable 80186 timer 1 |
| 84 | |
| 85 | */ |
| 86 | |
| 87 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 88 | |
| 89 | /* keyboard enable */ |
| 90 | state->kben = BIT(data, 0); |
| 91 | |
| 92 | /* external baud rate clock */ |
| 93 | state->extclk = BIT(data, 1); |
| 94 | |
| 95 | /* speaker gate */ |
| 96 | pit8253_gate0_w(state->pit, BIT(data, 2)); |
| 97 | |
| 98 | /* speaker data */ |
| 99 | state->spkrdata = BIT(data, 3); |
| 100 | speaker_update(state); |
| 101 | |
| 102 | /* refresh and baud rate clocks */ |
| 103 | pit8253_gate1_w(state->pit, BIT(data, 4)); |
| 104 | pit8253_gate2_w(state->pit, BIT(data, 4)); |
| 105 | |
| 106 | /* FDC reset */ |
| 107 | upd765_reset_w(state->fdc, BIT(data, 5)); |
| 108 | |
| 109 | /* TODO timer 0 enable */ |
| 110 | |
| 111 | /* TODO timer 1 enable */ |
| 112 | } |
| 113 | |
| 114 | static WRITE8_HANDLER( dma_mux_w ) |
| 115 | { |
| 116 | /* |
| 117 | |
| 118 | bit description |
| 119 | |
| 120 | 0 DMA channel 0 enable |
| 121 | 1 DMA channel 1 enable |
| 122 | 2 DMA channel 2 enable |
| 123 | 3 DMA channel 3 enable |
| 124 | 4 DMA channel 0 select |
| 125 | 5 DMA channel 1 select |
| 126 | 6 DMA channel 2 select |
| 127 | 7 DMA channel 3 select |
| 128 | |
| 129 | */ |
| 130 | } |
| 131 | |
| 132 | static READ8_DEVICE_HANDLER( fldtc_r ) |
| 133 | { |
| 134 | upd765_tc_w(device, 1); |
| 135 | upd765_tc_w(device, 0); |
| 136 | |
| 137 | return 0; |
| 138 | } |
| 139 | |
| 140 | static WRITE8_DEVICE_HANDLER( fldtc_w ) |
| 141 | { |
| 142 | upd765_tc_w(device, 1); |
| 143 | upd765_tc_w(device, 0); |
| 144 | } |
| 145 | |
| 146 | static WRITE8_HANDLER( addr_ctrl_w ) |
| 147 | { |
| 148 | /* |
| 149 | |
| 150 | bit signal description |
| 151 | |
| 152 | 8 A15 A15 of video access |
| 153 | 9 A16 A16 of video access |
| 154 | 10 A17 A17 of video access |
| 155 | 11 A18 A18 of video access |
| 156 | 12 A19 A19 of video access |
| 157 | 13 CLKSPD clock speed (0 = 22.4 MHz, 1 = 28 MHz) |
| 158 | 14 CLKCNT dots/char (0 = 10 [800x400], 1 = 8 [640x400]) |
| 159 | 15 VIDOUTS selects the video source for display on monochrome monitor |
| 160 | |
| 161 | */ |
| 162 | |
| 163 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 164 | |
| 165 | /* video access */ |
| 166 | state->vram_base = data << 15; |
| 167 | |
| 168 | /* video clock speed */ |
| 169 | crt9007_set_clock(state->vpac, BIT(data, 5) ? XTAL_16MHz*28/16 : XTAL_16MHz*28/20); |
| 170 | |
| 171 | /* dots per char */ |
| 172 | crt9007_set_hpixels_per_column(state->vpac, BIT(data, 6) ? 8 : 10); |
| 173 | |
| 174 | /* video source select */ |
| 175 | state->vidouts = BIT(data, 7); |
| 176 | |
| 177 | logerror("Address Control %02x\n", data); |
| 178 | } |
| 179 | |
| 180 | static READ8_HANDLER( keyboard_x0_r ) |
| 181 | { |
| 182 | /* |
| 183 | |
| 184 | bit description |
| 185 | |
| 186 | 0 X0 |
| 187 | 1 X1 |
| 188 | 2 X2 |
| 189 | 3 X3 |
| 190 | 4 X4 |
| 191 | 5 X5 |
| 192 | 6 X6 |
| 193 | 7 X7 |
| 194 | |
| 195 | */ |
| 196 | |
| 197 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 198 | |
| 199 | UINT8 data = 0xff; |
| 200 | |
| 201 | if (!BIT(state->keylatch, 0)) data &= input_port_read(space->machine, "Y0"); |
| 202 | if (!BIT(state->keylatch, 1)) data &= input_port_read(space->machine, "Y1"); |
| 203 | if (!BIT(state->keylatch, 2)) data &= input_port_read(space->machine, "Y2"); |
| 204 | if (!BIT(state->keylatch, 3)) data &= input_port_read(space->machine, "Y3"); |
| 205 | if (!BIT(state->keylatch, 4)) data &= input_port_read(space->machine, "Y4"); |
| 206 | if (!BIT(state->keylatch, 5)) data &= input_port_read(space->machine, "Y5"); |
| 207 | if (!BIT(state->keylatch, 6)) data &= input_port_read(space->machine, "Y6"); |
| 208 | if (!BIT(state->keylatch, 7)) data &= input_port_read(space->machine, "Y7"); |
| 209 | if (!BIT(state->keylatch, 8)) data &= input_port_read(space->machine, "Y8"); |
| 210 | if (!BIT(state->keylatch, 9)) data &= input_port_read(space->machine, "Y9"); |
| 211 | if (!BIT(state->keylatch, 10)) data &= input_port_read(space->machine, "Y10"); |
| 212 | if (!BIT(state->keylatch, 11)) data &= input_port_read(space->machine, "Y11"); |
| 213 | |
| 214 | return ~data; |
| 215 | } |
| 216 | |
| 217 | static WRITE8_HANDLER( keyboard_y0_w ) |
| 218 | { |
| 219 | /* |
| 220 | |
| 221 | bit description |
| 222 | |
| 223 | 0 Y0 |
| 224 | 1 Y1 |
| 225 | 2 Y2 |
| 226 | 3 Y3 |
| 227 | 4 Y4 |
| 228 | 5 Y5 |
| 229 | 6 Y6 |
| 230 | 7 Y7 |
| 231 | |
| 232 | */ |
| 233 | |
| 234 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 235 | |
| 236 | /* keyboard row select */ |
| 237 | state->keylatch = (state->keylatch & 0xff00) | data; |
| 238 | } |
| 239 | |
| 240 | static WRITE8_HANDLER( keyboard_y8_w ) |
| 241 | { |
| 242 | /* |
| 243 | |
| 244 | bit description |
| 245 | |
| 246 | 0 Y8 |
| 247 | 1 Y9 |
| 248 | 2 Y10 |
| 249 | 3 Y11 |
| 250 | 4 LED 2 |
| 251 | 5 LED 1 |
| 252 | 6 |
| 253 | 7 |
| 254 | |
| 255 | */ |
| 256 | |
| 257 | tandy2k_state *state = (tandy2k_state *)space->machine->driver_data; |
| 258 | |
| 259 | /* keyboard row select */ |
| 260 | state->keylatch = ((data & 0x0f) << 8) | (state->keylatch & 0xff); |
| 261 | } |
| 262 | |
| 263 | /* Memory Maps */ |
| 264 | |
| 265 | static ADDRESS_MAP_START( tandy2k_mem, ADDRESS_SPACE_PROGRAM, 16 ) |
| 266 | ADDRESS_MAP_UNMAP_HIGH |
| 267 | // AM_RANGE(0x00000, 0xdffff) AM_RAM |
| 268 | // AM_RANGE(0xe0000, 0xf7fff) AM_RAM // hires graphics |
| 269 | AM_RANGE(0xf8000, 0xfbfff) AM_RAM AM_BASE_MEMBER(tandy2k_state, char_ram) |
| 270 | AM_RANGE(0xfc000, 0xfdfff) AM_MIRROR(0x2000) AM_ROM AM_REGION(I80186_TAG, 0) |
| 271 | ADDRESS_MAP_END |
| 272 | |
| 273 | static ADDRESS_MAP_START( tandy2k_io, ADDRESS_SPACE_IO, 16 ) |
| 274 | ADDRESS_MAP_UNMAP_HIGH |
| 275 | AM_RANGE(0x00000, 0x00001) AM_READWRITE8(enable_r, enable_w, 0x00ff) |
| 276 | AM_RANGE(0x00002, 0x00003) AM_WRITE8(dma_mux_w, 0x00ff) |
| 277 | AM_RANGE(0x00004, 0x00005) AM_DEVREADWRITE8(I8272A_TAG, fldtc_r, fldtc_w, 0x00ff) |
| 278 | AM_RANGE(0x00010, 0x00013) AM_DEVREADWRITE8(I8251A_TAG, msm8251_data_r, msm8251_data_w, 0x00ff) |
| 279 | AM_RANGE(0x00030, 0x00031) AM_DEVREAD8(I8272A_TAG, upd765_status_r, 0x00ff) |
| 280 | AM_RANGE(0x00032, 0x00033) AM_DEVREADWRITE8(I8272A_TAG, upd765_data_r, upd765_data_w, 0x00ff) |
| 281 | AM_RANGE(0x00040, 0x00047) AM_DEVREADWRITE8(I8253_TAG, pit8253_r, pit8253_w, 0x00ff) |
| 282 | AM_RANGE(0x00050, 0x00057) AM_DEVREADWRITE8(I8255A_TAG, i8255a_r, i8255a_w, 0x00ff) |
| 283 | AM_RANGE(0x00060, 0x00063) AM_DEVREADWRITE8(I8259A_0_TAG, pic8259_r, pic8259_w, 0x00ff) |
| 284 | AM_RANGE(0x00070, 0x00073) AM_DEVREADWRITE8(I8259A_1_TAG, pic8259_r, pic8259_w, 0x00ff) |
| 285 | AM_RANGE(0x00080, 0x00081) AM_DEVREADWRITE8(I8272A_TAG, upd765_dack_r, upd765_dack_w, 0x00ff) |
| 286 | AM_RANGE(0x00100, 0x0017f) AM_DEVREADWRITE8(CRT9007_TAG, crt9007_r, crt9007_w, 0x00ff) |
| 287 | AM_RANGE(0x00100, 0x0017f) AM_WRITE8(addr_ctrl_w, 0xff00) |
| 288 | // AM_RANGE(0x00180, 0x00180) AM_READ8(hires_status_r, 0x00ff) |
| 289 | // AM_RANGE(0x00180, 0x001bf) AM_WRITE(hires_palette_w) |
| 290 | // AM_RANGE(0x001a0, 0x001a0) AM_READ8(hires_plane_w, 0x00ff) |
| 291 | // AM_RANGE(0x0ff00, 0x0ffff) AM_READWRITE(i186_internal_port_r, i186_internal_port_w) |
| 292 | ADDRESS_MAP_END |
| 293 | |
| 294 | static ADDRESS_MAP_START( tandy2k_hd_io, ADDRESS_SPACE_IO, 16 ) |
| 295 | AM_IMPORT_FROM(tandy2k_io) |
| 296 | // AM_RANGE(0x000e0, 0x000ff) AM_WRITE8(hdc_dack_w, 0x00ff) |
| 297 | // AM_RANGE(0x0026c, 0x0026d) AM_DEVREADWRITE8(WD1010_TAG, hdc_reset_r, hdc_reset_w, 0x00ff) |
| 298 | // AM_RANGE(0x0026e, 0x0027f) AM_DEVREADWRITE8(WD1010_TAG, wd1010_r, wd1010_w, 0x00ff) |
| 299 | ADDRESS_MAP_END |
| 300 | |
| 301 | static ADDRESS_MAP_START( keyboard_io, ADDRESS_SPACE_IO, 8 ) |
| 302 | AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(keyboard_y0_w) |
| 303 | AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(keyboard_y8_w) |
| 304 | AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READ(keyboard_x0_r) |
| 305 | ADDRESS_MAP_END |
| 306 | |
| 307 | /* Input Ports */ |
| 308 | |
| 309 | static INPUT_PORTS_START( tandy2k ) |
| 310 | PORT_START("ROW0") |
| 311 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 312 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 313 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 314 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 315 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 316 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 317 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 318 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 319 | |
| 320 | PORT_START("ROW1") |
| 321 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 322 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 323 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 324 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 325 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 326 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 327 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 328 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 329 | |
| 330 | PORT_START("ROW2") |
| 331 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 332 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 333 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 334 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 335 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 336 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 337 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 338 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 339 | |
| 340 | PORT_START("ROW3") |
| 341 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 342 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 343 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 344 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 345 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 346 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 347 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 348 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 349 | |
| 350 | PORT_START("ROW4") |
| 351 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 352 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 353 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 354 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 355 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 356 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 357 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 358 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 359 | |
| 360 | PORT_START("ROW5") |
| 361 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 362 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 363 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 364 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 365 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 366 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 367 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 368 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 369 | |
| 370 | PORT_START("ROW6") |
| 371 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 372 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 373 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 374 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 375 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 376 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 377 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 378 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 379 | |
| 380 | PORT_START("ROW7") |
| 381 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 382 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 383 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 384 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 385 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 386 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 387 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 388 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 389 | |
| 390 | PORT_START("ROW8") |
| 391 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 392 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 393 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 394 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 395 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 396 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 397 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 398 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 399 | |
| 400 | PORT_START("ROW9") |
| 401 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 402 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 403 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 404 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 405 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 406 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 407 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 408 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 409 | |
| 410 | PORT_START("ROW10") |
| 411 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 412 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 413 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 414 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 415 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 416 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 417 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 418 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 419 | |
| 420 | PORT_START("ROW11") |
| 421 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 422 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 423 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 424 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 425 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 426 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 427 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 428 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 429 | INPUT_PORTS_END |
| 430 | |
| 431 | /* Video */ |
| 432 | |
| 433 | static VIDEO_START( tandy2k ) |
| 434 | { |
| 435 | tandy2k_state *state = (tandy2k_state *)machine->driver_data; |
| 436 | |
| 437 | /* find devices */ |
| 438 | state->vpac = devtag_get_device(machine, CRT9007_TAG); |
| 439 | } |
| 440 | |
| 441 | static VIDEO_UPDATE( tandy2k ) |
| 442 | { |
| 443 | tandy2k_state *state = (tandy2k_state *)screen->machine->driver_data; |
| 444 | |
| 445 | //if (state->vidouts) |
| 446 | { |
| 447 | crt9007_update(state->vpac, bitmap, cliprect); |
| 448 | } |
| 449 | |
| 450 | return 0; |
| 451 | } |
| 452 | |
| 453 | static CRT9007_DRAW_SCANLINE( tandy2k_crt9007_display_pixels ) |
| 454 | { |
| 455 | tandy2k_state *state = (tandy2k_state *)device->machine->driver_data; |
| 456 | const address_space *program = cputag_get_address_space(device->machine, I80186_TAG, ADDRESS_SPACE_PROGRAM); |
| 457 | |
| 458 | for (int sx = 0; sx < x_count; sx++) |
| 459 | { |
| 460 | UINT32 videoram_addr = (state->vram_base | (va << 1)) + sx; |
| 461 | UINT8 videoram_data = memory_read_word(program, videoram_addr); |
| 462 | UINT16 charram_addr = (videoram_data << 4) | sl; |
| 463 | UINT8 data = state->char_ram[charram_addr] & 0xff; |
| 464 | |
| 465 | for (int bit = 0; bit < 10; bit++) |
| 466 | { |
| 467 | if (BIT(data, 7)) |
| 468 | { |
| 469 | *BITMAP_ADDR16(bitmap, y, x + (sx * 10) + bit) = 1; |
| 470 | } |
| 471 | |
| 472 | data <<= 1; |
| 473 | } |
| 474 | } |
| 475 | } |
| 476 | |
| 477 | static CRT9007_INTERFACE( crt9007_intf ) |
| 478 | { |
| 479 | SCREEN_TAG, |
| 480 | 10, |
| 481 | tandy2k_crt9007_display_pixels, |
| 482 | DEVCB_DEVICE_LINE(I8259A_1_TAG, pic8259_ir1_w), |
| 483 | DEVCB_NULL, |
| 484 | DEVCB_NULL, |
| 485 | DEVCB_NULL, |
| 486 | DEVCB_NULL, |
| 487 | DEVCB_NULL |
| 488 | }; |
| 489 | |
| 490 | /* Intel 8251A Interface */ |
| 491 | |
| 492 | static WRITE_LINE_DEVICE_HANDLER( rxrdy_w ) |
| 493 | { |
| 494 | tandy2k_state *driver_state = (tandy2k_state *)device->machine->driver_data; |
| 495 | |
| 496 | driver_state->rxrdy = state; |
| 497 | pic8259_ir2_w(driver_state->pic0, driver_state->rxrdy | driver_state->txrdy); |
| 498 | } |
| 499 | |
| 500 | static WRITE_LINE_DEVICE_HANDLER( txrdy_w ) |
| 501 | { |
| 502 | tandy2k_state *driver_state = (tandy2k_state *)device->machine->driver_data; |
| 503 | |
| 504 | driver_state->txrdy = state; |
| 505 | pic8259_ir2_w(driver_state->pic0, driver_state->rxrdy | driver_state->txrdy); |
| 506 | } |
| 507 | |
| 508 | static const msm8251_interface i8251_intf = |
| 509 | { |
| 510 | txrdy_w, |
| 511 | NULL, |
| 512 | rxrdy_w |
| 513 | }; |
| 514 | |
| 515 | /* Intel 8253 Interface */ |
| 516 | |
| 517 | static WRITE_LINE_DEVICE_HANDLER( outspkr_w ) |
| 518 | { |
| 519 | tandy2k_state *driver_state = (tandy2k_state *)device->machine->driver_data; |
| 520 | |
| 521 | driver_state->outspkr = state; |
| 522 | speaker_update(driver_state); |
| 523 | } |
| 524 | |
| 525 | static WRITE_LINE_DEVICE_HANDLER( intbrclk_w ) |
| 526 | { |
| 527 | tandy2k_state *driver_state = (tandy2k_state *)device->machine->driver_data; |
| 528 | |
| 529 | if (!driver_state->extclk && state) |
| 530 | { |
| 531 | msm8251_transmit_clock(driver_state->uart); |
| 532 | msm8251_receive_clock(driver_state->uart); |
| 533 | } |
| 534 | } |
| 535 | |
| 536 | static WRITE_LINE_DEVICE_HANDLER( rfrqpulse_w ) |
| 537 | { |
| 538 | } |
| 539 | |
| 540 | static const struct pit8253_config i8253_intf = |
| 541 | { |
| 542 | { |
| 543 | { |
| 544 | XTAL_16MHz/16, |
| 545 | DEVCB_NULL, |
| 546 | DEVCB_LINE(outspkr_w) |
| 547 | }, { |
| 548 | XTAL_16MHz/8, |
| 549 | DEVCB_NULL, |
| 550 | DEVCB_LINE(intbrclk_w) |
| 551 | }, { |
| 552 | XTAL_16MHz/8, |
| 553 | DEVCB_NULL, |
| 554 | DEVCB_LINE(rfrqpulse_w) |
| 555 | } |
| 556 | } |
| 557 | }; |
| 558 | |
| 559 | /* Intel 8255A Interface */ |
| 560 | |
| 561 | enum |
| 562 | { |
| 563 | LPINEN = 0, |
| 564 | KBDINEN, |
| 565 | PORTINEN |
| 566 | }; |
| 567 | |
| 568 | static READ8_DEVICE_HANDLER( ppi_pb_r ) |
| 569 | { |
| 570 | /* |
| 571 | |
| 572 | bit signal description |
| 573 | |
| 574 | 0 LPRIN0 auxiliary input 0 |
| 575 | 1 LPRIN1 auxiliary input 1 |
| 576 | 2 LPRIN2 auxiliary input 2 |
| 577 | 3 _LPRACK acknowledge |
| 578 | 4 _LPRFLT fault |
| 579 | 5 _LPRSEL select |
| 580 | 6 LPRPAEM paper empty |
| 581 | 7 LPRBSY busy |
| 582 | |
| 583 | */ |
| 584 | |
| 585 | tandy2k_state *state = (tandy2k_state *)device->machine->driver_data; |
| 586 | |
| 587 | UINT8 data = 0; |
| 588 | |
| 589 | switch (state->pb_sel) |
| 590 | { |
| 591 | case LPINEN: |
| 592 | /* printer acknowledge */ |
| 593 | data |= centronics_ack_r(state->centronics) << 3; |
| 594 | |
| 595 | /* printer fault */ |
| 596 | data |= centronics_fault_r(state->centronics) << 4; |
| 597 | |
| 598 | /* printer select */ |
| 599 | data |= centronics_vcc_r(state->centronics) << 5; |
| 600 | |
| 601 | /* paper empty */ |
| 602 | data |= centronics_pe_r(state->centronics) << 6; |
| 603 | |
| 604 | /* printer busy */ |
| 605 | data |= centronics_busy_r(state->centronics) << 7; |
| 606 | break; |
| 607 | |
| 608 | case KBDINEN: |
| 609 | /* keyboard data */ |
| 610 | break; |
| 611 | |
| 612 | case PORTINEN: |
| 613 | /* PCB revision */ |
| 614 | data = 0x03; |
| 615 | break; |
| 616 | } |
| 617 | |
| 618 | return data; |
| 619 | } |
| 620 | |
| 621 | static WRITE8_DEVICE_HANDLER( ppi_pc_w ) |
| 622 | { |
| 623 | /* |
| 624 | |
| 625 | bit signal description |
| 626 | |
| 627 | 0 port A direction |
| 628 | 1 port B input select bit 0 |
| 629 | 2 port B input select bit 1 |
| 630 | 3 LPRINT13 interrupt |
| 631 | 4 STROBE IN |
| 632 | 5 INBUFFULL |
| 633 | 6 _LPRACK |
| 634 | 7 _LPRDATSTB |
| 635 | |
| 636 | */ |
| 637 | |
| 638 | tandy2k_state *state = (tandy2k_state *)device->machine->driver_data; |
| 639 | |
| 640 | /* input select */ |
| 641 | state->pb_sel = (data >> 1) & 0x03; |
| 642 | |
| 643 | /* interrupt */ |
| 644 | pic8259_ir3_w(state->pic1, BIT(data, 3)); |
| 645 | |
| 646 | /* printer strobe */ |
| 647 | centronics_strobe_w(state->centronics, BIT(data, 7)); |
| 648 | } |
| 649 | |
| 650 | static I8255A_INTERFACE( i8255_intf ) |
| 651 | { |
| 652 | DEVCB_NULL, // Port A read |
| 653 | DEVCB_HANDLER(ppi_pb_r), // Port B write |
| 654 | DEVCB_NULL, // Port C read |
| 655 | DEVCB_DEVICE_HANDLER(CENTRONICS_TAG, centronics_data_w), /* port A write callback */ |
| 656 | DEVCB_NULL, // Port B write |
| 657 | DEVCB_HANDLER(ppi_pc_w) // Port C write |
| 658 | }; |
| 659 | |
| 660 | /* Intel 8259 Interfaces */ |
| 661 | |
| 662 | /* |
| 663 | |
| 664 | IR0 MEMINT00 |
| 665 | IR1 TMOINT01 |
| 666 | IR2 SERINT02 |
| 667 | IR3 BUSINT03 |
| 668 | IR4 FLDINT04 |
| 669 | IR5 BUSINT05 |
| 670 | IR6 HDCINT06 |
| 671 | IR7 BUSINT07 |
| 672 | |
| 673 | */ |
| 674 | |
| 675 | static const struct pic8259_interface i8259_0_intf = |
| 676 | { |
| 677 | DEVCB_CPU_INPUT_LINE(I80186_TAG, 0) |
| 678 | }; |
| 679 | |
| 680 | /* |
| 681 | |
| 682 | IR0 KBDINT10 |
| 683 | IR1 VIDINT11 |
| 684 | IR2 RATINT12 |
| 685 | IR3 LPRINT13 |
| 686 | IR4 MCPINT14 |
| 687 | IR5 MEMINT15 |
| 688 | IR6 DMEINT16 |
| 689 | IR7 BUSINT17 |
| 690 | |
| 691 | */ |
| 692 | |
| 693 | static const struct pic8259_interface i8259_1_intf = |
| 694 | { |
| 695 | /* TODO: INT1 is not implemented in the 80186 core */ |
| 696 | DEVCB_CPU_INPUT_LINE(I80186_TAG, 1) |
| 697 | }; |
| 698 | |
| 699 | /* Floppy Configuration */ |
| 700 | |
| 701 | static const floppy_config tandy2k_floppy_config = |
| 702 | { |
| 703 | DEVCB_NULL, |
| 704 | DEVCB_NULL, |
| 705 | DEVCB_NULL, |
| 706 | DEVCB_NULL, |
| 707 | DEVCB_NULL, |
| 708 | FLOPPY_DRIVE_DS_80, |
| 709 | FLOPPY_OPTIONS_NAME(default), |
| 710 | DO_NOT_KEEP_GEOMETRY |
| 711 | }; |
| 712 | |
| 713 | /* Intel 8272 Interface */ |
| 714 | |
| 715 | static UPD765_DMA_REQUEST( busdmarq0_w ) |
| 716 | { |
| 717 | } |
| 718 | |
| 719 | static const struct upd765_interface i8272_intf = |
| 720 | { |
| 721 | DEVCB_DEVICE_LINE(I8259A_0_TAG, pic8259_ir4_w), |
| 722 | busdmarq0_w, |
| 723 | NULL, |
| 724 | UPD765_RDY_PIN_CONNECTED, |
| 725 | { FLOPPY_0, FLOPPY_1, NULL, NULL } |
| 726 | }; |
| 727 | |
| 728 | /* Centronics Interface */ |
| 729 | |
| 730 | static const centronics_interface centronics_intf = |
| 731 | { |
| 732 | 0, /* is IBM PC? */ |
| 733 | DEVCB_DEVICE_LINE(I8255A_TAG, i8255a_pc6_w), /* ACK output */ |
| 734 | DEVCB_NULL, /* BUSY output */ |
| 735 | DEVCB_NULL /* NOT BUSY output */ |
| 736 | }; |
| 737 | |
| 738 | /* Machine Initialization */ |
| 739 | |
| 740 | static MACHINE_START( tandy2k ) |
| 741 | { |
| 742 | tandy2k_state *state = (tandy2k_state *)machine->driver_data; |
| 743 | |
| 744 | /* find devices */ |
| 745 | state->uart = devtag_get_device(machine, I8251A_TAG); |
| 746 | state->pit = devtag_get_device(machine, I8253_TAG); |
| 747 | state->pic0 = devtag_get_device(machine, I8259A_0_TAG); |
| 748 | state->pic1 = devtag_get_device(machine, I8259A_1_TAG); |
| 749 | state->fdc = devtag_get_device(machine, I8272A_TAG); |
| 750 | state->speaker = devtag_get_device(machine, SPEAKER_TAG); |
| 751 | state->centronics = devtag_get_device(machine, CENTRONICS_TAG); |
| 752 | |
| 753 | /* memory banking */ |
| 754 | const address_space *program = cputag_get_address_space(machine, I80186_TAG, ADDRESS_SPACE_PROGRAM); |
| 755 | UINT8 *ram = messram_get_ptr(devtag_get_device(machine, "messram")); |
| 756 | int ram_size = messram_get_size(devtag_get_device(machine, "messram")); |
| 757 | |
| 758 | memory_install_ram(program, 0x00000, ram_size - 1, 0, 0, ram); |
| 759 | |
| 760 | /* patch out i186 relocation register check */ |
| 761 | UINT8 *rom = memory_region(machine, I80186_TAG); |
| 762 | rom[0x1f16] = 0x90; |
| 763 | rom[0x1f17] = 0x90; |
| 764 | |
| 765 | /* register for state saving */ |
| 766 | // state_save_register_global(machine, state->); |
| 767 | } |
| 768 | |
| 769 | static MACHINE_RESET( tandy2k ) |
| 770 | { |
| 771 | } |
| 772 | |
| 773 | /* Machine Driver */ |
| 774 | |
| 775 | static MACHINE_DRIVER_START( tandy2k ) |
| 776 | MDRV_DRIVER_DATA(tandy2k_state) |
| 777 | |
| 778 | /* basic machine hardware */ |
| 779 | MDRV_CPU_ADD(I80186_TAG, I80186, XTAL_16MHz) |
| 780 | MDRV_CPU_PROGRAM_MAP(tandy2k_mem) |
| 781 | MDRV_CPU_IO_MAP(tandy2k_io) |
| 782 | |
| 783 | // MDRV_CPU_ADD(I8048_TAG, I8048, 1000000) // ? |
| 784 | // MDRV_CPU_IO_MAP(keyboard_io) |
| 785 | |
| 786 | MDRV_MACHINE_START(tandy2k) |
| 787 | MDRV_MACHINE_RESET(tandy2k) |
| 788 | |
| 789 | /* video hardware */ |
| 790 | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER) |
| 791 | MDRV_SCREEN_REFRESH_RATE(50) |
| 792 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 793 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 794 | MDRV_SCREEN_SIZE(640, 480) |
| 795 | MDRV_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1) |
| 796 | |
| 797 | MDRV_PALETTE_LENGTH(2) |
| 798 | MDRV_PALETTE_INIT(black_and_white) |
| 799 | MDRV_VIDEO_START(tandy2k) |
| 800 | MDRV_VIDEO_UPDATE(tandy2k) |
| 801 | MDRV_CRT9007_ADD(CRT9007_TAG, XTAL_16MHz*28/16, crt9007_intf) |
| 802 | |
| 803 | /* sound hardware */ |
| 804 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 805 | MDRV_SOUND_ADD(SPEAKER_TAG, SPEAKER, 0) |
| 806 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 807 | |
| 808 | /* devices */ |
| 809 | MDRV_I8255A_ADD(I8255A_TAG, i8255_intf) |
| 810 | MDRV_MSM8251_ADD(I8251A_TAG, i8251_intf) |
| 811 | MDRV_PIT8253_ADD(I8253_TAG, i8253_intf) |
| 812 | MDRV_PIC8259_ADD(I8259A_0_TAG, i8259_0_intf) |
| 813 | MDRV_PIC8259_ADD(I8259A_1_TAG, i8259_1_intf) |
| 814 | MDRV_UPD765A_ADD(I8272A_TAG, i8272_intf) |
| 815 | MDRV_FLOPPY_2_DRIVES_ADD(tandy2k_floppy_config) |
| 816 | MDRV_CENTRONICS_ADD(CENTRONICS_TAG, standard_centronics) |
| 817 | |
| 818 | /* internal ram */ |
| 819 | MDRV_RAM_ADD("messram") |
| 820 | MDRV_RAM_DEFAULT_SIZE("128K") |
| 821 | MDRV_RAM_EXTRA_OPTIONS("256K,384K,512K,640K,768K,896K") |
| 822 | MACHINE_DRIVER_END |
| 823 | |
| 824 | static MACHINE_DRIVER_START( tandy2k_hd ) |
| 825 | MDRV_IMPORT_FROM(tandy2k) |
| 826 | |
| 827 | /* basic machine hardware */ |
| 828 | MDRV_CPU_MODIFY(I80186_TAG) |
| 829 | MDRV_CPU_IO_MAP(tandy2k_hd_io) |
| 830 | |
| 831 | /* Tandon TM502 hard disk */ |
| 832 | //MDRV_WD1010_ADD(WD1010_TAG, wd1010_intf) |
| 833 | MACHINE_DRIVER_END |
| 834 | |
| 835 | /* ROMs */ |
| 836 | |
| 837 | ROM_START( tandy2k ) |
| 838 | ROM_REGION( 0x2000, I80186_TAG, 0 ) |
| 839 | ROM_LOAD16_BYTE( "484a00.u48", 0x0000, 0x1000, CRC(a5ee3e90) SHA1(4b1f404a4337c67065dd272d62ff88dcdee5e34b) ) |
| 840 | ROM_LOAD16_BYTE( "474600.u47", 0x0001, 0x1000, CRC(345701c5) SHA1(a775cbfa110b7a88f32834aaa2a9b868cbeed25b) ) |
| 841 | |
| 842 | ROM_REGION( 0x400, I8048_TAG, 0 ) |
| 843 | ROM_LOAD( "keyboard.m1", 0x0000, 0x0400, NO_DUMP ) |
| 844 | ROM_END |
| 845 | |
| 846 | #define rom_tandy2khd rom_tandy2k |
| 847 | |
| 848 | /* System Drivers */ |
| 849 | |
| 850 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 851 | COMP( 1983, tandy2k, 0, 0, tandy2k, tandy2k, 0, "Tandy Radio Shack", "Tandy 2000", GAME_NOT_WORKING) |
| 852 | COMP( 1983, tandy2khd, tandy2k, 0, tandy2k_hd, tandy2k, 0, "Tandy Radio Shack", "Tandy 2000HD", GAME_NOT_WORKING) |
src/mess/drivers/trs80m2.c
| r7571 | r7572 | |
| 1 | | /*
|
| 2 | | |
| 3 | | Tandy Radio Shack TRS-80 Model II/12/16/16B/6000
|
| 4 | | |
| 5 | | http://home.iae.nl/users/pb0aia/cm/modelii.html
|
| 6 | | |
| 7 | | */
|
| 8 | | |
| 9 | | /*
|
| 10 | | |
| 11 | | TODO:
|
| 12 | | |
| 13 | | - wd17xx.c thinks the drive is always ready
|
| 14 | | - keyboard CPU ROM
|
| 15 | | - keyboard layout
|
| 16 | | - graphics board
|
| 17 | | |
| 18 | | */
|
| 19 | | |
| 20 | | #include "emu.h"
|
| 21 | | #include "includes/trs80m2.h"
|
| 22 | | #include "cpu/z80/z80.h"
|
| 23 | | #include "cpu/z80/z80daisy.h"
|
| 24 | | #include "cpu/mcs48/mcs48.h"
|
| 25 | | #include "cpu/m68000/m68000.h"
|
| 26 | | #include "devices/flopdrv.h"
|
| 27 | | #include "devices/messram.h"
|
| 28 | | #include "machine/ctronics.h"
|
| 29 | | #include "machine/wd17xx.h"
|
| 30 | | #include "machine/z80ctc.h"
|
| 31 | | #include "machine/z80dma.h"
|
| 32 | | #include "machine/z80pio.h"
|
| 33 | | #include "machine/z80sio.h"
|
| 34 | | #include "video/mc6845.h"
|
| 35 | | |
| 36 | | /* Read/Write Handlers */
|
| 37 | | |
| 38 | | static WRITE8_DEVICE_HANDLER( drvslt_w )
|
| 39 | | {
|
| 40 | | /*
|
| 41 | | |
| 42 | | bit signal
|
| 43 | | |
| 44 | | 0 DS1
|
| 45 | | 1 DS2
|
| 46 | | 2 DS3
|
| 47 | | 3 DS4
|
| 48 | | 4
|
| 49 | | 5
|
| 50 | | 6 SDSEL
|
| 51 | | 7 FM/MFM
|
| 52 | | |
| 53 | | */
|
| 54 | | |
| 55 | | /* drive select */
|
| 56 | | if (!BIT(data, 0)) wd17xx_set_drive(device, 0);
|
| 57 | | if (!BIT(data, 1)) wd17xx_set_drive(device, 1);
|
| 58 | | if (!BIT(data, 2)) wd17xx_set_drive(device, 2);
|
| 59 | | if (!BIT(data, 3)) wd17xx_set_drive(device, 3);
|
| 60 | | |
| 61 | | /* side select */
|
| 62 | | wd17xx_set_side(device, !BIT(data, 6));
|
| 63 | | |
| 64 | | /* FM/MFM */
|
| 65 | | wd17xx_dden_w(device, BIT(data, 7));
|
| 66 | | }
|
| 67 | | |
| 68 | | static void bankswitch(running_machine *machine)
|
| 69 | | {
|
| 70 | | trs80m2_state *state = (trs80m2_state *)machine->driver_data;
|
| 71 | | |
| 72 | | const address_space *program = cputag_get_address_space(machine, Z80_TAG, ADDRESS_SPACE_PROGRAM);
|
| 73 | | running_device *messram = devtag_get_device(machine, "messram");
|
| 74 | | UINT8 *rom = memory_region(machine, Z80_TAG);
|
| 75 | | UINT8 *ram = messram_get_ptr(messram);
|
| 76 | | int last_page = (messram_get_size(messram) / 0x8000) - 1;
|
| 77 | | |
| 78 | | if (state->boot_rom)
|
| 79 | | {
|
| 80 | | /* enable BOOT ROM */
|
| 81 | | memory_install_rom(program, 0x0000, 0x07ff, 0, 0, rom);
|
| 82 | | memory_install_ram(program, 0x0800, 0x7fff, 0, 0, ram + 0x800);
|
| 83 | | }
|
| 84 | | else
|
| 85 | | {
|
| 86 | | /* enable RAM */
|
| 87 | | memory_install_ram(program, 0x0000, 0x7fff, 0, 0, ram);
|
| 88 | | }
|
| 89 | | |
| 90 | | if (state->bank > last_page)
|
| 91 | | {
|
| 92 | | memory_unmap_readwrite(program, 0x8000, 0xffff, 0, 0);
|
| 93 | | }
|
| 94 | | else
|
| 95 | | {
|
| 96 | | /* enable RAM */
|
| 97 | | memory_install_ram(program, 0x8000, 0xffff, 0, 0, ram + (state->bank * 0x8000));
|
| 98 | | }
|
| 99 | | |
| 100 | | if (state->msel)
|
| 101 | | {
|
| 102 | | /* enable video RAM */
|
| 103 | | memory_install_ram(program, 0xf800, 0xffff, 0, 0, state->video_ram);
|
| 104 | | }
|
| 105 | | }
|
| 106 | | |
| 107 | | static WRITE8_HANDLER( rom_enable_w )
|
| 108 | | {
|
| 109 | | /*
|
| 110 | | |
| 111 | | bit description
|
| 112 | | |
| 113 | | 0 BOOT ROM
|
| 114 | | 1
|
| 115 | | 2
|
| 116 | | 3
|
| 117 | | 4
|
| 118 | | 5
|
| 119 | | 6
|
| 120 | | 7
|
| 121 | | |
| 122 | | */
|
| 123 | | |
| 124 | | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data;
|
| 125 | | |
| 126 | | state->boot_rom = BIT(data, 0);
|
| 127 | | bankswitch(space->machine);
|
| 128 | | }
|
| 129 | | |
| 130 | | static READ8_HANDLER( keyboard_r )
|
| 131 | | {
|
| 132 | | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data;
|
| 133 | | |
| 134 | | /* clear keyboard interrupt */
|
| 135 | | state->kbirq = 1;
|
| 136 | | z80ctc_trg3_w(state->z80ctc, state->kbirq);
|
| 137 | | |
| 138 | | state->key_bit = 0;
|
| 139 | | |
| 140 | | return state->key_data;
|
| 141 | | }
|
| 142 | | |
| 143 | | static READ8_HANDLER( rtc_r )
|
| 144 | | {
|
| 145 | | /* clear RTC interrupt */
|
| 146 | | cputag_set_input_line(space->machine, Z80_TAG, INPUT_LINE_NMI, CLEAR_LINE);
|
| 147 | | |
| 148 | | return 0;
|
| 149 | | }
|
| 150 | | |
| 151 | | static READ8_HANDLER( nmi_r )
|
| 152 | | {
|
| 153 | | /*
|
| 154 | | |
| 155 | | bit signal description
|
| 156 | | |
| 157 | | 0
|
| 158 | | 1
|
| 159 | | 2
|
| 160 | | 3
|
| 161 | | 4 80/40 CHAR EN 80/40 character mode
|
| 162 | | 5 ENABLE RTC INT RTC interrupt enable
|
| 163 | | 6 DE display enabled
|
| 164 | | 7 KBIRQ keyboard interrupt
|
| 165 | | |
| 166 | | */
|
| 167 | | |
| 168 | | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data;
|
| 169 | | |
| 170 | | UINT8 data = 0;
|
| 171 | | |
| 172 | | /* 80/40 character mode*/
|
| 173 | | data |= state->_80_40_char_en << 4;
|
| 174 | | |
| 175 | | /* RTC interrupt enable */
|
| 176 | | data |= state->enable_rtc_int << 5;
|
| 177 | | |
| 178 | | /* display enabled */
|
| 179 | | data |= state->de << 6;
|
| 180 | | |
| 181 | | /* keyboard interrupt */
|
| 182 | | data |= state->kbirq << 7;
|
| 183 | | |
| 184 | | return data;
|
| 185 | | }
|
| 186 | | |
| 187 | | static WRITE8_HANDLER( nmi_w )
|
| 188 | | {
|
| 189 | | /*
|
| 190 | | |
| 191 | | bit signal description
|
| 192 | | |
| 193 | | 0 memory bank select bit 0
|
| 194 | | 1 memory bank select bit 1
|
| 195 | | 2 memory bank select bit 2
|
| 196 | | 3 memory bank select bit 3
|
| 197 | | 4 80/40 CHAR EN 80/40 character mode
|
| 198 | | 5 ENABLE RTC INT RTC interrupt enable
|
| 199 | | 6 BLNKVID video display enable
|
| 200 | | 7 video RAM enable
|
| 201 | | |
| 202 | | */
|
| 203 | | |
| 204 | | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data;
|
| 205 | | |
| 206 | | /* memory bank select */
|
| 207 | | state->bank = data & 0x0f;
|
| 208 | | |
| 209 | | /* 80/40 character mode */
|
| 210 | | state->_80_40_char_en = BIT(data, 4);
|
| 211 | | mc6845_set_clock(state->mc6845, state->_80_40_char_en ? XTAL_12_48MHz/16 : XTAL_12_48MHz/8);
|
| 212 | | |
| 213 | | /* RTC interrupt enable */
|
| 214 | | state->enable_rtc_int = BIT(data, 5);
|
| 215 | | |
| 216 | | if (state->enable_rtc_int && state->rtc_int)
|
| 217 | | {
|
| 218 | | /* trigger RTC interrupt */
|
| 219 | | cputag_set_input_line(space->machine, Z80_TAG, INPUT_LINE_NMI, ASSERT_LINE);
|
| 220 | | }
|
| 221 | | |
| 222 | | /* video display enable */
|
| 223 | | state->blnkvid = BIT(data, 6);
|
| 224 | | |
| 225 | | /* video RAM enable */
|
| 226 | | state->msel = BIT(data, 7);
|
| 227 | | bankswitch(space->machine);
|
| 228 | | }
|
| 229 | | |
| 230 | | static READ8_HANDLER( keyboard_busy_r )
|
| 231 | | {
|
| 232 | | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data;
|
| 233 | | |
| 234 | | return state->kbirq;
|
| 235 | | }
|
| 236 | | |
| 237 | | static READ8_HANDLER( keyboard_data_r )
|
| 238 | | {
|
| 239 | | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data;
|
| 240 | | |
| 241 | | static const char *const KEY_ROW[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7", "ROW8", "ROW9", "ROW10", "ROW11" };
|
| 242 | | |
| 243 | | return input_port_read(space->machine, KEY_ROW[state->key_latch]);
|
| 244 | | }
|
| 245 | | |
| 246 | | static WRITE8_HANDLER( keyboard_ctrl_w )
|
| 247 | | {
|
| 248 | | /*
|
| 249 | | |
| 250 | | bit description
|
| 251 | | |
| 252 | | 0 DATA
|
| 253 | | 1 CLOCK
|
| 254 | | 2 LED
|
| 255 | | 3
|
| 256 | | 4 LED
|
| 257 | | 5
|
| 258 | | 6
|
| 259 | | 7
|
| 260 | | |
| 261 | | */
|
| 262 | | |
| 263 | | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data;
|
| 264 | | |
| 265 | | int kbdata = BIT(data, 0);
|
| 266 | | int kbclk = BIT(data, 1);
|
| 267 | | |
| 268 | | if (state->key_bit == 8)
|
| 269 | | {
|
| 270 | | if (!state->kbdata && kbdata)
|
| 271 | | {
|
| 272 | | /* trigger keyboard interrupt */
|
| 273 | | state->kbirq = 0;
|
| 274 | | z80ctc_trg3_w(state->z80ctc, state->kbirq);
|
| 275 | | }
|
| 276 | | }
|
| 277 | | else
|
| 278 | | {
|
| 279 | | if (!state->kbclk && kbclk)
|
| 280 | | {
|
| 281 | | /* shift in keyboard data bit */
|
| 282 | | state->key_data <<= 1;
|
| 283 | | state->key_data |= kbdata;
|
| 284 | | state->key_bit++;
|
| 285 | | }
|
| 286 | | }
|
| 287 | | |
| 288 | | state->kbdata = kbdata;
|
| 289 | | state->kbclk = kbclk;
|
| 290 | | }
|
| 291 | | |
| 292 | | static WRITE8_HANDLER( keyboard_latch_w )
|
| 293 | | {
|
| 294 | | /*
|
| 295 | | |
| 296 | | bit description
|
| 297 | | |
| 298 | | 0 D
|
| 299 | | 1 C
|
| 300 | | 2 B
|
| 301 | | 3 A
|
| 302 | | 4
|
| 303 | | 5
|
| 304 | | 6
|
| 305 | | 7
|
| 306 | | |
| 307 | | */
|
| 308 | | |
| 309 | | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data;
|
| 310 | | |
| 311 | | state->key_latch = BITSWAP8(data, 7, 6, 5, 4, 0, 1, 2, 3) & 0x0f;
|
| 312 | | }
|
| 313 | | |
| 314 | | /* Memory Maps */
|
| 315 | | |
| 316 | | static ADDRESS_MAP_START( z80_mem, ADDRESS_SPACE_PROGRAM, 8 )
|
| 317 | | AM_RANGE(0x0000, 0xf7ff) AM_RAM
|
| 318 | | AM_RANGE(0xf800, 0xffff) AM_RAM AM_BASE_MEMBER(trs80m2_state, video_ram)
|
| 319 | | ADDRESS_MAP_END
|
| 320 | | |
| 321 | | static ADDRESS_MAP_START( z80_io, ADDRESS_SPACE_IO, 8 )
|
| 322 | | ADDRESS_MAP_GLOBAL_MASK(0xff)
|
| 323 | | AM_RANGE(0xe0, 0xe3) AM_DEVREADWRITE(Z80PIO_TAG, z80pio_cd_ba_r, z80pio_cd_ba_w)
|
| 324 | | AM_RANGE(0xe4, 0xe7) AM_DEVREADWRITE(FD1791_TAG, wd17xx_r, wd17xx_w)
|
| 325 | | AM_RANGE(0xef, 0xef) AM_DEVWRITE(FD1791_TAG, drvslt_w)
|
| 326 | | AM_RANGE(0xf0, 0xf3) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_r, z80ctc_w)
|
| 327 | | AM_RANGE(0xf4, 0xf7) AM_DEVREADWRITE(Z80SIO_TAG, z80sio_cd_ba_r, z80sio_cd_ba_w)
|
| 328 | | AM_RANGE(0xf8, 0xf8) AM_DEVREADWRITE(Z80DMA_TAG, z80dma_r, z80dma_w)
|
| 329 | | AM_RANGE(0xf9, 0xf9) AM_WRITE(rom_enable_w)
|
| 330 | | AM_RANGE(0xfc, 0xfc) AM_READ(keyboard_r) AM_DEVWRITE(MC6845_TAG, mc6845_address_w)
|
| 331 | | AM_RANGE(0xfd, 0xfd) AM_DEVREADWRITE(MC6845_TAG, mc6845_register_r, mc6845_register_w)
|
| 332 | | AM_RANGE(0xfe, 0xfe) AM_READ(rtc_r)
|
| 333 | | AM_RANGE(0xff, 0xff) AM_READWRITE(nmi_r, nmi_w)
|
| 334 | | ADDRESS_MAP_END
|
| 335 | | |
| 336 | | static ADDRESS_MAP_START( trs80m2_keyboard_io, ADDRESS_SPACE_IO, 8 )
|
| 337 | | AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(keyboard_busy_r)
|
| 338 | | AM_RANGE(MCS48_PORT_P0, MCS48_PORT_P0) AM_READ(keyboard_data_r)
|
| 339 | | AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(keyboard_ctrl_w)
|
| 340 | | AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(keyboard_latch_w)
|
| 341 | | ADDRESS_MAP_END
|
| 342 | | |
| 343 | | static ADDRESS_MAP_START( m68000_mem, ADDRESS_SPACE_PROGRAM, 16 )
|
| 344 | | ADDRESS_MAP_END
|
| 345 | | |
| 346 | | /* Input Ports */
|
| 347 | | |
| 348 | | static INPUT_PORTS_START( trs80m2 )
|
| 349 | | PORT_START("ROW0")
|
| 350 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 351 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
|
| 352 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
|
| 353 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
|
| 354 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
|
| 355 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD)
|
| 356 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
|
| 357 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 358 | | |
| 359 | | PORT_START("ROW1")
|
| 360 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 361 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
|
| 362 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
|
| 363 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
|
| 364 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
|
| 365 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x93") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
|
| 366 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
|
| 367 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 368 | | |
| 369 | | PORT_START("ROW2")
|
| 370 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("REPEAT")
|
| 371 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Right SHIFT") PORT_CODE(KEYCODE_RSHIFT)
|
| 372 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK))
|
| 373 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
|
| 374 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("LOCK")
|
| 375 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 376 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
|
| 377 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 378 | | |
| 379 | | PORT_START("ROW3")
|
| 380 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("cannot read label")
|
| 381 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
|
| 382 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
|
| 383 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
|
| 384 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
|
| 385 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD)
|
| 386 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD)
|
| 387 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x90") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
|
| 388 | | |
| 389 | | PORT_START("ROW4")
|
| 390 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BACKSPACE") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
|
| 391 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
|
| 392 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
|
| 393 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
|
| 394 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
|
| 395 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2)
|
| 396 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD)
|
| 397 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x92") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
|
| 398 | | |
| 399 | | PORT_START("ROW5")
|
| 400 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("HOLD")
|
| 401 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
|
| 402 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
|
| 403 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
|
| 404 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
|
| 405 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1)
|
| 406 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD)
|
| 407 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
|
| 408 | | |
| 409 | | PORT_START("ROW6")
|
| 410 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
|
| 411 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
|
| 412 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
|
| 413 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
|
| 414 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
|
| 415 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad ENTER") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(13)
|
| 416 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD)
|
| 417 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD)
|
| 418 | | |
| 419 | | PORT_START("ROW7")
|
| 420 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 421 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"')
|
| 422 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
|
| 423 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
|
| 424 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
|
| 425 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 426 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD)
|
| 427 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD)
|
| 428 | | |
| 429 | | PORT_START("ROW8")
|
| 430 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 431 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
|
| 432 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
|
| 433 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
|
| 434 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
|
| 435 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 436 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD)
|
| 437 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD)
|
| 438 | | |
| 439 | | PORT_START("ROW9")
|
| 440 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 441 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
|
| 442 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
|
| 443 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
|
| 444 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
|
| 445 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 446 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 447 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 448 | | |
| 449 | | PORT_START("ROW10")
|
| 450 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 451 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
|
| 452 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
|
| 453 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
|
| 454 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
|
| 455 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 456 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
|
| 457 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 458 | | |
| 459 | | PORT_START("ROW11")
|
| 460 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 461 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
|
| 462 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
|
| 463 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
|
| 464 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
|
| 465 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 466 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t')
|
| 467 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
|
| 468 | | INPUT_PORTS_END
|
| 469 | | |
| 470 | | /* Video */
|
| 471 | | |
| 472 | | static MC6845_UPDATE_ROW( trs80m2_update_row )
|
| 473 | | {
|
| 474 | | trs80m2_state *state = (trs80m2_state *)device->machine->driver_data;
|
| 475 | | |
| 476 | | for (int column = 0; column < x_count; column++)
|
| 477 | | {
|
| 478 | | int bit;
|
| 479 | | |
| 480 | | UINT16 address = (state->video_ram[(ma + column) & 0x7ff] << 4) | (ra & 0x0f);
|
| 481 | | UINT8 data = state->char_rom[address & 0x7ff];
|
| 482 | | |
| 483 | | if (column == cursor_x)
|
| 484 | | {
|
| 485 | | data = 0xff;
|
| 486 | | }
|
| 487 | | |
| 488 | | for (bit = 0; bit < 8; bit++)
|
| 489 | | {
|
| 490 | | int x = (column * 8) + bit;
|
| 491 | | |
| 492 | | *BITMAP_ADDR16(bitmap, y, x) = BIT(data, 7);
|
| 493 | | |
| 494 | | data <<= 1;
|
| 495 | | }
|
| 496 | | }
|
| 497 | | }
|
| 498 | | |
| 499 | | static WRITE_LINE_DEVICE_HANDLER( de_w )
|
| 500 | | {
|
| 501 | | trs80m2_state *driver_state = (trs80m2_state *)device->machine->driver_data;
|
| 502 | | |
| 503 | | driver_state->de = state;
|
| 504 | | }
|
| 505 | | |
| 506 | | static WRITE_LINE_DEVICE_HANDLER( vsync_w )
|
| 507 | | {
|
| 508 | | trs80m2_state *driver_state = (trs80m2_state *)device->machine->driver_data;
|
| 509 | | |
| 510 | | if (state)
|
| 511 | | {
|
| 512 | | driver_state->rtc_int = !driver_state->rtc_int;
|
| 513 | | |
| 514 | | if (driver_state->enable_rtc_int && driver_state->rtc_int)
|
| 515 | | {
|
| 516 | | /* trigger RTC interrupt */
|
| 517 | | cputag_set_input_line(device->machine, Z80_TAG, INPUT_LINE_NMI, ASSERT_LINE);
|
| 518 | | }
|
| 519 | | }
|
| 520 | | }
|
| 521 | | |
| 522 | | static const mc6845_interface mc6845_intf =
|
| 523 | | {
|
| 524 | | SCREEN_TAG,
|
| 525 | | 8,
|
| 526 | | NULL,
|
| 527 | | trs80m2_update_row,
|
| 528 | | NULL,
|
| 529 | | DEVCB_LINE(de_w),
|
| 530 | | DEVCB_NULL,
|
| 531 | | DEVCB_NULL,
|
| 532 | | DEVCB_LINE(vsync_w),
|
| 533 | | NULL
|
| 534 | | };
|
| 535 | | |
| 536 | | static VIDEO_START( trs80m2 )
|
| 537 | | {
|
| 538 | | trs80m2_state *state = (trs80m2_state *)machine->driver_data;
|
| 539 | | |
| 540 | | /* find devices */
|
| 541 | | state->mc6845 = devtag_get_device(machine, MC6845_TAG);
|
| 542 | | |
| 543 | | /* find memory regions */
|
| 544 | | state->char_rom = memory_region(machine, MC6845_TAG);
|
| 545 | | }
|
| 546 | | |
| 547 | | static VIDEO_UPDATE( trs80m2 )
|
| 548 | | {
|
| 549 | | trs80m2_state *state = (trs80m2_state *)screen->machine->driver_data;
|
| 550 | | |
| 551 | | if (state->blnkvid)
|
| 552 | | {
|
| 553 | | bitmap_fill(bitmap, cliprect, get_black_pen(screen->machine));
|
| 554 | | }
|
| 555 | | else
|
| 556 | | {
|
| 557 | | mc6845_update(state->mc6845, bitmap, cliprect);
|
| 558 | | }
|
| 559 | | |
| 560 | | return 0;
|
| 561 | | }
|
| 562 | | |
| 563 | | /* Z80-DMA Interface */
|
| 564 | | |
| 565 | | static Z80DMA_INTERFACE( dma_intf )
|
| 566 | | {
|
| 567 | | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_HALT),
|
| 568 | | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0),
|
| 569 | | DEVCB_NULL,
|
| 570 | | DEVCB_MEMORY_HANDLER(Z80_TAG, PROGRAM, memory_read_byte),
|
| 571 | | DEVCB_MEMORY_HANDLER(Z80_TAG, PROGRAM, memory_write_byte),
|
| 572 | | DEVCB_MEMORY_HANDLER(Z80_TAG, IO, memory_read_byte),
|
| 573 | | DEVCB_MEMORY_HANDLER(Z80_TAG, IO, memory_write_byte)
|
| 574 | | };
|
| 575 | | |
| 576 | | /* Z80-PIO Interface */
|
| 577 | | |
| 578 | | static READ8_DEVICE_HANDLER( pio_pa_r )
|
| 579 | | {
|
| 580 | | /*
|
| 581 | | |
| 582 | | bit signal description
|
| 583 | | |
| 584 | | 0 INTRQ FDC INT request
|
| 585 | | 1 _TWOSID 2-sided diskette
|
| 586 | | 2 _DSKCHG disk change
|
| 587 | | 3 PRIME prime
|
| 588 | | 4 FAULT printer fault
|
| 589 | | 5 PSEL printer select
|
| 590 | | 6 PE paper empty
|
| 591 | | 7 BUSY printer busy
|
| 592 | | |
| 593 | | */
|
| 594 | | |
| 595 | | trs80m2_state *state = (trs80m2_state *)device->machine->driver_data;
|
| 596 | | |
| 597 | | UINT8 data = 0;
|
| 598 | | |
| 599 | | /* floppy interrupt */
|
| 600 | | data |= state->fdc_intrq;
|
| 601 | | |
| 602 | | /* 2-sided diskette */
|
| 603 | | data |= floppy_twosid_r(state->floppy) << 1;
|
| 604 | | |
| 605 | | /* disk change */
|
| 606 | | data |= floppy_dskchg_r(state->floppy) << 2;
|
| 607 | | |
| 608 | | /* printer fault */
|
| 609 | | data |= centronics_fault_r(state->centronics) << 4;
|
| 610 | | |
| 611 | | /* paper empty */
|
| 612 | | data |= !centronics_pe_r(state->centronics) << 6;
|
| 613 | | |
| 614 | | /* printer busy */
|
| 615 | | data |= centronics_busy_r(state->centronics) << 7;
|
| 616 | | |
| 617 | | return data;
|
| 618 | | }
|
| 619 | | |
| 620 | | static WRITE8_DEVICE_HANDLER( pio_pa_w )
|
| 621 | | {
|
| 622 | | /*
|
| 623 | | |
| 624 | | bit signal description
|
| 625 | | |
| 626 | | 0 INTRQ FDC INT request
|
| 627 | | 1 _TWOSID 2-sided diskette
|
| 628 | | 2 _DSKCHG disk change
|
| 629 | | 3 PRIME prime
|
| 630 | | 4 FAULT printer fault
|
| 631 | | 5 PSEL printer select
|
| 632 | | 6 PE paper empty
|
| 633 | | 7 BUSY printer busy
|
| 634 | | |
| 635 | | */
|
| 636 | | |
| 637 | | trs80m2_state *state = (trs80m2_state *)device->machine->driver_data;
|
| 638 | | |
| 639 | | /* prime */
|
| 640 | | centronics_prime_w(state->centronics, BIT(data, 3));
|
| 641 | | }
|
| 642 | | |
| 643 | | static WRITE_LINE_DEVICE_HANDLER( strobe_w )
|
| 644 | | {
|
| 645 | | centronics_strobe_w(device, !state);
|
| 646 | | }
|
| 647 | | |
| 648 | | static Z80PIO_INTERFACE( pio_intf )
|
| 649 | | {
|
| 650 | | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0), /* interrupt callback */
|
| 651 | | DEVCB_HANDLER(pio_pa_r), /* port A read callback */
|
| 652 | | DEVCB_HANDLER(pio_pa_w), /* port A write callback */
|
| 653 | | DEVCB_NULL, /* port A ready callback */
|
| 654 | | DEVCB_NULL, /* port B read callback */
|
| 655 | | DEVCB_DEVICE_HANDLER(CENTRONICS_TAG, centronics_data_w), /* port B write callback */
|
| 656 | | DEVCB_DEVICE_LINE(CENTRONICS_TAG, strobe_w) /* port B ready callback */
|
| 657 | | };
|
| 658 | | |
| 659 | | /* Centronics Interface */
|
| 660 | | |
| 661 | | static const centronics_interface centronics_intf =
|
| 662 | | {
|
| 663 | | 0, /* is IBM PC? */
|
| 664 | | DEVCB_DEVICE_LINE(Z80PIO_TAG, z80pio_bstb_w), /* ACK output */
|
| 665 | | DEVCB_NULL, /* BUSY output */
|
| 666 | | DEVCB_NULL /* NOT BUSY output */
|
| 667 | | };
|
| 668 | | |
| 669 | | /* Z80-SIO/0 Interface */
|
| 670 | | |
| 671 | | static void sio_interrupt(running_device *device, int state)
|
| 672 | | {
|
| 673 | | cputag_set_input_line(device->machine, Z80_TAG, INPUT_LINE_IRQ0, state);
|
| 674 | | }
|
| 675 | | |
| 676 | | static const z80sio_interface sio_intf =
|
| 677 | | {
|
| 678 | | sio_interrupt, /* interrupt handler */
|
| 679 | | NULL, /* DTR changed handler */
|
| 680 | | NULL, /* RTS changed handler */
|
| 681 | | NULL, /* BREAK changed handler */
|
| 682 | | NULL, /* transmit handler */
|
| 683 | | NULL /* receive handler */
|
| 684 | | };
|
| 685 | | |
| 686 | | /* Z80-CTC Interface */
|
| 687 | | |
| 688 | | static TIMER_DEVICE_CALLBACK( ctc_tick )
|
| 689 | | {
|
| 690 | | trs80m2_state *state = (trs80m2_state *) timer->machine->driver_data;
|
| 691 | | |
| 692 | | z80ctc_trg0_w(state->z80ctc, 1);
|
| 693 | | z80ctc_trg0_w(state->z80ctc, 0);
|
| 694 | | |
| 695 | | z80ctc_trg1_w(state->z80ctc, 1);
|
| 696 | | z80ctc_trg1_w(state->z80ctc, 0);
|
| 697 | | |
| 698 | | z80ctc_trg2_w(state->z80ctc, 1);
|
| 699 | | z80ctc_trg2_w(state->z80ctc, 0);
|
| 700 | | }
|
| 701 | | |
| 702 | | static Z80CTC_INTERFACE( ctc_intf )
|
| 703 | | {
|
| 704 | | 0, /* timer disables */
|
| 705 | | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0), /* interrupt handler */
|
| 706 | | DEVCB_NULL, // DEVCB_DEVICE_LINE(Z80SIO_TAG, z80sio_rxca_w), /* ZC/TO0 callback */
|
| 707 | | DEVCB_NULL, // DEVCB_DEVICE_LINE(Z80SIO_TAG, z80sio_txca_w), /* ZC/TO1 callback */
|
| 708 | | DEVCB_NULL, // DEVCB_DEVICE_LINE(Z80SIO_TAG, z80sio_rxtxcb_w) /* ZC/TO2 callback */
|
| 709 | | };
|
| 710 | | |
| 711 | | /* FD1791 Interface */
|
| 712 | | |
| 713 | | static const floppy_config trs80m2_floppy_config =
|
| 714 | | {
|
| 715 | | DEVCB_NULL,
|
| 716 | | DEVCB_NULL,
|
| 717 | | DEVCB_NULL,
|
| 718 | | DEVCB_NULL,
|
| 719 | | DEVCB_NULL,
|
| 720 | | FLOPPY_DRIVE_DS_80,
|
| 721 | | FLOPPY_OPTIONS_NAME(default),
|
| 722 | | DO_NOT_KEEP_GEOMETRY
|
| 723 | | };
|
| 724 | | |
| 725 | | static WRITE_LINE_DEVICE_HANDLER( fdc_intrq_w )
|
| 726 | | {
|
| 727 | | trs80m2_state *driver_state = (trs80m2_state *)device->machine->driver_data;
|
| 728 | | |
| 729 | | driver_state->fdc_intrq = state;
|
| 730 | | |
| 731 | | z80pio_pa_w(driver_state->z80pio, 0, state);
|
| 732 | | }
|
| 733 | | |
| 734 | | static const wd17xx_interface fd1791_intf =
|
| 735 | | {
|
| 736 | | DEVCB_NULL,
|
| 737 | | DEVCB_LINE(fdc_intrq_w),
|
| 738 | | DEVCB_DEVICE_LINE(Z80DMA_TAG, z80dma_rdy_w),
|
| 739 | | { FLOPPY_0, NULL, NULL, NULL }
|
| 740 | | };
|
| 741 | | |
| 742 | | /* Z80 Daisy Chain */
|
| 743 | | |
| 744 | | static const z80_daisy_chain trs80m2_daisy_chain[] =
|
| 745 | | {
|
| 746 | | { Z80CTC_TAG },
|
| 747 | | { Z80SIO_TAG },
|
| 748 | | { Z80DMA_TAG },
|
| 749 | | { Z80PIO_TAG },
|
| 750 | | { NULL }
|
| 751 | | };
|
| 752 | | |
| 753 | | /* Machine Initialization */
|
| 754 | | |
| 755 | | static MACHINE_START( trs80m2 )
|
| 756 | | {
|
| 757 | | trs80m2_state *state = (trs80m2_state *)machine->driver_data;
|
| 758 | | |
| 759 | | /* find devices */
|
| 760 | | state->z80ctc = devtag_get_device(machine, Z80CTC_TAG);
|
| 761 | | state->z80pio = devtag_get_device(machine, Z80PIO_TAG);
|
| 762 | | state->mc6845 = devtag_get_device(machine, MC6845_TAG);
|
| 763 | | state->centronics = devtag_get_device(machine, CENTRONICS_TAG);
|
| 764 | | state->floppy = devtag_get_device(machine, FLOPPY_0);
|
| 765 | | |
| 766 | | /* Shugart SA-800 motor spins constantly */
|
| 767 | | floppy_mon_w(state->floppy, CLEAR_LINE);
|
| 768 | | |
| 769 | | /* register for state saving */
|
| 770 | | state_save_register_global(machine, state->boot_rom);
|
| 771 | | state_save_register_global(machine, state->bank);
|
| 772 | | state_save_register_global(machine, state->msel);
|
| 773 | | state_save_register_global(machine, state->fdc_intrq);
|
| 774 | | state_save_register_global(machine, state->key_latch);
|
| 775 | | state_save_register_global(machine, state->key_data);
|
| 776 | | state_save_register_global(machine, state->key_bit);
|
| 777 | | state_save_register_global(machine, state->kbclk);
|
| 778 | | state_save_register_global(machine, state->kbdata);
|
| 779 | | state_save_register_global(machine, state->kbirq);
|
| 780 | | state_save_register_global(machine, state->blnkvid);
|
| 781 | | state_save_register_global(machine, state->_80_40_char_en);
|
| 782 | | state_save_register_global(machine, state->de);
|
| 783 | | state_save_register_global(machine, state->rtc_int);
|
| 784 | | state_save_register_global(machine, state->enable_rtc_int);
|
| 785 | | }
|
| 786 | | |
| 787 | | static MACHINE_RESET( trs80m2 )
|
| 788 | | {
|
| 789 | | trs80m2_state *state = (trs80m2_state *)machine->driver_data;
|
| 790 | | |
| 791 | | /* clear keyboard interrupt */
|
| 792 | | state->kbirq = 1;
|
| 793 | | |
| 794 | | /* enable boot ROM */
|
| 795 | | state->boot_rom = 1;
|
| 796 | | |
| 797 | | /* disable video RAM */
|
| 798 | | state->msel = 0;
|
| 799 | | |
| 800 | | bankswitch(machine);
|
| 801 | | }
|
| 802 | | |
| 803 | | /* Machine Driver */
|
| 804 | | |
| 805 | | static MACHINE_DRIVER_START( trs80m2 )
|
| 806 | | MDRV_DRIVER_DATA(trs80m2_state)
|
| 807 | | |
| 808 | | /* basic machine hardware */
|
| 809 | | MDRV_CPU_ADD(Z80_TAG, Z80, XTAL_8MHz/2)
|
| 810 | | MDRV_CPU_CONFIG(trs80m2_daisy_chain)
|
| 811 | | MDRV_CPU_PROGRAM_MAP(z80_mem)
|
| 812 | | MDRV_CPU_IO_MAP(z80_io)
|
| 813 | | |
| 814 | | // MDRV_CPU_ADD(I8021_TAG, I8021, 100000)
|
| 815 | | // MDRV_CPU_IO_MAP(trs80m2_keyboard_io)
|
| 816 | | |
| 817 | | MDRV_MACHINE_START(trs80m2)
|
| 818 | | MDRV_MACHINE_RESET(trs80m2)
|
| 819 | | |
| 820 | | /* video hardware */
|
| 821 | | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
|
| 822 | | MDRV_SCREEN_REFRESH_RATE(60)
|
| 823 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
|
| 824 | | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
| 825 | | MDRV_SCREEN_SIZE(640, 480)
|
| 826 | | MDRV_SCREEN_VISIBLE_AREA(0, 639, 0, 479)
|
| 827 | | |
| 828 | | MDRV_PALETTE_LENGTH(2)
|
| 829 | | MDRV_PALETTE_INIT(black_and_white)
|
| 830 | | |
| 831 | | MDRV_VIDEO_START(trs80m2)
|
| 832 | | MDRV_VIDEO_UPDATE(trs80m2)
|
| 833 | | |
| 834 | | MDRV_MC6845_ADD(MC6845_TAG, MC6845, XTAL_12_48MHz/8, mc6845_intf)
|
| 835 | | |
| 836 | | /* devices */
|
| 837 | | MDRV_WD179X_ADD(FD1791_TAG, fd1791_intf)
|
| 838 | | MDRV_Z80CTC_ADD(Z80CTC_TAG, XTAL_8MHz/2, ctc_intf)
|
| 839 | | MDRV_TIMER_ADD_PERIODIC("ctc", ctc_tick, HZ(XTAL_8MHz/2/2))
|
| 840 | | MDRV_Z80DMA_ADD(Z80DMA_TAG, XTAL_8MHz/2, dma_intf)
|
| 841 | | MDRV_Z80PIO_ADD(Z80PIO_TAG, XTAL_8MHz/2, pio_intf)
|
| 842 | | MDRV_Z80SIO_ADD(Z80SIO_TAG, XTAL_8MHz/2, sio_intf)
|
| 843 | | MDRV_CENTRONICS_ADD(CENTRONICS_TAG, centronics_intf)
|
| 844 | | MDRV_FLOPPY_DRIVE_ADD(FLOPPY_0, trs80m2_floppy_config)
|
| 845 | | |
| 846 | | /* internal RAM */
|
| 847 | | MDRV_RAM_ADD("messram")
|
| 848 | | MDRV_RAM_DEFAULT_SIZE("32K")
|
| 849 | | MDRV_RAM_EXTRA_OPTIONS("64K,96K,128K,160K,192K,224K,256K,288K,320K,352K,384K,416K,448K,480K,512K")
|
| 850 | | MACHINE_DRIVER_END
|
| 851 | | |
| 852 | | static MACHINE_DRIVER_START( trs80m16 )
|
| 853 | | MDRV_IMPORT_FROM(trs80m2)
|
| 854 | | |
| 855 | | /* basic machine hardware */
|
| 856 | | // MDRV_CPU_ADD(M68000_TAG, M68000, 6000000)
|
| 857 | | // MDRV_CPU_PROGRAM_MAP(m68000_mem)
|
| 858 | | |
| 859 | | /* video hardware */
|
| 860 | | MDRV_PALETTE_INIT(monochrome_green)
|
| 861 | | |
| 862 | | /* internal RAM */
|
| 863 | | MDRV_RAM_MODIFY("messram")
|
| 864 | | MDRV_RAM_DEFAULT_SIZE("256K")
|
| 865 | | MDRV_RAM_EXTRA_OPTIONS("512K,768K,1M")
|
| 866 | | MACHINE_DRIVER_END
|
| 867 | | |
| 868 | | /* ROMs */
|
| 869 | | |
| 870 | | ROM_START( trs80m2 )
|
| 871 | | ROM_REGION( 0x800, Z80_TAG, 0 )
|
| 872 | | ROM_LOAD( "8043216.u11", 0x0000, 0x0800, CRC(7017a373) SHA1(1c7127fcc99fc351a40d3a3199ba478e783c452e) )
|
| 873 | | |
| 874 | | ROM_REGION( 0x800, MC6845_TAG, 0 )
|
| 875 | | ROM_LOAD( "8043316.u9", 0x0000, 0x0800, CRC(04425b03) SHA1(32a29dc202b7fcf21838289cc3bffc51ef943dab) )
|
| 876 | | |
| 877 | | ROM_REGION( 0x400, I8021_TAG, 0 )
|
| 878 | | ROM_LOAD( "65-1991.z4", 0x0000, 0x0400, NO_DUMP )
|
| 879 | | ROM_END
|
| 880 | | |
| 881 | | /*
|
| 882 | | |
| 883 | | TRS-80 Model II/16 Z80 CPU Board ROM
|
| 884 | | |
| 885 | | It would seem that every processor board I find has a different ROM on it! It seems that the early ROMs
|
| 886 | | don't boot directly from a hard drive. But there seems to be many versions of ROMs. I've placed them in
|
| 887 | | order of serial number in the list below. There also appears to be at least two board revisions, "C" and "D".
|
| 888 | | |
| 889 | | cpu_c8ff.bin/hex:
|
| 890 | | Mask Programmable PROM, Equivilant to Intel 2716 EPROM, with checksum C8FF came from a cpu board with
|
| 891 | | serial number 120353 out of a Model II with serial number 2002102 and catalog number 26-6002. The board
|
| 892 | | was labeled, "Revision C". This appears to be an early ROM and according to a very helpful fellow
|
| 893 | | collector, Aaron in Australia, doesn't allow boot directly from a hard disk.
|
| 894 | | |
| 895 | | cpu_9733.bin/hex:
|
| 896 | | An actual SGS-Ates (Now STMicroelectronics) 2716 EPROM, with checksum 9733 came from a cpu board with
|
| 897 | | serial number 161993 out of a pile of random cards that I have. I don't know what machine it originated
|
| 898 | | from. The board was labeled, "Revision C". This appears to be a later ROM in that it is able to boot
|
| 899 | | directly from an 8MB hard disk. The EPROM had a windows sticker on it labeled, "U54".
|
| 900 | | |
| 901 | | cpu_2119.bin/hex:
|
| 902 | | An actual Texas Instruments 2716 EPROM, with checksum 2119 came from a cpu board with serial number
|
| 903 | | 178892 out of a Model 16 with serial number 64014509 and catalog number 26-4002. The board was labeled,
|
| 904 | | "Revision D". This appears to be a later ROM and does appear to allow boot directly from an 8MB hard disk.
|
| 905 | | |
| 906 | | cpu_2bff.bin/hex:
|
| 907 | | Mask Programmable PROM, Equivilant to Intel 2716 EPROM, with checksum 2BFF came from a cpu board with
|
| 908 | | serial number 187173 our of a pile of random cards that I have. I don't know what machine it originated
|
| 909 | | from. The board was labeled, "Revision D". This appears to be a later ROM in that it is able to boot
|
| 910 | | directly from an 8MB hard disk.
|
| 911 | | |
| 912 | | */
|
| 913 | | |
| 914 | | ROM_START( trs80m16 )
|
| 915 | | ROM_REGION( 0x800, Z80_TAG, 0 )
|
| 916 | | ROM_SYSTEM_BIOS( 0, "c8ff", "S/N 120353" )
|
| 917 | | ROMX_LOAD( "cpu_c8ff.u11", 0x0000, 0x0800, CRC(7017a373) SHA1(1c7127fcc99fc351a40d3a3199ba478e783c452e), ROM_BIOS(1) )
|
| 918 | | ROM_SYSTEM_BIOS( 1, "9733", "S/N 161993" )
|
| 919 | | ROMX_LOAD( "cpu_9733.u11", 0x0000, 0x0800, CRC(823924b1) SHA1(aee0625bcbd8620b28ab705e15ad9bea804c8476), ROM_BIOS(2) )
|
| 920 | | ROM_SYSTEM_BIOS( 2, "2119", "S/N 64014509" )
|
| 921 | | ROMX_LOAD( "cpu_2119.u11", 0x0000, 0x0800, CRC(7a663049) SHA1(f308439ce266df717bfe79adcdad6024b4faa141), ROM_BIOS(3) )
|
| 922 | | ROM_SYSTEM_BIOS( 3, "2bff", "S/N 187173" )
|
| 923 | | ROMX_LOAD( "cpu_2bff.u11", 0x0000, 0x0800, CRC(c6c71d8b) SHA1(7107e2cbbe769851a4460680c2deff8e76a101b5), ROM_BIOS(4) )
|
| 924 | | |
| 925 | | ROM_REGION( 0x800, MC6845_TAG, 0 )
|
| 926 | | ROM_LOAD( "8043316.u9", 0x0000, 0x0800, CRC(04425b03) SHA1(32a29dc202b7fcf21838289cc3bffc51ef943dab) )
|
| 927 | | |
| 928 | | ROM_REGION( 0x400, I8021_TAG, 0 )
|
| 929 | | ROM_LOAD( "65-1991.z4", 0x0000, 0x0400, NO_DUMP )
|
| 930 | | |
| 931 | | ROM_REGION( 0x1000, M68000_TAG, 0 )
|
| 932 | | ROM_LOAD( "m68000.rom", 0x0000, 0x1000, NO_DUMP )
|
| 933 | | ROM_END
|
| 934 | | |
| 935 | | /* System Drivers */
|
| 936 | | |
| 937 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
| 938 | | COMP( 1979, trs80m2, 0, 0, trs80m2, trs80m2, 0, "Tandy Radio Shack", "TRS-80 Model II", GAME_NO_SOUND_HW | GAME_NOT_WORKING )
|
| 939 | | COMP( 1982, trs80m16, trs80m2, 0, trs80m16, trs80m2, 0, "Tandy Radio Shack", "TRS-80 Model 16", GAME_NO_SOUND_HW | GAME_NOT_WORKING )
|
| 940 | | //COMP( 1983, trs80m12, trs80m2, 0, trs80m16, trs80m2, 0, "Tandy Radio Shack", "TRS-80 Model 12", GAME_NO_SOUND_HW | GAME_NOT_WORKING )
|
| 941 | | //COMP( 1984, trs80m16b,trs80m2, 0, trs80m16, trs80m2, 0, "Tandy Radio Shack", "TRS-80 Model 16B", GAME_NO_SOUND_HW | GAME_NOT_WORKING )
|
| 942 | | //COMP( 1985, tandy6k, trs80m2, 0, tandy6k, trs80m2, 0, "Tandy Radio Shack", "Tandy 6000 HD", GAME_NO_SOUND_HW | GAME_NOT_WORKING )
|
| 1 | /* |
| 2 | |
| 3 | Tandy Radio Shack TRS-80 Model II/12/16/16B/6000 |
| 4 | |
| 5 | http://home.iae.nl/users/pb0aia/cm/modelii.html |
| 6 | |
| 7 | */ |
| 8 | |
| 9 | /* |
| 10 | |
| 11 | TODO: |
| 12 | |
| 13 | - wd17xx.c thinks the drive is always ready |
| 14 | - keyboard CPU ROM |
| 15 | - keyboard layout |
| 16 | - graphics board |
| 17 | |
| 18 | */ |
| 19 | |
| 20 | #include "emu.h" |
| 21 | #include "includes/trs80m2.h" |
| 22 | #include "cpu/z80/z80.h" |
| 23 | #include "cpu/z80/z80daisy.h" |
| 24 | #include "cpu/mcs48/mcs48.h" |
| 25 | #include "cpu/m68000/m68000.h" |
| 26 | #include "devices/flopdrv.h" |
| 27 | #include "devices/messram.h" |
| 28 | #include "machine/ctronics.h" |
| 29 | #include "machine/wd17xx.h" |
| 30 | #include "machine/z80ctc.h" |
| 31 | #include "machine/z80dma.h" |
| 32 | #include "machine/z80pio.h" |
| 33 | #include "machine/z80sio.h" |
| 34 | #include "video/mc6845.h" |
| 35 | |
| 36 | /* Read/Write Handlers */ |
| 37 | |
| 38 | static WRITE8_DEVICE_HANDLER( drvslt_w ) |
| 39 | { |
| 40 | /* |
| 41 | |
| 42 | bit signal |
| 43 | |
| 44 | 0 DS1 |
| 45 | 1 DS2 |
| 46 | 2 DS3 |
| 47 | 3 DS4 |
| 48 | 4 |
| 49 | 5 |
| 50 | 6 SDSEL |
| 51 | 7 FM/MFM |
| 52 | |
| 53 | */ |
| 54 | |
| 55 | /* drive select */ |
| 56 | if (!BIT(data, 0)) wd17xx_set_drive(device, 0); |
| 57 | if (!BIT(data, 1)) wd17xx_set_drive(device, 1); |
| 58 | if (!BIT(data, 2)) wd17xx_set_drive(device, 2); |
| 59 | if (!BIT(data, 3)) wd17xx_set_drive(device, 3); |
| 60 | |
| 61 | /* side select */ |
| 62 | wd17xx_set_side(device, !BIT(data, 6)); |
| 63 | |
| 64 | /* FM/MFM */ |
| 65 | wd17xx_dden_w(device, BIT(data, 7)); |
| 66 | } |
| 67 | |
| 68 | static void bankswitch(running_machine *machine) |
| 69 | { |
| 70 | trs80m2_state *state = (trs80m2_state *)machine->driver_data; |
| 71 | |
| 72 | const address_space *program = cputag_get_address_space(machine, Z80_TAG, ADDRESS_SPACE_PROGRAM); |
| 73 | running_device *messram = devtag_get_device(machine, "messram"); |
| 74 | UINT8 *rom = memory_region(machine, Z80_TAG); |
| 75 | UINT8 *ram = messram_get_ptr(messram); |
| 76 | int last_page = (messram_get_size(messram) / 0x8000) - 1; |
| 77 | |
| 78 | if (state->boot_rom) |
| 79 | { |
| 80 | /* enable BOOT ROM */ |
| 81 | memory_install_rom(program, 0x0000, 0x07ff, 0, 0, rom); |
| 82 | memory_install_ram(program, 0x0800, 0x7fff, 0, 0, ram + 0x800); |
| 83 | } |
| 84 | else |
| 85 | { |
| 86 | /* enable RAM */ |
| 87 | memory_install_ram(program, 0x0000, 0x7fff, 0, 0, ram); |
| 88 | } |
| 89 | |
| 90 | if (state->bank > last_page) |
| 91 | { |
| 92 | memory_unmap_readwrite(program, 0x8000, 0xffff, 0, 0); |
| 93 | } |
| 94 | else |
| 95 | { |
| 96 | /* enable RAM */ |
| 97 | memory_install_ram(program, 0x8000, 0xffff, 0, 0, ram + (state->bank * 0x8000)); |
| 98 | } |
| 99 | |
| 100 | if (state->msel) |
| 101 | { |
| 102 | /* enable video RAM */ |
| 103 | memory_install_ram(program, 0xf800, 0xffff, 0, 0, state->video_ram); |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | static WRITE8_HANDLER( rom_enable_w ) |
| 108 | { |
| 109 | /* |
| 110 | |
| 111 | bit description |
| 112 | |
| 113 | 0 BOOT ROM |
| 114 | 1 |
| 115 | 2 |
| 116 | 3 |
| 117 | 4 |
| 118 | 5 |
| 119 | 6 |
| 120 | 7 |
| 121 | |
| 122 | */ |
| 123 | |
| 124 | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data; |
| 125 | |
| 126 | state->boot_rom = BIT(data, 0); |
| 127 | bankswitch(space->machine); |
| 128 | } |
| 129 | |
| 130 | static READ8_HANDLER( keyboard_r ) |
| 131 | { |
| 132 | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data; |
| 133 | |
| 134 | /* clear keyboard interrupt */ |
| 135 | state->kbirq = 1; |
| 136 | z80ctc_trg3_w(state->z80ctc, state->kbirq); |
| 137 | |
| 138 | state->key_bit = 0; |
| 139 | |
| 140 | return state->key_data; |
| 141 | } |
| 142 | |
| 143 | static READ8_HANDLER( rtc_r ) |
| 144 | { |
| 145 | /* clear RTC interrupt */ |
| 146 | cputag_set_input_line(space->machine, Z80_TAG, INPUT_LINE_NMI, CLEAR_LINE); |
| 147 | |
| 148 | return 0; |
| 149 | } |
| 150 | |
| 151 | static READ8_HANDLER( nmi_r ) |
| 152 | { |
| 153 | /* |
| 154 | |
| 155 | bit signal description |
| 156 | |
| 157 | 0 |
| 158 | 1 |
| 159 | 2 |
| 160 | 3 |
| 161 | 4 80/40 CHAR EN 80/40 character mode |
| 162 | 5 ENABLE RTC INT RTC interrupt enable |
| 163 | 6 DE display enabled |
| 164 | 7 KBIRQ keyboard interrupt |
| 165 | |
| 166 | */ |
| 167 | |
| 168 | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data; |
| 169 | |
| 170 | UINT8 data = 0; |
| 171 | |
| 172 | /* 80/40 character mode*/ |
| 173 | data |= state->_80_40_char_en << 4; |
| 174 | |
| 175 | /* RTC interrupt enable */ |
| 176 | data |= state->enable_rtc_int << 5; |
| 177 | |
| 178 | /* display enabled */ |
| 179 | data |= state->de << 6; |
| 180 | |
| 181 | /* keyboard interrupt */ |
| 182 | data |= state->kbirq << 7; |
| 183 | |
| 184 | return data; |
| 185 | } |
| 186 | |
| 187 | static WRITE8_HANDLER( nmi_w ) |
| 188 | { |
| 189 | /* |
| 190 | |
| 191 | bit signal description |
| 192 | |
| 193 | 0 memory bank select bit 0 |
| 194 | 1 memory bank select bit 1 |
| 195 | 2 memory bank select bit 2 |
| 196 | 3 memory bank select bit 3 |
| 197 | 4 80/40 CHAR EN 80/40 character mode |
| 198 | 5 ENABLE RTC INT RTC interrupt enable |
| 199 | 6 BLNKVID video display enable |
| 200 | 7 video RAM enable |
| 201 | |
| 202 | */ |
| 203 | |
| 204 | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data; |
| 205 | |
| 206 | /* memory bank select */ |
| 207 | state->bank = data & 0x0f; |
| 208 | |
| 209 | /* 80/40 character mode */ |
| 210 | state->_80_40_char_en = BIT(data, 4); |
| 211 | mc6845_set_clock(state->mc6845, state->_80_40_char_en ? XTAL_12_48MHz/16 : XTAL_12_48MHz/8); |
| 212 | |
| 213 | /* RTC interrupt enable */ |
| 214 | state->enable_rtc_int = BIT(data, 5); |
| 215 | |
| 216 | if (state->enable_rtc_int && state->rtc_int) |
| 217 | { |
| 218 | /* trigger RTC interrupt */ |
| 219 | cputag_set_input_line(space->machine, Z80_TAG, INPUT_LINE_NMI, ASSERT_LINE); |
| 220 | } |
| 221 | |
| 222 | /* video display enable */ |
| 223 | state->blnkvid = BIT(data, 6); |
| 224 | |
| 225 | /* video RAM enable */ |
| 226 | state->msel = BIT(data, 7); |
| 227 | bankswitch(space->machine); |
| 228 | } |
| 229 | |
| 230 | static READ8_HANDLER( keyboard_busy_r ) |
| 231 | { |
| 232 | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data; |
| 233 | |
| 234 | return state->kbirq; |
| 235 | } |
| 236 | |
| 237 | static READ8_HANDLER( keyboard_data_r ) |
| 238 | { |
| 239 | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data; |
| 240 | |
| 241 | static const char *const KEY_ROW[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7", "ROW8", "ROW9", "ROW10", "ROW11" }; |
| 242 | |
| 243 | return input_port_read(space->machine, KEY_ROW[state->key_latch]); |
| 244 | } |
| 245 | |
| 246 | static WRITE8_HANDLER( keyboard_ctrl_w ) |
| 247 | { |
| 248 | /* |
| 249 | |
| 250 | bit description |
| 251 | |
| 252 | 0 DATA |
| 253 | 1 CLOCK |
| 254 | 2 LED |
| 255 | 3 |
| 256 | 4 LED |
| 257 | 5 |
| 258 | 6 |
| 259 | 7 |
| 260 | |
| 261 | */ |
| 262 | |
| 263 | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data; |
| 264 | |
| 265 | int kbdata = BIT(data, 0); |
| 266 | int kbclk = BIT(data, 1); |
| 267 | |
| 268 | if (state->key_bit == 8) |
| 269 | { |
| 270 | if (!state->kbdata && kbdata) |
| 271 | { |
| 272 | /* trigger keyboard interrupt */ |
| 273 | state->kbirq = 0; |
| 274 | z80ctc_trg3_w(state->z80ctc, state->kbirq); |
| 275 | } |
| 276 | } |
| 277 | else |
| 278 | { |
| 279 | if (!state->kbclk && kbclk) |
| 280 | { |
| 281 | /* shift in keyboard data bit */ |
| 282 | state->key_data <<= 1; |
| 283 | state->key_data |= kbdata; |
| 284 | state->key_bit++; |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | state->kbdata = kbdata; |
| 289 | state->kbclk = kbclk; |
| 290 | } |
| 291 | |
| 292 | static WRITE8_HANDLER( keyboard_latch_w ) |
| 293 | { |
| 294 | /* |
| 295 | |
| 296 | bit description |
| 297 | |
| 298 | 0 D |
| 299 | 1 C |
| 300 | 2 B |
| 301 | 3 A |
| 302 | 4 |
| 303 | 5 |
| 304 | 6 |
| 305 | 7 |
| 306 | |
| 307 | */ |
| 308 | |
| 309 | trs80m2_state *state = (trs80m2_state *)space->machine->driver_data; |
| 310 | |
| 311 | state->key_latch = BITSWAP8(data, 7, 6, 5, 4, 0, 1, 2, 3) & 0x0f; |
| 312 | } |
| 313 | |
| 314 | /* Memory Maps */ |
| 315 | |
| 316 | static ADDRESS_MAP_START( z80_mem, ADDRESS_SPACE_PROGRAM, 8 ) |
| 317 | AM_RANGE(0x0000, 0xf7ff) AM_RAM |
| 318 | AM_RANGE(0xf800, 0xffff) AM_RAM AM_BASE_MEMBER(trs80m2_state, video_ram) |
| 319 | ADDRESS_MAP_END |
| 320 | |
| 321 | static ADDRESS_MAP_START( z80_io, ADDRESS_SPACE_IO, 8 ) |
| 322 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 323 | AM_RANGE(0xe0, 0xe3) AM_DEVREADWRITE(Z80PIO_TAG, z80pio_cd_ba_r, z80pio_cd_ba_w) |
| 324 | AM_RANGE(0xe4, 0xe7) AM_DEVREADWRITE(FD1791_TAG, wd17xx_r, wd17xx_w) |
| 325 | AM_RANGE(0xef, 0xef) AM_DEVWRITE(FD1791_TAG, drvslt_w) |
| 326 | AM_RANGE(0xf0, 0xf3) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_r, z80ctc_w) |
| 327 | AM_RANGE(0xf4, 0xf7) AM_DEVREADWRITE(Z80SIO_TAG, z80sio_cd_ba_r, z80sio_cd_ba_w) |
| 328 | AM_RANGE(0xf8, 0xf8) AM_DEVREADWRITE(Z80DMA_TAG, z80dma_r, z80dma_w) |
| 329 | AM_RANGE(0xf9, 0xf9) AM_WRITE(rom_enable_w) |
| 330 | AM_RANGE(0xfc, 0xfc) AM_READ(keyboard_r) AM_DEVWRITE(MC6845_TAG, mc6845_address_w) |
| 331 | AM_RANGE(0xfd, 0xfd) AM_DEVREADWRITE(MC6845_TAG, mc6845_register_r, mc6845_register_w) |
| 332 | AM_RANGE(0xfe, 0xfe) AM_READ(rtc_r) |
| 333 | AM_RANGE(0xff, 0xff) AM_READWRITE(nmi_r, nmi_w) |
| 334 | ADDRESS_MAP_END |
| 335 | |
| 336 | static ADDRESS_MAP_START( trs80m2_keyboard_io, ADDRESS_SPACE_IO, 8 ) |
| 337 | AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(keyboard_busy_r) |
| 338 | AM_RANGE(MCS48_PORT_P0, MCS48_PORT_P0) AM_READ(keyboard_data_r) |
| 339 | AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(keyboard_ctrl_w) |
| 340 | AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(keyboard_latch_w) |
| 341 | ADDRESS_MAP_END |
| 342 | |
| 343 | static ADDRESS_MAP_START( m68000_mem, ADDRESS_SPACE_PROGRAM, 16 ) |
| 344 | ADDRESS_MAP_END |
| 345 | |
| 346 | /* Input Ports */ |
| 347 | |
| 348 | static INPUT_PORTS_START( trs80m2 ) |
| 349 | PORT_START("ROW0") |
| 350 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 351 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') |
| 352 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') |
| 353 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') |
| 354 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') |
| 355 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) |
| 356 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') |
| 357 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 358 | |
| 359 | PORT_START("ROW1") |
| 360 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 361 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') |
| 362 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') |
| 363 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') |
| 364 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') |
| 365 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x93") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) |
| 366 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') |
| 367 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 368 | |
| 369 | PORT_START("ROW2") |
| 370 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("REPEAT") |
| 371 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Right SHIFT") PORT_CODE(KEYCODE_RSHIFT) |
| 372 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) |
| 373 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) |
| 374 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("LOCK") |
| 375 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 376 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) |
| 377 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 378 | |
| 379 | PORT_START("ROW3") |
| 380 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("cannot read label") |
| 381 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') |
| 382 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') |
| 383 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') |
| 384 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') |
| 385 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) |
| 386 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) |
| 387 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x90") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) |
| 388 | |
| 389 | PORT_START("ROW4") |
| 390 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BACKSPACE") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) |
| 391 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') |
| 392 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') |
| 393 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') |
| 394 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') |
| 395 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) |
| 396 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) |
| 397 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x92") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) |
| 398 | |
| 399 | PORT_START("ROW5") |
| 400 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("HOLD") |
| 401 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') |
| 402 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') |
| 403 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') |
| 404 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') |
| 405 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) |
| 406 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) |
| 407 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) |
| 408 | |
| 409 | PORT_START("ROW6") |
| 410 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 411 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') |
| 412 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') |
| 413 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') |
| 414 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') |
| 415 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad ENTER") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(13) |
| 416 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) |
| 417 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) |
| 418 | |
| 419 | PORT_START("ROW7") |
| 420 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 421 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') |
| 422 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') |
| 423 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') |
| 424 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') |
| 425 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 426 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) |
| 427 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) |
| 428 | |
| 429 | PORT_START("ROW8") |
| 430 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 431 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') |
| 432 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') |
| 433 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') |
| 434 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') |
| 435 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 436 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) |
| 437 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) |
| 438 | |
| 439 | PORT_START("ROW9") |
| 440 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 441 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') |
| 442 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') |
| 443 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') |
| 444 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') |
| 445 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 446 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 447 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 448 | |
| 449 | PORT_START("ROW10") |
| 450 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 451 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') |
| 452 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') |
| 453 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') |
| 454 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') |
| 455 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 456 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) |
| 457 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 458 | |
| 459 | PORT_START("ROW11") |
| 460 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 461 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') |
| 462 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') |
| 463 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') |
| 464 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') |
| 465 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 466 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t') |
| 467 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 468 | INPUT_PORTS_END |
| 469 | |
| 470 | /* Video */ |
| 471 | |
| 472 | static MC6845_UPDATE_ROW( trs80m2_update_row ) |
| 473 | { |
| 474 | trs80m2_state *state = (trs80m2_state *)device->machine->driver_data; |
| 475 | |
| 476 | for (int column = 0; column < x_count; column++) |
| 477 | { |
| 478 | int bit; |
| 479 | |
| 480 | UINT16 address = (state->video_ram[(ma + column) & 0x7ff] << 4) | (ra & 0x0f); |
| 481 | UINT8 data = state->char_rom[address & 0x7ff]; |
| 482 | |
| 483 | if (column == cursor_x) |
| 484 | { |
| 485 | data = 0xff; |
| 486 | } |
| 487 | |
| 488 | for (bit = 0; bit < 8; bit++) |
| 489 | { |
| 490 | int x = (column * 8) + bit; |
| 491 | |
| 492 | *BITMAP_ADDR16(bitmap, y, x) = BIT(data, 7); |
| 493 | |
| 494 | data <<= 1; |
| 495 | } |
| 496 | } |
| 497 | } |
| 498 | |
| 499 | static WRITE_LINE_DEVICE_HANDLER( de_w ) |
| 500 | { |
| 501 | trs80m2_state *driver_state = (trs80m2_state *)device->machine->driver_data; |
| 502 | |
| 503 | driver_state->de = state; |
| 504 | } |
| 505 | |
| 506 | static WRITE_LINE_DEVICE_HANDLER( vsync_w ) |
| 507 | { |
| 508 | trs80m2_state *driver_state = (trs80m2_state *)device->machine->driver_data; |
| 509 | |
| 510 | if (state) |
| 511 | { |
| 512 | driver_state->rtc_int = !driver_state->rtc_int; |
| 513 | |
| 514 | if (driver_state->enable_rtc_int && driver_state->rtc_int) |
| 515 | { |
| 516 | /* trigger RTC interrupt */ |
| 517 | cputag_set_input_line(device->machine, Z80_TAG, INPUT_LINE_NMI, ASSERT_LINE); |
| 518 | } |
| 519 | } |
| 520 | } |
| 521 | |
| 522 | static const mc6845_interface mc6845_intf = |
| 523 | { |
| 524 | SCREEN_TAG, |
| 525 | 8, |
| 526 | NULL, |
| 527 | trs80m2_update_row, |
| 528 | NULL, |
| 529 | DEVCB_LINE(de_w), |
| 530 | DEVCB_NULL, |
| 531 | DEVCB_NULL, |
| 532 | DEVCB_LINE(vsync_w), |
| 533 | NULL |
| 534 | }; |
| 535 | |
| 536 | static VIDEO_START( trs80m2 ) |
| 537 | { |
| 538 | trs80m2_state *state = (trs80m2_state *)machine->driver_data; |
| 539 | |
| 540 | /* find devices */ |
| 541 | state->mc6845 = devtag_get_device(machine, MC6845_TAG); |
| 542 | |
| 543 | /* find memory regions */ |
| 544 | state->char_rom = memory_region(machine, MC6845_TAG); |
| 545 | } |
| 546 | |
| 547 | static VIDEO_UPDATE( trs80m2 ) |
| 548 | { |
| 549 | trs80m2_state *state = (trs80m2_state *)screen->machine->driver_data; |
| 550 | |
| 551 | if (state->blnkvid) |
| 552 | { |
| 553 | bitmap_fill(bitmap, cliprect, get_black_pen(screen->machine)); |
| 554 | } |
| 555 | else |
| 556 | { |
| 557 | mc6845_update(state->mc6845, bitmap, cliprect); |
| 558 | } |
| 559 | |
| 560 | return 0; |
| 561 | } |
| 562 | |
| 563 | /* Z80-DMA Interface */ |
| 564 | |
| 565 | static Z80DMA_INTERFACE( dma_intf ) |
| 566 | { |
| 567 | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_HALT), |
| 568 | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0), |
| 569 | DEVCB_NULL, |
| 570 | DEVCB_MEMORY_HANDLER(Z80_TAG, PROGRAM, memory_read_byte), |
| 571 | DEVCB_MEMORY_HANDLER(Z80_TAG, PROGRAM, memory_write_byte), |
| 572 | DEVCB_MEMORY_HANDLER(Z80_TAG, IO, memory_read_byte), |
| 573 | DEVCB_MEMORY_HANDLER(Z80_TAG, IO, memory_write_byte) |
| 574 | }; |
| 575 | |
| 576 | /* Z80-PIO Interface */ |
| 577 | |
| 578 | static READ8_DEVICE_HANDLER( pio_pa_r ) |
| 579 | { |
| 580 | /* |
| 581 | |
| 582 | bit signal description |
| 583 | |
| 584 | 0 INTRQ FDC INT request |
| 585 | 1 _TWOSID 2-sided diskette |
| 586 | 2 _DSKCHG disk change |
| 587 | 3 PRIME prime |
| 588 | 4 FAULT printer fault |
| 589 | 5 PSEL printer select |
| 590 | 6 PE paper empty |
| 591 | 7 BUSY printer busy |
| 592 | |
| 593 | */ |
| 594 | |
| 595 | trs80m2_state *state = (trs80m2_state *)device->machine->driver_data; |
| 596 | |
| 597 | UINT8 data = 0; |
| 598 | |
| 599 | /* floppy interrupt */ |
| 600 | data |= state->fdc_intrq; |
| 601 | |
| 602 | /* 2-sided diskette */ |
| 603 | data |= floppy_twosid_r(state->floppy) << 1; |
| 604 | |
| 605 | /* disk change */ |
| 606 | data |= floppy_dskchg_r(state->floppy) << 2; |
| 607 | |
| 608 | /* printer fault */ |
| 609 | data |= centronics_fault_r(state->centronics) << 4; |
| 610 | |
| 611 | /* paper empty */ |
| 612 | data |= !centronics_pe_r(state->centronics) << 6; |
| 613 | |
| 614 | /* printer busy */ |
| 615 | data |= centronics_busy_r(state->centronics) << 7; |
| 616 | |
| 617 | return data; |
| 618 | } |
| 619 | |
| 620 | static WRITE8_DEVICE_HANDLER( pio_pa_w ) |
| 621 | { |
| 622 | /* |
| 623 | |
| 624 | bit signal description |
| 625 | |
| 626 | 0 INTRQ FDC INT request |
| 627 | 1 _TWOSID 2-sided diskette |
| 628 | 2 _DSKCHG disk change |
| 629 | 3 PRIME prime |
| 630 | 4 FAULT printer fault |
| 631 | 5 PSEL printer select |
| 632 | 6 PE paper empty |
| 633 | 7 BUSY printer busy |
| 634 | |
| 635 | */ |
| 636 | |
| 637 | trs80m2_state *state = (trs80m2_state *)device->machine->driver_data; |
| 638 | |
| 639 | /* prime */ |
| 640 | centronics_prime_w(state->centronics, BIT(data, 3)); |
| 641 | } |
| 642 | |
| 643 | static WRITE_LINE_DEVICE_HANDLER( strobe_w ) |
| 644 | { |
| 645 | centronics_strobe_w(device, !state); |
| 646 | } |
| 647 | |
| 648 | static Z80PIO_INTERFACE( pio_intf ) |
| 649 | { |
| 650 | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0), /* interrupt callback */ |
| 651 | DEVCB_HANDLER(pio_pa_r), /* port A read callback */ |
| 652 | DEVCB_HANDLER(pio_pa_w), /* port A write callback */ |
| 653 | DEVCB_NULL, /* port A ready callback */ |
| 654 | DEVCB_NULL, /* port B read callback */ |
| 655 | DEVCB_DEVICE_HANDLER(CENTRONICS_TAG, centronics_data_w), /* port B write callback */ |
| 656 | DEVCB_DEVICE_LINE(CENTRONICS_TAG, strobe_w) /* port B ready callback */ |
| 657 | }; |
| 658 | |
| 659 | /* Centronics Interface */ |
| 660 | |
| 661 | static const centronics_interface centronics_intf = |
| 662 | { |
| 663 | 0, /* is IBM PC? */ |
| 664 | DEVCB_DEVICE_LINE(Z80PIO_TAG, z80pio_bstb_w), /* ACK output */ |
| 665 | DEVCB_NULL, /* BUSY output */ |
| 666 | DEVCB_NULL /* NOT BUSY output */ |
| 667 | }; |
| 668 | |
| 669 | /* Z80-SIO/0 Interface */ |
| 670 | |
| 671 | static void sio_interrupt(running_device *device, int state) |
| 672 | { |
| 673 | cputag_set_input_line(device->machine, Z80_TAG, INPUT_LINE_IRQ0, state); |
| 674 | } |
| 675 | |
| 676 | static const z80sio_interface sio_intf = |
| 677 | { |
| 678 | sio_interrupt, /* interrupt handler */ |
| 679 | NULL, /* DTR changed handler */ |
| 680 | NULL, /* RTS changed handler */ |
| 681 | NULL, /* BREAK changed handler */ |
| 682 | NULL, /* transmit handler */ |
| 683 | NULL /* receive handler */ |
| 684 | }; |
| 685 | |
| 686 | /* Z80-CTC Interface */ |
| 687 | |
| 688 | static TIMER_DEVICE_CALLBACK( ctc_tick ) |
| 689 | { |
| 690 | trs80m2_state *state = (trs80m2_state *) timer->machine->driver_data; |
| 691 | |
| 692 | z80ctc_trg0_w(state->z80ctc, 1); |
| 693 | z80ctc_trg0_w(state->z80ctc, 0); |
| 694 | |
| 695 | z80ctc_trg1_w(state->z80ctc, 1); |
| 696 | z80ctc_trg1_w(state->z80ctc, 0); |
| 697 | |
| 698 | z80ctc_trg2_w(state->z80ctc, 1); |
| 699 | z80ctc_trg2_w(state->z80ctc, 0); |
| 700 | } |
| 701 | |
| 702 | static Z80CTC_INTERFACE( ctc_intf ) |
| 703 | { |
| 704 | 0, /* timer disables */ |
| 705 | DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0), /* interrupt handler */ |
| 706 | DEVCB_NULL, // DEVCB_DEVICE_LINE(Z80SIO_TAG, z80sio_rxca_w), /* ZC/TO0 callback */ |
| 707 | DEVCB_NULL, // DEVCB_DEVICE_LINE(Z80SIO_TAG, z80sio_txca_w), /* ZC/TO1 callback */ |
| 708 | DEVCB_NULL, // DEVCB_DEVICE_LINE(Z80SIO_TAG, z80sio_rxtxcb_w) /* ZC/TO2 callback */ |
| 709 | }; |
| 710 | |
| 711 | /* FD1791 Interface */ |
| 712 | |
| 713 | static const floppy_config trs80m2_floppy_config = |
| 714 | { |
| 715 | DEVCB_NULL, |
| 716 | DEVCB_NULL, |
| 717 | DEVCB_NULL, |
| 718 | DEVCB_NULL, |
| 719 | DEVCB_NULL, |
| 720 | FLOPPY_DRIVE_DS_80, |
| 721 | FLOPPY_OPTIONS_NAME(default), |
| 722 | DO_NOT_KEEP_GEOMETRY |
| 723 | }; |
| 724 | |
| 725 | static WRITE_LINE_DEVICE_HANDLER( fdc_intrq_w ) |
| 726 | { |
| 727 | trs80m2_state *driver_state = (trs80m2_state *)device->machine->driver_data; |
| 728 | |
| 729 | driver_state->fdc_intrq = state; |
| 730 | |
| 731 | z80pio_pa_w(driver_state->z80pio, 0, state); |
| 732 | } |
| 733 | |
| 734 | static const wd17xx_interface fd1791_intf = |
| 735 | { |
| 736 | DEVCB_NULL, |
| 737 | DEVCB_LINE(fdc_intrq_w), |
| 738 | DEVCB_DEVICE_LINE(Z80DMA_TAG, z80dma_rdy_w), |
| 739 | { FLOPPY_0, NULL, NULL, NULL } |
| 740 | }; |
| 741 | |
| 742 | /* Z80 Daisy Chain */ |
| 743 | |
| 744 | static const z80_daisy_chain trs80m2_daisy_chain[] = |
| 745 | { |
| 746 | { Z80CTC_TAG }, |
| 747 | { Z80SIO_TAG }, |
| 748 | { Z80DMA_TAG }, |
| 749 | { Z80PIO_TAG }, |
| 750 | { NULL } |
| 751 | }; |
| 752 | |
| 753 | /* Machine Initialization */ |
| 754 | |
| 755 | static MACHINE_START( trs80m2 ) |
| 756 | { |
| 757 | trs80m2_state *state = (trs80m2_state *)machine->driver_data; |
| 758 | |
| 759 | /* find devices */ |
| 760 | state->z80ctc = devtag_get_device(machine, Z80CTC_TAG); |
| 761 | state->z80pio = devtag_get_device(machine, Z80PIO_TAG); |
| 762 | state->mc6845 = devtag_get_device(machine, MC6845_TAG); |
| 763 | state->centronics = devtag_get_device(machine, CENTRONICS_TAG); |
| 764 | state->floppy = devtag_get_device(machine, FLOPPY_0); |
| 765 | |
| 766 | /* Shugart SA-800 motor spins constantly */ |
| 767 | floppy_mon_w(state->floppy, CLEAR_LINE); |
| 768 | |
| 769 | /* register for state saving */ |
| 770 | state_save_register_global(machine, state->boot_rom); |
| 771 | state_save_register_global(machine, state->bank); |
| 772 | state_save_register_global(machine, state->msel); |
| 773 | state_save_register_global(machine, state->fdc_intrq); |
| 774 | state_save_register_global(machine, state->key_latch); |
| 775 | state_save_register_global(machine, state->key_data); |
| 776 | state_save_register_global(machine, state->key_bit); |
| 777 | state_save_register_global(machine, state->kbclk); |
| 778 | state_save_register_global(machine, state->kbdata); |
| 779 | state_save_register_global(machine, state->kbirq); |
| 780 | state_save_register_global(machine, state->blnkvid); |
| 781 | state_save_register_global(machine, state->_80_40_char_en); |
| 782 | state_save_register_global(machine, state->de); |
| 783 | state_save_register_global(machine, state->rtc_int); |
| 784 | state_save_register_global(machine, state->enable_rtc_int); |
| 785 | } |
| 786 | |
| 787 | static MACHINE_RESET( trs80m2 ) |
| 788 | { |
| 789 | trs80m2_state *state = (trs80m2_state *)machine->driver_data; |
| 790 | |
| 791 | /* clear keyboard interrupt */ |
| 792 | state->kbirq = 1; |
| 793 | |
| 794 | /* enable boot ROM */ |
| 795 | state->boot_rom = 1; |
| 796 | |
| 797 | /* disable video RAM */ |
| 798 | state->msel = 0; |
| 799 | |
| 800 | bankswitch(machine); |
| 801 | } |
| 802 | |
| 803 | /* Machine Driver */ |
| 804 | |
| 805 | static MACHINE_DRIVER_START( trs80m2 ) |
| 806 | MDRV_DRIVER_DATA(trs80m2_state) |
| 807 | |
| 808 | /* basic machine hardware */ |
| 809 | MDRV_CPU_ADD(Z80_TAG, Z80, XTAL_8MHz/2) |
| 810 | MDRV_CPU_CONFIG(trs80m2_daisy_chain) |
| 811 | MDRV_CPU_PROGRAM_MAP(z80_mem) |
| 812 | MDRV_CPU_IO_MAP(z80_io) |
| 813 | |
| 814 | // MDRV_CPU_ADD(I8021_TAG, I8021, 100000) |
| 815 | // MDRV_CPU_IO_MAP(trs80m2_keyboard_io) |
| 816 | |
| 817 | MDRV_MACHINE_START(trs80m2) |
| 818 | MDRV_MACHINE_RESET(trs80m2) |
| 819 | |
| 820 | /* video hardware */ |
| 821 | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER) |
| 822 | MDRV_SCREEN_REFRESH_RATE(60) |
| 823 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) |
| 824 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 825 | MDRV_SCREEN_SIZE(640, 480) |
| 826 | MDRV_SCREEN_VISIBLE_AREA(0, 639, 0, 479) |
| 827 | |
| 828 | MDRV_PALETTE_LENGTH(2) |
| 829 | MDRV_PALETTE_INIT(black_and_white) |
| 830 | |
| 831 | MDRV_VIDEO_START(trs80m2) |
| 832 | MDRV_VIDEO_UPDATE(trs80m2) |
| 833 | |
| 834 | MDRV_MC6845_ADD(MC6845_TAG, MC6845, XTAL_12_48MHz/8, mc6845_intf) |
| 835 | |
| 836 | /* devices */ |
| 837 | MDRV_WD179X_ADD(FD1791_TAG, fd1791_intf) |
| 838 | MDRV_Z80CTC_ADD(Z80CTC_TAG, XTAL_8MHz/2, ctc_intf) |
| 839 | MDRV_TIMER_ADD_PERIODIC("ctc", ctc_tick, HZ(XTAL_8MHz/2/2)) |
| 840 | MDRV_Z80DMA_ADD(Z80DMA_TAG, XTAL_8MHz/2, dma_intf) |
| 841 | MDRV_Z80PIO_ADD(Z80PIO_TAG, XTAL_8MHz/2, pio_intf) |
| 842 | MDRV_Z80SIO_ADD(Z80SIO_TAG, XTAL_8MHz/2, sio_intf) |
| 843 | MDRV_CENTRONICS_ADD(CENTRONICS_TAG, centronics_intf) |
| 844 | MDRV_FLOPPY_DRIVE_ADD(FLOPPY_0, trs80m2_floppy_config) |
| 845 | |
| 846 | /* internal RAM */ |
| 847 | MDRV_RAM_ADD("messram") |
| 848 | MDRV_RAM_DEFAULT_SIZE("32K") |
| 849 | MDRV_RAM_EXTRA_OPTIONS("64K,96K,128K,160K,192K,224K,256K,288K,320K,352K,384K,416K,448K,480K,512K") |
| 850 | MACHINE_DRIVER_END |
| 851 | |
| 852 | static MACHINE_DRIVER_START( trs80m16 ) |
| 853 | MDRV_IMPORT_FROM(trs80m2) |
| 854 | |
| 855 | /* basic machine hardware */ |
| 856 | // MDRV_CPU_ADD(M68000_TAG, M68000, 6000000) |
| 857 | // MDRV_CPU_PROGRAM_MAP(m68000_mem) |
| 858 | |
| 859 | /* video hardware */ |
| 860 | MDRV_PALETTE_INIT(monochrome_green) |
| 861 | |
| 862 | /* internal RAM */ |
| 863 | MDRV_RAM_MODIFY("messram") |
| 864 | MDRV_RAM_DEFAULT_SIZE("256K") |
| 865 | MDRV_RAM_EXTRA_OPTIONS("512K,768K,1M") |
| 866 | MACHINE_DRIVER_END |
| 867 | |
| 868 | /* ROMs */ |
| 869 | |
| 870 | ROM_START( trs80m2 ) |
| 871 | ROM_REGION( 0x800, Z80_TAG, 0 ) |
| 872 | ROM_LOAD( "8043216.u11", 0x0000, 0x0800, CRC(7017a373) SHA1(1c7127fcc99fc351a40d3a3199ba478e783c452e) ) |
| 873 | |
| 874 | ROM_REGION( 0x800, MC6845_TAG, 0 ) |
| 875 | ROM_LOAD( "8043316.u9", 0x0000, 0x0800, CRC(04425b03) SHA1(32a29dc202b7fcf21838289cc3bffc51ef943dab) ) |
| 876 | |
| 877 | ROM_REGION( 0x400, I8021_TAG, 0 ) |
| 878 | ROM_LOAD( "65-1991.z4", 0x0000, 0x0400, NO_DUMP ) |
| 879 | ROM_END |
| 880 | |
| 881 | /* |
| 882 | |
| 883 | TRS-80 Model II/16 Z80 CPU Board ROM |
| 884 | |
| 885 | It would seem that every processor board I find has a different ROM on it! It seems that the early ROMs |
| 886 | don't boot directly from a hard drive. But there seems to be many versions of ROMs. I've placed them in |
| 887 | order of serial number in the list below. There also appears to be at least two board revisions, "C" and "D". |
| 888 | |
| 889 | cpu_c8ff.bin/hex: |
| 890 | Mask Programmable PROM, Equivilant to Intel 2716 EPROM, with checksum C8FF came from a cpu board with |
| 891 | serial number 120353 out of a Model II with serial number 2002102 and catalog number 26-6002. The board |
| 892 | was labeled, "Revision C". This appears to be an early ROM and according to a very helpful fellow |
| 893 | collector, Aaron in Australia, doesn't allow boot directly from a hard disk. |
| 894 | |
| 895 | cpu_9733.bin/hex: |
| 896 | An actual SGS-Ates (Now STMicroelectronics) 2716 EPROM, with checksum 9733 came from a cpu board with |
| 897 | serial number 161993 out of a pile of random cards that I have. I don't know what machine it originated |
| 898 | from. The board was labeled, "Revision C". This appears to be a later ROM in that it is able to boot |
| 899 | directly from an 8MB hard disk. The EPROM had a windows sticker on it labeled, "U54". |
| 900 | |
| 901 | cpu_2119.bin/hex: |
| 902 | An actual Texas Instruments 2716 EPROM, with checksum 2119 came from a cpu board with serial number |
| 903 | 178892 out of a Model 16 with serial number 64014509 and catalog number 26-4002. The board was labeled, |
| 904 | "Revision D". This appears to be a later ROM and does appear to allow boot directly from an 8MB hard disk. |
| 905 | |
| 906 | cpu_2bff.bin/hex: |
| 907 | Mask Programmable PROM, Equivilant to Intel 2716 EPROM, with checksum 2BFF came from a cpu board with |
| 908 | serial number 187173 our of a pile of random cards that I have. I don't know what machine it originated |
| 909 | from. The board was labeled, "Revision D". This appears to be a later ROM in that it is able to boot |
| 910 | directly from an 8MB hard disk. |
| 911 | |
| 912 | */ |
| 913 | |
| 914 | ROM_START( trs80m16 ) |
| 915 | ROM_REGION( 0x800, Z80_TAG, 0 ) |
| 916 | ROM_SYSTEM_BIOS( 0, "c8ff", "S/N 120353" ) |
| 917 | ROMX_LOAD( "cpu_c8ff.u11", 0x0000, 0x0800, CRC(7017a373) SHA1(1c7127fcc99fc351a40d3a3199ba478e783c452e), ROM_BIOS(1) ) |
| 918 | ROM_SYSTEM_BIOS( 1, "9733", "S/N 161993" ) |
| 919 | ROMX_LOAD( "cpu_9733.u11", 0x0000, 0x0800, CRC(823924b1) SHA1(aee0625bcbd8620b28ab705e15ad9bea804c8476), ROM_BIOS(2) ) |
| 920 | ROM_SYSTEM_BIOS( 2, "2119", "S/N 64014509" ) |
| 921 | ROMX_LOAD( "cpu_2119.u11", 0x0000, 0x0800, CRC(7a663049) SHA1(f308439ce266df717bfe79adcdad6024b4faa141), ROM_BIOS(3) ) |
| 922 | ROM_SYSTEM_BIOS( 3, "2bff", "S/N 187173" ) |
| 923 | ROMX_LOAD( "cpu_2bff.u11", 0x0000, 0x0800, CRC(c6c71d8b) SHA1(7107e2cbbe769851a4460680c2deff8e76a101b5), ROM_BIOS(4) ) |
| 924 | |
| 925 | ROM_REGION( 0x800, MC6845_TAG, 0 ) |
| 926 | ROM_LOAD( "8043316.u9", 0x0000, 0x0800, CRC(04425b03) SHA1(32a29dc202b7fcf21838289cc3bffc51ef943dab) ) |
| 927 | |
| 928 | ROM_REGION( 0x400, I8021_TAG, 0 ) |
| 929 | ROM_LOAD( "65-1991.z4", 0x0000, 0x0400, NO_DUMP ) |
| 930 | |
| 931 | ROM_REGION( 0x1000, M68000_TAG, 0 ) |
| 932 | ROM_LOAD( "m68000.rom", 0x0000, 0x1000, NO_DUMP ) |
| 933 | ROM_END |
| 934 | |
| 935 | /* System Drivers */ |
| 936 | |
| 937 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 938 | COMP( 1979, trs80m2, 0, 0, trs80m2, trs80m2, 0, "Tandy Radio Shack", "TRS-80 Model II", GAME_NO_SOUND_HW | GAME_NOT_WORKING ) |
| 939 | COMP( 1982, trs80m16, trs80m2, 0, trs80m16, trs80m2, 0, "Tandy Radio Shack", "TRS-80 Model 16", GAME_NO_SOUND_HW | GAME_NOT_WORKING ) |
| 940 | //COMP( 1983, trs80m12, trs80m2, 0, trs80m16, trs80m2, 0, "Tandy Radio Shack", "TRS-80 Model 12", GAME_NO_SOUND_HW | GAME_NOT_WORKING ) |
| 941 | //COMP( 1984, trs80m16b,trs80m2, 0, trs80m16, trs80m2, 0, "Tandy Radio Shack", "TRS-80 Model 16B", GAME_NO_SOUND_HW | GAME_NOT_WORKING ) |
| 942 | //COMP( 1985, tandy6k, trs80m2, 0, tandy6k, trs80m2, 0, "Tandy Radio Shack", "Tandy 6000 HD", GAME_NO_SOUND_HW | GAME_NOT_WORKING ) |
src/mess/drivers/victor9k.c
| r7571 | r7572 | |
| 1 | | /***************************************************************************
|
| 2 | | |
| 3 | | Victor 9000
|
| 4 | | |
| 5 | | - very exciting hardware, disk controller is a direct descendant
|
| 6 | | of the Commodore drives (designed by Chuck Peddle)
|
| 7 | | |
| 8 | | Skeleton driver
|
| 9 | | |
| 10 | | ***************************************************************************/
|
| 11 | | |
| 12 | | /*
|
| 13 | | |
| 14 | | TODO:
|
| 15 | | |
| 16 | | - floppy 8048
|
| 17 | | - keyboard
|
| 18 | | - add HD46505S variant to mc6845.c
|
| 19 | | - hires graphics
|
| 20 | | - character attributes
|
| 21 | | - brightness/contrast
|
| 22 | | - MC6852
|
| 23 | | - codec sound
|
| 24 | | |
| 25 | | */
|
| 26 | | |
| 27 | | #include "emu.h"
|
| 28 | | #include "includes/victor9k.h"
|
| 29 | | #include "cpu/i86/i86.h"
|
| 30 | | #include "cpu/mcs48/mcs48.h"
|
| 31 | | #include "devices/flopdrv.h"
|
| 32 | | #include "devices/messram.h"
|
| 33 | | #include "machine/ctronics.h"
|
| 34 | | #include "machine/6522via.h"
|
| 35 | | #include "machine/ieee488.h"
|
| 36 | | #include "machine/pit8253.h"
|
| 37 | | #include "machine/pic8259.h"
|
| 38 | | #include "machine/upd7201.h"
|
| 39 | | #include "sound/hc55516.h"
|
| 40 | | #include "video/mc6845.h"
|
| 41 | | |
| 42 | | /* Memory Maps */
|
| 43 | | |
| 44 | | static ADDRESS_MAP_START( victor9k_mem, ADDRESS_SPACE_PROGRAM, 8 )
|
| 45 | | // AM_RANGE(0x00000, 0xdffff) AM_RAM
|
| 46 | | AM_RANGE(0xe0000, 0xe0001) AM_DEVREADWRITE(I8259A_TAG, pic8259_r, pic8259_w)
|
| 47 | | AM_RANGE(0xe0020, 0xe0023) AM_DEVREADWRITE(I8253_TAG, pit8253_r, pit8253_w)
|
| 48 | | AM_RANGE(0xe0040, 0xe0043) AM_DEVREADWRITE(UPD7201_TAG, upd7201_cd_ba_r, upd7201_cd_ba_w)
|
| 49 | | AM_RANGE(0xe8000, 0xe8000) AM_DEVREADWRITE(HD46505S_TAG, mc6845_status_r, mc6845_address_w)
|
| 50 | | AM_RANGE(0xe8001, 0xe8001) AM_DEVREADWRITE(HD46505S_TAG, mc6845_register_r, mc6845_register_w)
|
| 51 | | AM_RANGE(0xe8020, 0xe802f) AM_DEVREADWRITE(M6522_1_TAG, via_r, via_w)
|
| 52 | | AM_RANGE(0xe8040, 0xe804f) AM_DEVREADWRITE(M6522_2_TAG, via_r, via_w)
|
| 53 | | // AM_RANGE(0xe8060, 0xe806f) AM_DEVREADWRITE(MC6852_TAG, mc6852_r, mc6852_w)
|
| 54 | | AM_RANGE(0xe8080, 0xe808f) AM_DEVREADWRITE(M6522_3_TAG, via_r, via_w)
|
| 55 | | AM_RANGE(0xe80a0, 0xe80af) AM_DEVREADWRITE(M6522_4_TAG, via_r, via_w)
|
| 56 | | AM_RANGE(0xe80c0, 0xe80cf) AM_DEVREADWRITE(M6522_6_TAG, via_r, via_w)
|
| 57 | | AM_RANGE(0xe80e0, 0xe80ef) AM_DEVREADWRITE(M6522_5_TAG, via_r, via_w)
|
| 58 | | AM_RANGE(0xf0000, 0xf0fff) AM_MIRROR(0x1000) AM_RAM AM_BASE_MEMBER(victor9k_state, video_ram)
|
| 59 | | AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION(I8088_TAG, 0)
|
| 60 | | ADDRESS_MAP_END
|
| 61 | | |
| 62 | | static ADDRESS_MAP_START( floppy_io, ADDRESS_SPACE_IO, 8 )
|
| 63 | | // AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1)
|
| 64 | | // AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2)
|
| 65 | | // AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1)
|
| 66 | | // AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS)
|
| 67 | | ADDRESS_MAP_END
|
| 68 | | |
| 69 | | static ADDRESS_MAP_START( keyboard_io, ADDRESS_SPACE_IO, 8 )
|
| 70 | | // AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1)
|
| 71 | | // AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2)
|
| 72 | | // AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1)
|
| 73 | | // AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS)
|
| 74 | | ADDRESS_MAP_END
|
| 75 | | |
| 76 | | /* Input Ports */
|
| 77 | | |
| 78 | | static INPUT_PORTS_START( victor9k )
|
| 79 | | INPUT_PORTS_END
|
| 80 | | |
| 81 | | /* Video */
|
| 82 | | |
| 83 | | #define CODE_NON_DISPLAY 0x1000
|
| 84 | | #define CODE_UNDERLINE 0x2000
|
| 85 | | #define CODE_LOW_INTENSITY 0x4000
|
| 86 | | #define CODE_REVERSE_VIDEO 0x8000
|
| 87 | | |
| 88 | | static MC6845_UPDATE_ROW( victor9k_update_row )
|
| 89 | | {
|
| 90 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 91 | | const address_space *program = cputag_get_address_space(device->machine, I8088_TAG, ADDRESS_SPACE_PROGRAM);
|
| 92 | | |
| 93 | | if (BIT(ma, 13))
|
| 94 | | {
|
| 95 | | fatalerror("Graphics mode not supported!");
|
| 96 | | }
|
| 97 | | else
|
| 98 | | {
|
| 99 | | UINT16 video_ram_addr = (ma & 0xfff) << 1;
|
| 100 | | |
| 101 | | for (int sx = 0; sx < x_count; sx++)
|
| 102 | | {
|
| 103 | | UINT16 code = (state->video_ram[video_ram_addr + 1] << 8) | state->video_ram[video_ram_addr];
|
| 104 | | UINT32 char_ram_addr = (BIT(ma, 12) << 16) | ((code & 0xff) << 5) | (ra << 1);
|
| 105 | | UINT16 data = memory_read_word_16le(program, char_ram_addr);
|
| 106 | | |
| 107 | | for (int x = 0; x <= 10; x++)
|
| 108 | | {
|
| 109 | | int color = BIT(data, x);
|
| 110 | | |
| 111 | | if (sx == cursor_x) color = 1;
|
| 112 | | |
| 113 | | *BITMAP_ADDR16(bitmap, y, x + sx*10) = color;
|
| 114 | | }
|
| 115 | | |
| 116 | | video_ram_addr += 2;
|
| 117 | | video_ram_addr &= 0xfff;
|
| 118 | | }
|
| 119 | | }
|
| 120 | | }
|
| 121 | | |
| 122 | | static WRITE_LINE_DEVICE_HANDLER( vsync_w )
|
| 123 | | {
|
| 124 | | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data;
|
| 125 | | |
| 126 | | pic8259_ir7_w(driver_state->pic, state);
|
| 127 | | driver_state->vert = state;
|
| 128 | | }
|
| 129 | | |
| 130 | | static const mc6845_interface hd46505s_intf =
|
| 131 | | {
|
| 132 | | SCREEN_TAG,
|
| 133 | | 10,
|
| 134 | | NULL,
|
| 135 | | victor9k_update_row,
|
| 136 | | NULL,
|
| 137 | | DEVCB_NULL,
|
| 138 | | DEVCB_NULL,
|
| 139 | | DEVCB_NULL,
|
| 140 | | DEVCB_LINE(vsync_w),
|
| 141 | | NULL
|
| 142 | | };
|
| 143 | | |
| 144 | | static VIDEO_START( victor9k )
|
| 145 | | {
|
| 146 | | victor9k_state *state = (victor9k_state *)machine->driver_data;
|
| 147 | | |
| 148 | | /* find devices */
|
| 149 | | state->crt = devtag_get_device(machine, HD46505S_TAG);
|
| 150 | | }
|
| 151 | | |
| 152 | | static VIDEO_UPDATE( victor9k )
|
| 153 | | {
|
| 154 | | victor9k_state *state = (victor9k_state *)screen->machine->driver_data;
|
| 155 | | |
| 156 | | mc6845_update(state->crt, bitmap, cliprect);
|
| 157 | | |
| 158 | | return 0;
|
| 159 | | }
|
| 160 | | |
| 161 | | /* Intel 8253 Interface */
|
| 162 | | |
| 163 | | static WRITE_LINE_DEVICE_HANDLER( mux_serial_b_w )
|
| 164 | | {
|
| 165 | | }
|
| 166 | | |
| 167 | | static WRITE_LINE_DEVICE_HANDLER( mux_serial_a_w )
|
| 168 | | {
|
| 169 | | }
|
| 170 | | |
| 171 | | static const struct pit8253_config pit_intf =
|
| 172 | | {
|
| 173 | | {
|
| 174 | | {
|
| 175 | | 2500000,
|
| 176 | | DEVCB_LINE_VCC,
|
| 177 | | DEVCB_LINE(mux_serial_b_w)
|
| 178 | | }, {
|
| 179 | | 2500000,
|
| 180 | | DEVCB_LINE_VCC,
|
| 181 | | DEVCB_LINE(mux_serial_a_w)
|
| 182 | | }, {
|
| 183 | | 100000,
|
| 184 | | DEVCB_LINE_VCC,
|
| 185 | | DEVCB_DEVICE_LINE(I8259A_TAG, pic8259_ir2_w)
|
| 186 | | }
|
| 187 | | }
|
| 188 | | };
|
| 189 | | |
| 190 | | /* Intel 8259 Interfaces */
|
| 191 | | |
| 192 | | /*
|
| 193 | | |
| 194 | | pin signal description
|
| 195 | | |
| 196 | | IR0 SYN sync detect
|
| 197 | | IR1 COMM serial communications (7201)
|
| 198 | | IR2 TIMER 8253 timer
|
| 199 | | IR3 PARALLEL all 6522 IRQ (including disk)
|
| 200 | | IR4 IR4 expansion IR4
|
| 201 | | IR5 IR5 expansion IR5
|
| 202 | | IR6 KBINT keyboard data ready
|
| 203 | | IR7 VINT vertical sync or nonspecific interrupt
|
| 204 | | |
| 205 | | */
|
| 206 | | |
| 207 | | static const struct pic8259_interface pic_intf =
|
| 208 | | {
|
| 209 | | DEVCB_CPU_INPUT_LINE(I8088_TAG, INPUT_LINE_IRQ0)
|
| 210 | | };
|
| 211 | | |
| 212 | | /* NEC uPD7201 Interface */
|
| 213 | | |
| 214 | | static UPD7201_INTERFACE( mpsc_intf )
|
| 215 | | {
|
| 216 | | DEVCB_DEVICE_LINE(I8259A_TAG, pic8259_ir1_w), /* interrupt */
|
| 217 | | {
|
| 218 | | {
|
| 219 | | 0, /* receive clock */
|
| 220 | | 0, /* transmit clock */
|
| 221 | | DEVCB_NULL, /* receive DRQ */
|
| 222 | | DEVCB_NULL, /* transmit DRQ */
|
| 223 | | DEVCB_NULL, /* receive data */
|
| 224 | | DEVCB_NULL, /* transmit data */
|
| 225 | | DEVCB_NULL, /* clear to send */
|
| 226 | | DEVCB_NULL, /* data carrier detect */
|
| 227 | | DEVCB_NULL, /* ready to send */
|
| 228 | | DEVCB_NULL, /* data terminal ready */
|
| 229 | | DEVCB_NULL, /* wait */
|
| 230 | | DEVCB_NULL /* sync output */
|
| 231 | | }, {
|
| 232 | | 0, /* receive clock */
|
| 233 | | 0, /* transmit clock */
|
| 234 | | DEVCB_NULL, /* receive DRQ */
|
| 235 | | DEVCB_NULL, /* transmit DRQ */
|
| 236 | | DEVCB_NULL, /* receive data */
|
| 237 | | DEVCB_NULL, /* transmit data */
|
| 238 | | DEVCB_NULL, /* clear to send */
|
| 239 | | DEVCB_NULL, /* data carrier detect */
|
| 240 | | DEVCB_NULL, /* ready to send */
|
| 241 | | DEVCB_NULL, /* data terminal ready */
|
| 242 | | DEVCB_NULL, /* wait */
|
| 243 | | DEVCB_NULL /* sync output */
|
| 244 | | }
|
| 245 | | }
|
| 246 | | };
|
| 247 | | |
| 248 | | /* M6522 Interface */
|
| 249 | | |
| 250 | | static READ8_DEVICE_HANDLER( via1_pa_r )
|
| 251 | | {
|
| 252 | | /*
|
| 253 | | |
| 254 | | bit description
|
| 255 | | |
| 256 | | PA0 DIO1
|
| 257 | | PA1 DIO2
|
| 258 | | PA2 DIO3
|
| 259 | | PA3 DIO4
|
| 260 | | PA4 DIO5
|
| 261 | | PA5 DIO6
|
| 262 | | PA6 DIO7
|
| 263 | | PA7 DIO8
|
| 264 | | |
| 265 | | */
|
| 266 | | |
| 267 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 268 | | |
| 269 | | return ieee488_dio_r(state->ieee488, 0);
|
| 270 | | }
|
| 271 | | |
| 272 | | static WRITE8_DEVICE_HANDLER( via1_pa_w )
|
| 273 | | {
|
| 274 | | /*
|
| 275 | | |
| 276 | | bit description
|
| 277 | | |
| 278 | | PA0 DIO1
|
| 279 | | PA1 DIO2
|
| 280 | | PA2 DIO3
|
| 281 | | PA3 DIO4
|
| 282 | | PA4 DIO5
|
| 283 | | PA5 DIO6
|
| 284 | | PA6 DIO7
|
| 285 | | PA7 DIO8
|
| 286 | | |
| 287 | | */
|
| 288 | | |
| 289 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 290 | | |
| 291 | | ieee488_dio_w(state->ieee488, device, data);
|
| 292 | | }
|
| 293 | | |
| 294 | | static READ8_DEVICE_HANDLER( via1_pb_r )
|
| 295 | | {
|
| 296 | | /*
|
| 297 | | |
| 298 | | bit description
|
| 299 | | |
| 300 | | PB0 DAV
|
| 301 | | PB1 EOI
|
| 302 | | PB2 REN
|
| 303 | | PB3 ATN
|
| 304 | | PB4 IFC
|
| 305 | | PB5 SRQ
|
| 306 | | PB6 NRFD
|
| 307 | | PB7 NDAC
|
| 308 | | |
| 309 | | */
|
| 310 | | |
| 311 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 312 | | |
| 313 | | UINT8 data = 0;
|
| 314 | | |
| 315 | | /* data valid */
|
| 316 | | data |= ieee488_dav_r(state->ieee488);
|
| 317 | | |
| 318 | | /* end or identify */
|
| 319 | | data |= ieee488_eoi_r(state->ieee488) << 1;
|
| 320 | | |
| 321 | | /* remote enable */
|
| 322 | | data |= ieee488_ren_r(state->ieee488) << 2;
|
| 323 | | |
| 324 | | /* attention */
|
| 325 | | data |= ieee488_atn_r(state->ieee488) << 3;
|
| 326 | | |
| 327 | | /* interface clear */
|
| 328 | | data |= ieee488_ifc_r(state->ieee488) << 4;
|
| 329 | | |
| 330 | | /* service request */
|
| 331 | | data |= ieee488_srq_r(state->ieee488) << 5;
|
| 332 | | |
| 333 | | /* not ready for data */
|
| 334 | | data |= ieee488_nrfd_r(state->ieee488) << 6;
|
| 335 | | |
| 336 | | /* data not accepted */
|
| 337 | | data |= ieee488_ndac_r(state->ieee488) << 7;
|
| 338 | | |
| 339 | | return data;
|
| 340 | | }
|
| 341 | | |
| 342 | | static WRITE8_DEVICE_HANDLER( via1_pb_w )
|
| 343 | | {
|
| 344 | | /*
|
| 345 | | |
| 346 | | bit description
|
| 347 | | |
| 348 | | PB0 DAV
|
| 349 | | PB1 EOI
|
| 350 | | PB2 REN
|
| 351 | | PB3 ATN
|
| 352 | | PB4 IFC
|
| 353 | | PB5 SRQ
|
| 354 | | PB6 NRFD
|
| 355 | | PB7 NDAC
|
| 356 | | |
| 357 | | */
|
| 358 | | |
| 359 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 360 | | |
| 361 | | /* data valid */
|
| 362 | | ieee488_dav_w(state->ieee488, device, BIT(data, 0));
|
| 363 | | |
| 364 | | /* end or identify */
|
| 365 | | ieee488_eoi_w(state->ieee488, device, BIT(data, 1));
|
| 366 | | |
| 367 | | /* remote enable */
|
| 368 | | ieee488_ren_w(state->ieee488, device, BIT(data, 2));
|
| 369 | | |
| 370 | | /* attention */
|
| 371 | | ieee488_atn_w(state->ieee488, device, BIT(data, 3));
|
| 372 | | |
| 373 | | /* interface clear */
|
| 374 | | ieee488_ifc_w(state->ieee488, device, BIT(data, 4));
|
| 375 | | |
| 376 | | /* service request */
|
| 377 | | ieee488_srq_w(state->ieee488, device, BIT(data, 5));
|
| 378 | | |
| 379 | | /* not ready for data */
|
| 380 | | ieee488_nrfd_w(state->ieee488, device, BIT(data, 6));
|
| 381 | | |
| 382 | | /* data not accepted */
|
| 383 | | ieee488_ndac_w(state->ieee488, device, BIT(data, 7));
|
| 384 | | }
|
| 385 | | |
| 386 | | static WRITE_LINE_DEVICE_HANDLER( codec_vol_w )
|
| 387 | | {
|
| 388 | | }
|
| 389 | | |
| 390 | | static WRITE_LINE_DEVICE_HANDLER( via1_irq_w )
|
| 391 | | {
|
| 392 | | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data;
|
| 393 | | |
| 394 | | driver_state->via1_irq = state;
|
| 395 | | |
| 396 | | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq);
|
| 397 | | }
|
| 398 | | |
| 399 | | static const via6522_interface via1_intf =
|
| 400 | | {
|
| 401 | | DEVCB_HANDLER(via1_pa_r),
|
| 402 | | DEVCB_HANDLER(via1_pb_r),
|
| 403 | | DEVCB_DEVICE_LINE(IEEE488_TAG, ieee488_nrfd_r),
|
| 404 | | DEVCB_NULL,
|
| 405 | | DEVCB_DEVICE_LINE(IEEE488_TAG, ieee488_ndac_r),
|
| 406 | | DEVCB_NULL,
|
| 407 | | |
| 408 | | DEVCB_HANDLER(via1_pa_w),
|
| 409 | | DEVCB_HANDLER(via1_pb_w),
|
| 410 | | DEVCB_NULL,
|
| 411 | | DEVCB_NULL,
|
| 412 | | DEVCB_NULL,
|
| 413 | | DEVCB_LINE(codec_vol_w),
|
| 414 | | |
| 415 | | DEVCB_LINE(via1_irq_w)
|
| 416 | | };
|
| 417 | | |
| 418 | | static READ8_DEVICE_HANDLER( via2_pa_r )
|
| 419 | | {
|
| 420 | | /*
|
| 421 | | |
| 422 | | bit description
|
| 423 | | |
| 424 | | PA0 _INT/EXTA
|
| 425 | | PA1 _INT/EXTB
|
| 426 | | PA2 RIA
|
| 427 | | PA3 DSRA
|
| 428 | | PA4 RIB
|
| 429 | | PA5 DSRB
|
| 430 | | PA6 KBDATA
|
| 431 | | PA7 VERT
|
| 432 | | |
| 433 | | */
|
| 434 | | |
| 435 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 436 | | |
| 437 | | UINT8 data = 0;
|
| 438 | | |
| 439 | | /* vertical sync */
|
| 440 | | data |= state->vert << 7;
|
| 441 | | |
| 442 | | return data;
|
| 443 | | }
|
| 444 | | |
| 445 | | static WRITE8_DEVICE_HANDLER( via2_pa_w )
|
| 446 | | {
|
| 447 | | /*
|
| 448 | | |
| 449 | | bit description
|
| 450 | | |
| 451 | | PA0 _INT/EXTA
|
| 452 | | PA1 _INT/EXTB
|
| 453 | | PA2 RIA
|
| 454 | | PA3 DSRA
|
| 455 | | PA4 RIB
|
| 456 | | PA5 DSRB
|
| 457 | | PA6 KBDATA
|
| 458 | | PA7 VERT
|
| 459 | | |
| 460 | | */
|
| 461 | | }
|
| 462 | | |
| 463 | | static WRITE8_DEVICE_HANDLER( via2_pb_w )
|
| 464 | | {
|
| 465 | | /*
|
| 466 | | |
| 467 | | bit description
|
| 468 | | |
| 469 | | PB0 TALK/LISTEN
|
| 470 | | PB1 KBACKCTL
|
| 471 | | PB2 BRT0
|
| 472 | | PB3 BRT1
|
| 473 | | PB4 BRT2
|
| 474 | | PB5 CONT0
|
| 475 | | PB6 CONT1
|
| 476 | | PB7 CONT2
|
| 477 | | |
| 478 | | */
|
| 479 | | |
| 480 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 481 | | |
| 482 | | /* brightness */
|
| 483 | | state->brt = (data >> 2) & 0x07;
|
| 484 | | |
| 485 | | /* contrast */
|
| 486 | | state->cont = data >> 5;
|
| 487 | | }
|
| 488 | | |
| 489 | | static WRITE_LINE_DEVICE_HANDLER( via2_irq_w )
|
| 490 | | {
|
| 491 | | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data;
|
| 492 | | |
| 493 | | driver_state->via2_irq = state;
|
| 494 | | |
| 495 | | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq);
|
| 496 | | }
|
| 497 | | |
| 498 | | static const via6522_interface via2_intf =
|
| 499 | | {
|
| 500 | | DEVCB_HANDLER(via2_pa_r),
|
| 501 | | DEVCB_NULL,
|
| 502 | | DEVCB_NULL,
|
| 503 | | DEVCB_NULL, // KBRDY
|
| 504 | | DEVCB_NULL, // SRQ/BUSY
|
| 505 | | DEVCB_NULL, // KBDATA
|
| 506 | | |
| 507 | | DEVCB_HANDLER(via2_pa_w),
|
| 508 | | DEVCB_HANDLER(via2_pb_w),
|
| 509 | | DEVCB_NULL,
|
| 510 | | DEVCB_NULL,
|
| 511 | | DEVCB_NULL,
|
| 512 | | DEVCB_NULL,
|
| 513 | | |
| 514 | | DEVCB_LINE(via2_irq_w)
|
| 515 | | };
|
| 516 | | |
| 517 | | static READ8_DEVICE_HANDLER( via3_pa_r )
|
| 518 | | {
|
| 519 | | /*
|
| 520 | | |
| 521 | | bit description
|
| 522 | | |
| 523 | | PA0 J5-16
|
| 524 | | PA1 J5-18
|
| 525 | | PA2 J5-20
|
| 526 | | PA3 J5-22
|
| 527 | | PA4 J5-24
|
| 528 | | PA5 J5-26
|
| 529 | | PA6 J5-28
|
| 530 | | PA7 J5-30
|
| 531 | | |
| 532 | | */
|
| 533 | | |
| 534 | | return 0;
|
| 535 | | }
|
| 536 | | |
| 537 | | static WRITE8_DEVICE_HANDLER( via3_pa_w )
|
| 538 | | {
|
| 539 | | /*
|
| 540 | | |
| 541 | | bit description
|
| 542 | | |
| 543 | | PA0 J5-16
|
| 544 | | PA1 J5-18
|
| 545 | | PA2 J5-20
|
| 546 | | PA3 J5-22
|
| 547 | | PA4 J5-24
|
| 548 | | PA5 J5-26
|
| 549 | | PA6 J5-28
|
| 550 | | PA7 J5-30
|
| 551 | | |
| 552 | | */
|
| 553 | | }
|
| 554 | | |
| 555 | | static READ8_DEVICE_HANDLER( via3_pb_r )
|
| 556 | | {
|
| 557 | | /*
|
| 558 | | |
| 559 | | bit description
|
| 560 | | |
| 561 | | PB0 J5-32
|
| 562 | | PB1 J5-34
|
| 563 | | PB2 J5-36
|
| 564 | | PB3 J5-38
|
| 565 | | PB4 J5-40
|
| 566 | | PB5 J5-42
|
| 567 | | PB6 J5-44
|
| 568 | | PB7 J5-46
|
| 569 | | |
| 570 | | */
|
| 571 | | |
| 572 | | return 0;
|
| 573 | | }
|
| 574 | | |
| 575 | | static WRITE8_DEVICE_HANDLER( via3_pb_w )
|
| 576 | | {
|
| 577 | | /*
|
| 578 | | |
| 579 | | bit description
|
| 580 | | |
| 581 | | PB0 J5-32
|
| 582 | | PB1 J5-34
|
| 583 | | PB2 J5-36
|
| 584 | | PB3 J5-38
|
| 585 | | PB4 J5-40
|
| 586 | | PB5 J5-42
|
| 587 | | PB6 J5-44
|
| 588 | | PB7 J5-46
|
| 589 | | |
| 590 | | */
|
| 591 | | |
| 592 | | /* codec clock output */
|
| 593 | | //mc6852_rxclk_w(state->ssda, BIT(data, 7));
|
| 594 | | //mc6852_txclk_w(state->ssda, BIT(data, 7));
|
| 595 | | }
|
| 596 | | |
| 597 | | static WRITE_LINE_DEVICE_HANDLER( via3_irq_w )
|
| 598 | | {
|
| 599 | | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data;
|
| 600 | | |
| 601 | | driver_state->via3_irq = state;
|
| 602 | | |
| 603 | | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq);
|
| 604 | | }
|
| 605 | | |
| 606 | | static const via6522_interface via3_intf =
|
| 607 | | {
|
| 608 | | DEVCB_HANDLER(via3_pa_r),
|
| 609 | | DEVCB_HANDLER(via3_pb_r),
|
| 610 | | DEVCB_NULL, // J5-12
|
| 611 | | DEVCB_NULL, // J5-48
|
| 612 | | DEVCB_NULL, // J5-14
|
| 613 | | DEVCB_NULL, // J5-50
|
| 614 | | |
| 615 | | DEVCB_HANDLER(via3_pa_w),
|
| 616 | | DEVCB_HANDLER(via3_pb_w),
|
| 617 | | DEVCB_NULL,
|
| 618 | | DEVCB_NULL,
|
| 619 | | DEVCB_NULL,
|
| 620 | | DEVCB_NULL,
|
| 621 | | |
| 622 | | DEVCB_LINE(via3_irq_w)
|
| 623 | | };
|
| 624 | | |
| 625 | | static WRITE8_DEVICE_HANDLER( via4_pa_w )
|
| 626 | | {
|
| 627 | | /*
|
| 628 | | |
| 629 | | bit description
|
| 630 | | |
| 631 | | PA0 L0MS0
|
| 632 | | PA1 L0MS1
|
| 633 | | PA2 L0MS2
|
| 634 | | PA3 L0MS3
|
| 635 | | PA4 ST0A
|
| 636 | | PA5 ST0B
|
| 637 | | PA6 ST0C
|
| 638 | | PA7 ST0D
|
| 639 | | |
| 640 | | */
|
| 641 | | }
|
| 642 | | |
| 643 | | static WRITE8_DEVICE_HANDLER( via4_pb_w )
|
| 644 | | {
|
| 645 | | /*
|
| 646 | | |
| 647 | | bit description
|
| 648 | | |
| 649 | | PB0 L1MS0
|
| 650 | | PB1 L1MS1
|
| 651 | | PB2 L1MS2
|
| 652 | | PB3 L1MS3
|
| 653 | | PB4 ST1A
|
| 654 | | PB5 ST1B
|
| 655 | | PB6 ST1C
|
| 656 | | PB7 ST1D
|
| 657 | | |
| 658 | | */
|
| 659 | | }
|
| 660 | | |
| 661 | | static WRITE_LINE_DEVICE_HANDLER( mode_w )
|
| 662 | | {
|
| 663 | | }
|
| 664 | | |
| 665 | | static WRITE_LINE_DEVICE_HANDLER( via4_irq_w )
|
| 666 | | {
|
| 667 | | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data;
|
| 668 | | |
| 669 | | driver_state->via4_irq = state;
|
| 670 | | |
| 671 | | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq);
|
| 672 | | }
|
| 673 | | |
| 674 | | static const via6522_interface via4_intf =
|
| 675 | | {
|
| 676 | | DEVCB_NULL,
|
| 677 | | DEVCB_NULL,
|
| 678 | | DEVCB_NULL, // DS0
|
| 679 | | DEVCB_NULL, // DS1
|
| 680 | | DEVCB_NULL,
|
| 681 | | DEVCB_NULL,
|
| 682 | | |
| 683 | | DEVCB_HANDLER(via4_pa_w),
|
| 684 | | DEVCB_HANDLER(via4_pb_w),
|
| 685 | | DEVCB_NULL,
|
| 686 | | DEVCB_NULL,
|
| 687 | | DEVCB_LINE(mode_w),
|
| 688 | | DEVCB_NULL,
|
| 689 | | |
| 690 | | DEVCB_LINE(via4_irq_w)
|
| 691 | | };
|
| 692 | | |
| 693 | | static READ8_DEVICE_HANDLER( via5_pa_r )
|
| 694 | | {
|
| 695 | | /*
|
| 696 | | |
| 697 | | bit description
|
| 698 | | |
| 699 | | PA0 E0
|
| 700 | | PA1 E1
|
| 701 | | PA2 I1
|
| 702 | | PA3 E2
|
| 703 | | PA4 E4
|
| 704 | | PA5 E5
|
| 705 | | PA6 I7
|
| 706 | | PA7 E6
|
| 707 | | |
| 708 | | */
|
| 709 | | |
| 710 | | return 0;
|
| 711 | | }
|
| 712 | | |
| 713 | | static WRITE8_DEVICE_HANDLER( via5_pb_w )
|
| 714 | | {
|
| 715 | | /*
|
| 716 | | |
| 717 | | bit description
|
| 718 | | |
| 719 | | PB0 WD0
|
| 720 | | PB1 WD1
|
| 721 | | PB2 WD2
|
| 722 | | PB3 WD3
|
| 723 | | PB4 WD4
|
| 724 | | PB5 WD5
|
| 725 | | PB6 WD6
|
| 726 | | PB7 WD7
|
| 727 | | |
| 728 | | */
|
| 729 | | }
|
| 730 | | |
| 731 | | static WRITE_LINE_DEVICE_HANDLER( via5_irq_w )
|
| 732 | | {
|
| 733 | | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data;
|
| 734 | | |
| 735 | | driver_state->via5_irq = state;
|
| 736 | | |
| 737 | | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq);
|
| 738 | | }
|
| 739 | | |
| 740 | | static const via6522_interface via5_intf =
|
| 741 | | {
|
| 742 | | DEVCB_HANDLER(via5_pa_r),
|
| 743 | | DEVCB_NULL,
|
| 744 | | DEVCB_NULL, // BRDY
|
| 745 | | DEVCB_NULL,
|
| 746 | | DEVCB_NULL, // RDY0
|
| 747 | | DEVCB_NULL, // RDY1
|
| 748 | | |
| 749 | | DEVCB_NULL,
|
| 750 | | DEVCB_HANDLER(via5_pb_w),
|
| 751 | | DEVCB_NULL,
|
| 752 | | DEVCB_NULL,
|
| 753 | | DEVCB_NULL,
|
| 754 | | DEVCB_NULL,
|
| 755 | | |
| 756 | | DEVCB_LINE(via5_irq_w)
|
| 757 | | };
|
| 758 | | |
| 759 | | static READ8_DEVICE_HANDLER( via6_pa_r )
|
| 760 | | {
|
| 761 | | /*
|
| 762 | | |
| 763 | | bit description
|
| 764 | | |
| 765 | | PA0 LED0A
|
| 766 | | PA1 TRK0D0
|
| 767 | | PA2 LED1A
|
| 768 | | PA3 TRK0D1
|
| 769 | | PA4 SIDE SELECT
|
| 770 | | PA5 DRIVE SELECT
|
| 771 | | PA6 WPS
|
| 772 | | PA7 SYNC
|
| 773 | | |
| 774 | | */
|
| 775 | | |
| 776 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 777 | | |
| 778 | | UINT8 data = 0;
|
| 779 | | |
| 780 | | /* drive 0 track 0 sense */
|
| 781 | | data |= floppy_tk00_r(state->floppy[0].image) << 1;
|
| 782 | | |
| 783 | | /* drive 1 track 0 sense */
|
| 784 | | data |= floppy_tk00_r(state->floppy[1].image) << 3;
|
| 785 | | |
| 786 | | /* write protect sense */
|
| 787 | | data |= floppy_wpt_r(state->floppy[state->drive].image) << 6;
|
| 788 | | |
| 789 | | return data;
|
| 790 | | }
|
| 791 | | |
| 792 | | static WRITE8_DEVICE_HANDLER( via6_pa_w )
|
| 793 | | {
|
| 794 | | /*
|
| 795 | | |
| 796 | | bit description
|
| 797 | | |
| 798 | | PA0 LED0A
|
| 799 | | PA1 TRK0D0
|
| 800 | | PA2 LED1A
|
| 801 | | PA3 TRK0D1
|
| 802 | | PA4 SIDE SELECT
|
| 803 | | PA5 DRIVE SELECT
|
| 804 | | PA6 WPS
|
| 805 | | PA7 SYNC
|
| 806 | | |
| 807 | | */
|
| 808 | | |
| 809 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 810 | | |
| 811 | | /* side select */
|
| 812 | | state->side = BIT(data, 4);
|
| 813 | | |
| 814 | | /* drive select */
|
| 815 | | state->drive = BIT(data, 5);
|
| 816 | | }
|
| 817 | | |
| 818 | | static READ8_DEVICE_HANDLER( via6_pb_r )
|
| 819 | | {
|
| 820 | | /*
|
| 821 | | |
| 822 | | bit description
|
| 823 | | |
| 824 | | PB0 RDY0
|
| 825 | | PB1 RDY1
|
| 826 | | PB2 SCRESET
|
| 827 | | PB3 _DS1
|
| 828 | | PB4 _DS0
|
| 829 | | PB5 SINGLE/_DOUBLE SIDED
|
| 830 | | PB6 stepper enable A
|
| 831 | | PB7 stepper enable B
|
| 832 | | |
| 833 | | */
|
| 834 | | |
| 835 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 836 | | |
| 837 | | UINT8 data = 0;
|
| 838 | | |
| 839 | | /* drive 0 ready */
|
| 840 | | data |= !(floppy_drive_get_flag_state(state->floppy[0].image, FLOPPY_DRIVE_READY) == FLOPPY_DRIVE_READY) << 4;
|
| 841 | | |
| 842 | | /* drive 1 ready */
|
| 843 | | data |= !(floppy_drive_get_flag_state(state->floppy[0].image, FLOPPY_DRIVE_READY) == FLOPPY_DRIVE_READY) << 3;
|
| 844 | | |
| 845 | | /* single/double sided */
|
| 846 | | data |= floppy_twosid_r(state->floppy[state->drive].image) << 5;
|
| 847 | | |
| 848 | | return data;
|
| 849 | | }
|
| 850 | | |
| 851 | | static WRITE8_DEVICE_HANDLER( via6_pb_w )
|
| 852 | | {
|
| 853 | | /*
|
| 854 | | |
| 855 | | bit description
|
| 856 | | |
| 857 | | PB0 RDY0
|
| 858 | | PB1 RDY1
|
| 859 | | PB2 SCRESET
|
| 860 | | PB3 _DS1
|
| 861 | | PB4 _DS0
|
| 862 | | PB5 SINGLE/_DOUBLE SIDED
|
| 863 | | PB6 stepper enable A
|
| 864 | | PB7 stepper enable B
|
| 865 | | |
| 866 | | */
|
| 867 | | |
| 868 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 869 | | |
| 870 | | /* motor speed controller reset */
|
| 871 | | cputag_set_input_line(device->machine, I8048_TAG, INPUT_LINE_RESET, BIT(data, 2));
|
| 872 | | |
| 873 | | /* stepper enable A */
|
| 874 | | state->floppy[0].se = BIT(data, 6);
|
| 875 | | |
| 876 | | /* stepper enable B */
|
| 877 | | state->floppy[1].se = BIT(data, 7);
|
| 878 | | }
|
| 879 | | |
| 880 | | static WRITE_LINE_DEVICE_HANDLER( drw_w )
|
| 881 | | {
|
| 882 | | }
|
| 883 | | |
| 884 | | static WRITE_LINE_DEVICE_HANDLER( erase_w )
|
| 885 | | {
|
| 886 | | }
|
| 887 | | |
| 888 | | static WRITE_LINE_DEVICE_HANDLER( via6_irq_w )
|
| 889 | | {
|
| 890 | | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data;
|
| 891 | | |
| 892 | | driver_state->via6_irq = state;
|
| 893 | | |
| 894 | | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq);
|
| 895 | | }
|
| 896 | | |
| 897 | | static const via6522_interface via6_intf =
|
| 898 | | {
|
| 899 | | DEVCB_HANDLER(via6_pa_r),
|
| 900 | | DEVCB_HANDLER(via6_pb_r),
|
| 901 | | DEVCB_NULL, // GCRERR
|
| 902 | | DEVCB_NULL,
|
| 903 | | DEVCB_NULL,
|
| 904 | | DEVCB_NULL,
|
| 905 | | |
| 906 | | DEVCB_HANDLER(via6_pa_w),
|
| 907 | | DEVCB_HANDLER(via6_pb_w),
|
| 908 | | DEVCB_NULL,
|
| 909 | | DEVCB_NULL,
|
| 910 | | DEVCB_LINE(drw_w),
|
| 911 | | DEVCB_LINE(erase_w),
|
| 912 | | |
| 913 | | DEVCB_LINE(via6_irq_w)
|
| 914 | | };
|
| 915 | | |
| 916 | | /* Floppy Configuration */
|
| 917 | | |
| 918 | | static const floppy_config victor9k_floppy_config =
|
| 919 | | {
|
| 920 | | DEVCB_NULL,
|
| 921 | | DEVCB_NULL,
|
| 922 | | DEVCB_NULL,
|
| 923 | | DEVCB_NULL,
|
| 924 | | DEVCB_NULL,
|
| 925 | | FLOPPY_DRIVE_DS_80,
|
| 926 | | FLOPPY_OPTIONS_NAME(default),
|
| 927 | | DO_NOT_KEEP_GEOMETRY
|
| 928 | | };
|
| 929 | | |
| 930 | | /* IEEE-488 Interface */
|
| 931 | | |
| 932 | | static IEEE488_DAISY( ieee488_daisy )
|
| 933 | | {
|
| 934 | | { M6522_1_TAG, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_LINE(M6522_1_TAG, via_ca1_w), DEVCB_DEVICE_LINE(M6522_1_TAG, via_ca2_w) },
|
| 935 | | { NULL }
|
| 936 | | };
|
| 937 | | |
| 938 | | /* Machine Initialization */
|
| 939 | | |
| 940 | | static IRQ_CALLBACK( victor9k_irq_callback )
|
| 941 | | {
|
| 942 | | victor9k_state *state = (victor9k_state *)device->machine->driver_data;
|
| 943 | | |
| 944 | | return pic8259_acknowledge(state->pic);
|
| 945 | | }
|
| 946 | | |
| 947 | | static MACHINE_START( victor9k )
|
| 948 | | {
|
| 949 | | victor9k_state *state = (victor9k_state *)machine->driver_data;
|
| 950 | | |
| 951 | | /* set interrupt callback */
|
| 952 | | cpu_set_irq_callback(machine->firstcpu, victor9k_irq_callback);
|
| 953 | | |
| 954 | | /* find devices */
|
| 955 | | state->ieee488 = devtag_get_device(machine, IEEE488_TAG);
|
| 956 | | state->pic = devtag_get_device(machine, I8259A_TAG);
|
| 957 | | state->ssda = devtag_get_device(machine, MC6852_TAG);
|
| 958 | | state->cvsd = devtag_get_device(machine, HC55516_TAG);
|
| 959 | | state->floppy[0].image = devtag_get_device(machine, FLOPPY_0);
|
| 960 | | state->floppy[1].image = devtag_get_device(machine, FLOPPY_1);
|
| 961 | | |
| 962 | | /* memory banking */
|
| 963 | | const address_space *program = cputag_get_address_space(machine, I8088_TAG, ADDRESS_SPACE_PROGRAM);
|
| 964 | | UINT8 *ram = messram_get_ptr(devtag_get_device(machine, "messram"));
|
| 965 | | int ram_size = messram_get_size(devtag_get_device(machine, "messram"));
|
| 966 | | |
| 967 | | memory_install_ram(program, 0x00000, ram_size - 1, 0, 0, ram);
|
| 968 | | }
|
| 969 | | |
| 970 | | /* Machine Driver */
|
| 971 | | |
| 972 | | static MACHINE_DRIVER_START( victor9k )
|
| 973 | | MDRV_DRIVER_DATA(victor9k_state)
|
| 974 | | |
| 975 | | /* basic machine hardware */
|
| 976 | | MDRV_CPU_ADD(I8088_TAG, I8088, XTAL_30MHz/6)
|
| 977 | | MDRV_CPU_PROGRAM_MAP(victor9k_mem)
|
| 978 | | |
| 979 | | MDRV_CPU_ADD(I8048_TAG, I8048, XTAL_30MHz/6)
|
| 980 | | MDRV_CPU_IO_MAP(floppy_io)
|
| 981 | | |
| 982 | | // MDRV_CPU_ADD(I8022_TAG, I8022, 100000)
|
| 983 | | // MDRV_CPU_IO_MAP(keyboard_io)
|
| 984 | | |
| 985 | | MDRV_MACHINE_START(victor9k)
|
| 986 | | |
| 987 | | /* video hardware */
|
| 988 | | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
|
| 989 | | MDRV_SCREEN_REFRESH_RATE(50)
|
| 990 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
| 991 | | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
| 992 | | MDRV_SCREEN_SIZE(640, 480)
|
| 993 | | MDRV_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
|
| 994 | | |
| 995 | | MDRV_PALETTE_LENGTH(2)
|
| 996 | | MDRV_PALETTE_INIT(monochrome_green)
|
| 997 | | |
| 998 | | MDRV_VIDEO_START(victor9k)
|
| 999 | | MDRV_VIDEO_UPDATE(victor9k)
|
| 1000 | | |
| 1001 | | MDRV_MC6845_ADD(HD46505S_TAG, H46505, 1000000, hd46505s_intf)
|
| 1002 | | |
| 1003 | | /* sound hardware */
|
| 1004 | | MDRV_SPEAKER_STANDARD_MONO("mono")
|
| 1005 | | MDRV_SOUND_ADD(HC55516_TAG, HC55516, 100000)
|
| 1006 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
| 1007 | | |
| 1008 | | /* devices */
|
| 1009 | | MDRV_IEEE488_ADD(IEEE488_TAG, ieee488_daisy)
|
| 1010 | | MDRV_PIC8259_ADD(I8259A_TAG, pic_intf)
|
| 1011 | | MDRV_PIT8253_ADD(I8253_TAG, pit_intf)
|
| 1012 | | MDRV_UPD7201_ADD(UPD7201_TAG, XTAL_30MHz/30, mpsc_intf)
|
| 1013 | | // MDRV_MC6852_ADD(MC6852_TAG, XTAL_30MHz/30, mc6852_intf)
|
| 1014 | | MDRV_VIA6522_ADD(M6522_1_TAG, XTAL_30MHz/30, via1_intf)
|
| 1015 | | MDRV_VIA6522_ADD(M6522_2_TAG, XTAL_30MHz/30, via2_intf)
|
| 1016 | | MDRV_VIA6522_ADD(M6522_3_TAG, XTAL_30MHz/30, via3_intf)
|
| 1017 | | MDRV_VIA6522_ADD(M6522_4_TAG, XTAL_30MHz/30, via4_intf)
|
| 1018 | | MDRV_VIA6522_ADD(M6522_5_TAG, XTAL_30MHz/30, via5_intf)
|
| 1019 | | MDRV_VIA6522_ADD(M6522_6_TAG, XTAL_30MHz/30, via6_intf)
|
| 1020 | | MDRV_FLOPPY_2_DRIVES_ADD(victor9k_floppy_config)
|
| 1021 | | |
| 1022 | | /* internal ram */
|
| 1023 | | MDRV_RAM_ADD("messram")
|
| 1024 | | MDRV_RAM_DEFAULT_SIZE("128K")
|
| 1025 | | MDRV_RAM_EXTRA_OPTIONS("256K,384K,512K,640K,768K,896K")
|
| 1026 | | MACHINE_DRIVER_END
|
| 1027 | | |
| 1028 | | /* ROMs */
|
| 1029 | | |
| 1030 | | ROM_START( victor9k )
|
| 1031 | | ROM_REGION( 0x2000, I8088_TAG, 0 )
|
| 1032 | | ROM_DEFAULT_BIOS( "univ" )
|
| 1033 | | ROM_SYSTEM_BIOS( 0, "old", "Older" )
|
| 1034 | | ROMX_LOAD( "102320.7j", 0x0000, 0x1000, CRC(3d615fd7) SHA1(b22f7e5d66404185395d8effbf57efded0079a92), ROM_BIOS(1) )
|
| 1035 | | ROMX_LOAD( "102322.8j", 0x1000, 0x1000, CRC(9209df0e) SHA1(3ee8e0c15186bbd5768b550ecc1fa3b6b1dbb928), ROM_BIOS(1) )
|
| 1036 | | ROM_SYSTEM_BIOS( 1, "univ", "Universal" )
|
| 1037 | | ROMX_LOAD( "v9000 univ. fe f3f7 13db.7j", 0x0000, 0x1000, CRC(25c7a59f) SHA1(8784e9aa7eb9439f81e18b8e223c94714e033911), ROM_BIOS(2) )
|
| 1038 | | ROMX_LOAD( "v9000 univ. ff f3f7 39fe.8j", 0x1000, 0x1000, CRC(496c7467) SHA1(eccf428f62ef94ab85f4a43ba59ae6a066244a66), ROM_BIOS(2) )
|
| 1039 | | |
| 1040 | | ROM_REGION( 0x800, "gcr", 0 )
|
| 1041 | | ROM_LOAD( "100836-001.4k", 0x000, 0x800, CRC(adc601bd) SHA1(6eeff3d2063ae2d97452101aa61e27ef83a467e5) )
|
| 1042 | | |
| 1043 | | ROM_REGION( 0x400, I8048_TAG, 0)
|
| 1044 | | ROM_LOAD( "36080.5d", 0x000, 0x400, CRC(9bf49f7d) SHA1(b3a11bb65105db66ae1985b6f482aab6ea1da38b) )
|
| 1045 | | |
| 1046 | | ROM_REGION( 0x800, I8022_TAG, 0)
|
| 1047 | | ROM_LOAD( "keyboard controller i8022", 0x000, 0x800, NO_DUMP )
|
| 1048 | | ROM_END
|
| 1049 | | |
| 1050 | | /* System Drivers */
|
| 1051 | | |
| 1052 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
| 1053 | | COMP( 1982, victor9k, 0, 0, victor9k, victor9k, 0, "Victor Business Products", "Victor 9000", GAME_NOT_WORKING )
|
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Victor 9000 |
| 4 | |
| 5 | - very exciting hardware, disk controller is a direct descendant |
| 6 | of the Commodore drives (designed by Chuck Peddle) |
| 7 | |
| 8 | Skeleton driver |
| 9 | |
| 10 | ***************************************************************************/ |
| 11 | |
| 12 | /* |
| 13 | |
| 14 | TODO: |
| 15 | |
| 16 | - floppy 8048 |
| 17 | - keyboard |
| 18 | - add HD46505S variant to mc6845.c |
| 19 | - hires graphics |
| 20 | - character attributes |
| 21 | - brightness/contrast |
| 22 | - MC6852 |
| 23 | - codec sound |
| 24 | |
| 25 | */ |
| 26 | |
| 27 | #include "emu.h" |
| 28 | #include "includes/victor9k.h" |
| 29 | #include "cpu/i86/i86.h" |
| 30 | #include "cpu/mcs48/mcs48.h" |
| 31 | #include "devices/flopdrv.h" |
| 32 | #include "devices/messram.h" |
| 33 | #include "machine/ctronics.h" |
| 34 | #include "machine/6522via.h" |
| 35 | #include "machine/ieee488.h" |
| 36 | #include "machine/pit8253.h" |
| 37 | #include "machine/pic8259.h" |
| 38 | #include "machine/upd7201.h" |
| 39 | #include "sound/hc55516.h" |
| 40 | #include "video/mc6845.h" |
| 41 | |
| 42 | /* Memory Maps */ |
| 43 | |
| 44 | static ADDRESS_MAP_START( victor9k_mem, ADDRESS_SPACE_PROGRAM, 8 ) |
| 45 | // AM_RANGE(0x00000, 0xdffff) AM_RAM |
| 46 | AM_RANGE(0xe0000, 0xe0001) AM_DEVREADWRITE(I8259A_TAG, pic8259_r, pic8259_w) |
| 47 | AM_RANGE(0xe0020, 0xe0023) AM_DEVREADWRITE(I8253_TAG, pit8253_r, pit8253_w) |
| 48 | AM_RANGE(0xe0040, 0xe0043) AM_DEVREADWRITE(UPD7201_TAG, upd7201_cd_ba_r, upd7201_cd_ba_w) |
| 49 | AM_RANGE(0xe8000, 0xe8000) AM_DEVREADWRITE(HD46505S_TAG, mc6845_status_r, mc6845_address_w) |
| 50 | AM_RANGE(0xe8001, 0xe8001) AM_DEVREADWRITE(HD46505S_TAG, mc6845_register_r, mc6845_register_w) |
| 51 | AM_RANGE(0xe8020, 0xe802f) AM_DEVREADWRITE(M6522_1_TAG, via_r, via_w) |
| 52 | AM_RANGE(0xe8040, 0xe804f) AM_DEVREADWRITE(M6522_2_TAG, via_r, via_w) |
| 53 | // AM_RANGE(0xe8060, 0xe806f) AM_DEVREADWRITE(MC6852_TAG, mc6852_r, mc6852_w) |
| 54 | AM_RANGE(0xe8080, 0xe808f) AM_DEVREADWRITE(M6522_3_TAG, via_r, via_w) |
| 55 | AM_RANGE(0xe80a0, 0xe80af) AM_DEVREADWRITE(M6522_4_TAG, via_r, via_w) |
| 56 | AM_RANGE(0xe80c0, 0xe80cf) AM_DEVREADWRITE(M6522_6_TAG, via_r, via_w) |
| 57 | AM_RANGE(0xe80e0, 0xe80ef) AM_DEVREADWRITE(M6522_5_TAG, via_r, via_w) |
| 58 | AM_RANGE(0xf0000, 0xf0fff) AM_MIRROR(0x1000) AM_RAM AM_BASE_MEMBER(victor9k_state, video_ram) |
| 59 | AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION(I8088_TAG, 0) |
| 60 | ADDRESS_MAP_END |
| 61 | |
| 62 | static ADDRESS_MAP_START( floppy_io, ADDRESS_SPACE_IO, 8 ) |
| 63 | // AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) |
| 64 | // AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) |
| 65 | // AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) |
| 66 | // AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) |
| 67 | ADDRESS_MAP_END |
| 68 | |
| 69 | static ADDRESS_MAP_START( keyboard_io, ADDRESS_SPACE_IO, 8 ) |
| 70 | // AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) |
| 71 | // AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) |
| 72 | // AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) |
| 73 | // AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) |
| 74 | ADDRESS_MAP_END |
| 75 | |
| 76 | /* Input Ports */ |
| 77 | |
| 78 | static INPUT_PORTS_START( victor9k ) |
| 79 | INPUT_PORTS_END |
| 80 | |
| 81 | /* Video */ |
| 82 | |
| 83 | #define CODE_NON_DISPLAY 0x1000 |
| 84 | #define CODE_UNDERLINE 0x2000 |
| 85 | #define CODE_LOW_INTENSITY 0x4000 |
| 86 | #define CODE_REVERSE_VIDEO 0x8000 |
| 87 | |
| 88 | static MC6845_UPDATE_ROW( victor9k_update_row ) |
| 89 | { |
| 90 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 91 | const address_space *program = cputag_get_address_space(device->machine, I8088_TAG, ADDRESS_SPACE_PROGRAM); |
| 92 | |
| 93 | if (BIT(ma, 13)) |
| 94 | { |
| 95 | fatalerror("Graphics mode not supported!"); |
| 96 | } |
| 97 | else |
| 98 | { |
| 99 | UINT16 video_ram_addr = (ma & 0xfff) << 1; |
| 100 | |
| 101 | for (int sx = 0; sx < x_count; sx++) |
| 102 | { |
| 103 | UINT16 code = (state->video_ram[video_ram_addr + 1] << 8) | state->video_ram[video_ram_addr]; |
| 104 | UINT32 char_ram_addr = (BIT(ma, 12) << 16) | ((code & 0xff) << 5) | (ra << 1); |
| 105 | UINT16 data = memory_read_word_16le(program, char_ram_addr); |
| 106 | |
| 107 | for (int x = 0; x <= 10; x++) |
| 108 | { |
| 109 | int color = BIT(data, x); |
| 110 | |
| 111 | if (sx == cursor_x) color = 1; |
| 112 | |
| 113 | *BITMAP_ADDR16(bitmap, y, x + sx*10) = color; |
| 114 | } |
| 115 | |
| 116 | video_ram_addr += 2; |
| 117 | video_ram_addr &= 0xfff; |
| 118 | } |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | static WRITE_LINE_DEVICE_HANDLER( vsync_w ) |
| 123 | { |
| 124 | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data; |
| 125 | |
| 126 | pic8259_ir7_w(driver_state->pic, state); |
| 127 | driver_state->vert = state; |
| 128 | } |
| 129 | |
| 130 | static const mc6845_interface hd46505s_intf = |
| 131 | { |
| 132 | SCREEN_TAG, |
| 133 | 10, |
| 134 | NULL, |
| 135 | victor9k_update_row, |
| 136 | NULL, |
| 137 | DEVCB_NULL, |
| 138 | DEVCB_NULL, |
| 139 | DEVCB_NULL, |
| 140 | DEVCB_LINE(vsync_w), |
| 141 | NULL |
| 142 | }; |
| 143 | |
| 144 | static VIDEO_START( victor9k ) |
| 145 | { |
| 146 | victor9k_state *state = (victor9k_state *)machine->driver_data; |
| 147 | |
| 148 | /* find devices */ |
| 149 | state->crt = devtag_get_device(machine, HD46505S_TAG); |
| 150 | } |
| 151 | |
| 152 | static VIDEO_UPDATE( victor9k ) |
| 153 | { |
| 154 | victor9k_state *state = (victor9k_state *)screen->machine->driver_data; |
| 155 | |
| 156 | mc6845_update(state->crt, bitmap, cliprect); |
| 157 | |
| 158 | return 0; |
| 159 | } |
| 160 | |
| 161 | /* Intel 8253 Interface */ |
| 162 | |
| 163 | static WRITE_LINE_DEVICE_HANDLER( mux_serial_b_w ) |
| 164 | { |
| 165 | } |
| 166 | |
| 167 | static WRITE_LINE_DEVICE_HANDLER( mux_serial_a_w ) |
| 168 | { |
| 169 | } |
| 170 | |
| 171 | static const struct pit8253_config pit_intf = |
| 172 | { |
| 173 | { |
| 174 | { |
| 175 | 2500000, |
| 176 | DEVCB_LINE_VCC, |
| 177 | DEVCB_LINE(mux_serial_b_w) |
| 178 | }, { |
| 179 | 2500000, |
| 180 | DEVCB_LINE_VCC, |
| 181 | DEVCB_LINE(mux_serial_a_w) |
| 182 | }, { |
| 183 | 100000, |
| 184 | DEVCB_LINE_VCC, |
| 185 | DEVCB_DEVICE_LINE(I8259A_TAG, pic8259_ir2_w) |
| 186 | } |
| 187 | } |
| 188 | }; |
| 189 | |
| 190 | /* Intel 8259 Interfaces */ |
| 191 | |
| 192 | /* |
| 193 | |
| 194 | pin signal description |
| 195 | |
| 196 | IR0 SYN sync detect |
| 197 | IR1 COMM serial communications (7201) |
| 198 | IR2 TIMER 8253 timer |
| 199 | IR3 PARALLEL all 6522 IRQ (including disk) |
| 200 | IR4 IR4 expansion IR4 |
| 201 | IR5 IR5 expansion IR5 |
| 202 | IR6 KBINT keyboard data ready |
| 203 | IR7 VINT vertical sync or nonspecific interrupt |
| 204 | |
| 205 | */ |
| 206 | |
| 207 | static const struct pic8259_interface pic_intf = |
| 208 | { |
| 209 | DEVCB_CPU_INPUT_LINE(I8088_TAG, INPUT_LINE_IRQ0) |
| 210 | }; |
| 211 | |
| 212 | /* NEC uPD7201 Interface */ |
| 213 | |
| 214 | static UPD7201_INTERFACE( mpsc_intf ) |
| 215 | { |
| 216 | DEVCB_DEVICE_LINE(I8259A_TAG, pic8259_ir1_w), /* interrupt */ |
| 217 | { |
| 218 | { |
| 219 | 0, /* receive clock */ |
| 220 | 0, /* transmit clock */ |
| 221 | DEVCB_NULL, /* receive DRQ */ |
| 222 | DEVCB_NULL, /* transmit DRQ */ |
| 223 | DEVCB_NULL, /* receive data */ |
| 224 | DEVCB_NULL, /* transmit data */ |
| 225 | DEVCB_NULL, /* clear to send */ |
| 226 | DEVCB_NULL, /* data carrier detect */ |
| 227 | DEVCB_NULL, /* ready to send */ |
| 228 | DEVCB_NULL, /* data terminal ready */ |
| 229 | DEVCB_NULL, /* wait */ |
| 230 | DEVCB_NULL /* sync output */ |
| 231 | }, { |
| 232 | 0, /* receive clock */ |
| 233 | 0, /* transmit clock */ |
| 234 | DEVCB_NULL, /* receive DRQ */ |
| 235 | DEVCB_NULL, /* transmit DRQ */ |
| 236 | DEVCB_NULL, /* receive data */ |
| 237 | DEVCB_NULL, /* transmit data */ |
| 238 | DEVCB_NULL, /* clear to send */ |
| 239 | DEVCB_NULL, /* data carrier detect */ |
| 240 | DEVCB_NULL, /* ready to send */ |
| 241 | DEVCB_NULL, /* data terminal ready */ |
| 242 | DEVCB_NULL, /* wait */ |
| 243 | DEVCB_NULL /* sync output */ |
| 244 | } |
| 245 | } |
| 246 | }; |
| 247 | |
| 248 | /* M6522 Interface */ |
| 249 | |
| 250 | static READ8_DEVICE_HANDLER( via1_pa_r ) |
| 251 | { |
| 252 | /* |
| 253 | |
| 254 | bit description |
| 255 | |
| 256 | PA0 DIO1 |
| 257 | PA1 DIO2 |
| 258 | PA2 DIO3 |
| 259 | PA3 DIO4 |
| 260 | PA4 DIO5 |
| 261 | PA5 DIO6 |
| 262 | PA6 DIO7 |
| 263 | PA7 DIO8 |
| 264 | |
| 265 | */ |
| 266 | |
| 267 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 268 | |
| 269 | return ieee488_dio_r(state->ieee488, 0); |
| 270 | } |
| 271 | |
| 272 | static WRITE8_DEVICE_HANDLER( via1_pa_w ) |
| 273 | { |
| 274 | /* |
| 275 | |
| 276 | bit description |
| 277 | |
| 278 | PA0 DIO1 |
| 279 | PA1 DIO2 |
| 280 | PA2 DIO3 |
| 281 | PA3 DIO4 |
| 282 | PA4 DIO5 |
| 283 | PA5 DIO6 |
| 284 | PA6 DIO7 |
| 285 | PA7 DIO8 |
| 286 | |
| 287 | */ |
| 288 | |
| 289 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 290 | |
| 291 | ieee488_dio_w(state->ieee488, device, data); |
| 292 | } |
| 293 | |
| 294 | static READ8_DEVICE_HANDLER( via1_pb_r ) |
| 295 | { |
| 296 | /* |
| 297 | |
| 298 | bit description |
| 299 | |
| 300 | PB0 DAV |
| 301 | PB1 EOI |
| 302 | PB2 REN |
| 303 | PB3 ATN |
| 304 | PB4 IFC |
| 305 | PB5 SRQ |
| 306 | PB6 NRFD |
| 307 | PB7 NDAC |
| 308 | |
| 309 | */ |
| 310 | |
| 311 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 312 | |
| 313 | UINT8 data = 0; |
| 314 | |
| 315 | /* data valid */ |
| 316 | data |= ieee488_dav_r(state->ieee488); |
| 317 | |
| 318 | /* end or identify */ |
| 319 | data |= ieee488_eoi_r(state->ieee488) << 1; |
| 320 | |
| 321 | /* remote enable */ |
| 322 | data |= ieee488_ren_r(state->ieee488) << 2; |
| 323 | |
| 324 | /* attention */ |
| 325 | data |= ieee488_atn_r(state->ieee488) << 3; |
| 326 | |
| 327 | /* interface clear */ |
| 328 | data |= ieee488_ifc_r(state->ieee488) << 4; |
| 329 | |
| 330 | /* service request */ |
| 331 | data |= ieee488_srq_r(state->ieee488) << 5; |
| 332 | |
| 333 | /* not ready for data */ |
| 334 | data |= ieee488_nrfd_r(state->ieee488) << 6; |
| 335 | |
| 336 | /* data not accepted */ |
| 337 | data |= ieee488_ndac_r(state->ieee488) << 7; |
| 338 | |
| 339 | return data; |
| 340 | } |
| 341 | |
| 342 | static WRITE8_DEVICE_HANDLER( via1_pb_w ) |
| 343 | { |
| 344 | /* |
| 345 | |
| 346 | bit description |
| 347 | |
| 348 | PB0 DAV |
| 349 | PB1 EOI |
| 350 | PB2 REN |
| 351 | PB3 ATN |
| 352 | PB4 IFC |
| 353 | PB5 SRQ |
| 354 | PB6 NRFD |
| 355 | PB7 NDAC |
| 356 | |
| 357 | */ |
| 358 | |
| 359 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 360 | |
| 361 | /* data valid */ |
| 362 | ieee488_dav_w(state->ieee488, device, BIT(data, 0)); |
| 363 | |
| 364 | /* end or identify */ |
| 365 | ieee488_eoi_w(state->ieee488, device, BIT(data, 1)); |
| 366 | |
| 367 | /* remote enable */ |
| 368 | ieee488_ren_w(state->ieee488, device, BIT(data, 2)); |
| 369 | |
| 370 | /* attention */ |
| 371 | ieee488_atn_w(state->ieee488, device, BIT(data, 3)); |
| 372 | |
| 373 | /* interface clear */ |
| 374 | ieee488_ifc_w(state->ieee488, device, BIT(data, 4)); |
| 375 | |
| 376 | /* service request */ |
| 377 | ieee488_srq_w(state->ieee488, device, BIT(data, 5)); |
| 378 | |
| 379 | /* not ready for data */ |
| 380 | ieee488_nrfd_w(state->ieee488, device, BIT(data, 6)); |
| 381 | |
| 382 | /* data not accepted */ |
| 383 | ieee488_ndac_w(state->ieee488, device, BIT(data, 7)); |
| 384 | } |
| 385 | |
| 386 | static WRITE_LINE_DEVICE_HANDLER( codec_vol_w ) |
| 387 | { |
| 388 | } |
| 389 | |
| 390 | static WRITE_LINE_DEVICE_HANDLER( via1_irq_w ) |
| 391 | { |
| 392 | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data; |
| 393 | |
| 394 | driver_state->via1_irq = state; |
| 395 | |
| 396 | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq); |
| 397 | } |
| 398 | |
| 399 | static const via6522_interface via1_intf = |
| 400 | { |
| 401 | DEVCB_HANDLER(via1_pa_r), |
| 402 | DEVCB_HANDLER(via1_pb_r), |
| 403 | DEVCB_DEVICE_LINE(IEEE488_TAG, ieee488_nrfd_r), |
| 404 | DEVCB_NULL, |
| 405 | DEVCB_DEVICE_LINE(IEEE488_TAG, ieee488_ndac_r), |
| 406 | DEVCB_NULL, |
| 407 | |
| 408 | DEVCB_HANDLER(via1_pa_w), |
| 409 | DEVCB_HANDLER(via1_pb_w), |
| 410 | DEVCB_NULL, |
| 411 | DEVCB_NULL, |
| 412 | DEVCB_NULL, |
| 413 | DEVCB_LINE(codec_vol_w), |
| 414 | |
| 415 | DEVCB_LINE(via1_irq_w) |
| 416 | }; |
| 417 | |
| 418 | static READ8_DEVICE_HANDLER( via2_pa_r ) |
| 419 | { |
| 420 | /* |
| 421 | |
| 422 | bit description |
| 423 | |
| 424 | PA0 _INT/EXTA |
| 425 | PA1 _INT/EXTB |
| 426 | PA2 RIA |
| 427 | PA3 DSRA |
| 428 | PA4 RIB |
| 429 | PA5 DSRB |
| 430 | PA6 KBDATA |
| 431 | PA7 VERT |
| 432 | |
| 433 | */ |
| 434 | |
| 435 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 436 | |
| 437 | UINT8 data = 0; |
| 438 | |
| 439 | /* vertical sync */ |
| 440 | data |= state->vert << 7; |
| 441 | |
| 442 | return data; |
| 443 | } |
| 444 | |
| 445 | static WRITE8_DEVICE_HANDLER( via2_pa_w ) |
| 446 | { |
| 447 | /* |
| 448 | |
| 449 | bit description |
| 450 | |
| 451 | PA0 _INT/EXTA |
| 452 | PA1 _INT/EXTB |
| 453 | PA2 RIA |
| 454 | PA3 DSRA |
| 455 | PA4 RIB |
| 456 | PA5 DSRB |
| 457 | PA6 KBDATA |
| 458 | PA7 VERT |
| 459 | |
| 460 | */ |
| 461 | } |
| 462 | |
| 463 | static WRITE8_DEVICE_HANDLER( via2_pb_w ) |
| 464 | { |
| 465 | /* |
| 466 | |
| 467 | bit description |
| 468 | |
| 469 | PB0 TALK/LISTEN |
| 470 | PB1 KBACKCTL |
| 471 | PB2 BRT0 |
| 472 | PB3 BRT1 |
| 473 | PB4 BRT2 |
| 474 | PB5 CONT0 |
| 475 | PB6 CONT1 |
| 476 | PB7 CONT2 |
| 477 | |
| 478 | */ |
| 479 | |
| 480 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 481 | |
| 482 | /* brightness */ |
| 483 | state->brt = (data >> 2) & 0x07; |
| 484 | |
| 485 | /* contrast */ |
| 486 | state->cont = data >> 5; |
| 487 | } |
| 488 | |
| 489 | static WRITE_LINE_DEVICE_HANDLER( via2_irq_w ) |
| 490 | { |
| 491 | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data; |
| 492 | |
| 493 | driver_state->via2_irq = state; |
| 494 | |
| 495 | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq); |
| 496 | } |
| 497 | |
| 498 | static const via6522_interface via2_intf = |
| 499 | { |
| 500 | DEVCB_HANDLER(via2_pa_r), |
| 501 | DEVCB_NULL, |
| 502 | DEVCB_NULL, |
| 503 | DEVCB_NULL, // KBRDY |
| 504 | DEVCB_NULL, // SRQ/BUSY |
| 505 | DEVCB_NULL, // KBDATA |
| 506 | |
| 507 | DEVCB_HANDLER(via2_pa_w), |
| 508 | DEVCB_HANDLER(via2_pb_w), |
| 509 | DEVCB_NULL, |
| 510 | DEVCB_NULL, |
| 511 | DEVCB_NULL, |
| 512 | DEVCB_NULL, |
| 513 | |
| 514 | DEVCB_LINE(via2_irq_w) |
| 515 | }; |
| 516 | |
| 517 | static READ8_DEVICE_HANDLER( via3_pa_r ) |
| 518 | { |
| 519 | /* |
| 520 | |
| 521 | bit description |
| 522 | |
| 523 | PA0 J5-16 |
| 524 | PA1 J5-18 |
| 525 | PA2 J5-20 |
| 526 | PA3 J5-22 |
| 527 | PA4 J5-24 |
| 528 | PA5 J5-26 |
| 529 | PA6 J5-28 |
| 530 | PA7 J5-30 |
| 531 | |
| 532 | */ |
| 533 | |
| 534 | return 0; |
| 535 | } |
| 536 | |
| 537 | static WRITE8_DEVICE_HANDLER( via3_pa_w ) |
| 538 | { |
| 539 | /* |
| 540 | |
| 541 | bit description |
| 542 | |
| 543 | PA0 J5-16 |
| 544 | PA1 J5-18 |
| 545 | PA2 J5-20 |
| 546 | PA3 J5-22 |
| 547 | PA4 J5-24 |
| 548 | PA5 J5-26 |
| 549 | PA6 J5-28 |
| 550 | PA7 J5-30 |
| 551 | |
| 552 | */ |
| 553 | } |
| 554 | |
| 555 | static READ8_DEVICE_HANDLER( via3_pb_r ) |
| 556 | { |
| 557 | /* |
| 558 | |
| 559 | bit description |
| 560 | |
| 561 | PB0 J5-32 |
| 562 | PB1 J5-34 |
| 563 | PB2 J5-36 |
| 564 | PB3 J5-38 |
| 565 | PB4 J5-40 |
| 566 | PB5 J5-42 |
| 567 | PB6 J5-44 |
| 568 | PB7 J5-46 |
| 569 | |
| 570 | */ |
| 571 | |
| 572 | return 0; |
| 573 | } |
| 574 | |
| 575 | static WRITE8_DEVICE_HANDLER( via3_pb_w ) |
| 576 | { |
| 577 | /* |
| 578 | |
| 579 | bit description |
| 580 | |
| 581 | PB0 J5-32 |
| 582 | PB1 J5-34 |
| 583 | PB2 J5-36 |
| 584 | PB3 J5-38 |
| 585 | PB4 J5-40 |
| 586 | PB5 J5-42 |
| 587 | PB6 J5-44 |
| 588 | PB7 J5-46 |
| 589 | |
| 590 | */ |
| 591 | |
| 592 | /* codec clock output */ |
| 593 | //mc6852_rxclk_w(state->ssda, BIT(data, 7)); |
| 594 | //mc6852_txclk_w(state->ssda, BIT(data, 7)); |
| 595 | } |
| 596 | |
| 597 | static WRITE_LINE_DEVICE_HANDLER( via3_irq_w ) |
| 598 | { |
| 599 | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data; |
| 600 | |
| 601 | driver_state->via3_irq = state; |
| 602 | |
| 603 | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq); |
| 604 | } |
| 605 | |
| 606 | static const via6522_interface via3_intf = |
| 607 | { |
| 608 | DEVCB_HANDLER(via3_pa_r), |
| 609 | DEVCB_HANDLER(via3_pb_r), |
| 610 | DEVCB_NULL, // J5-12 |
| 611 | DEVCB_NULL, // J5-48 |
| 612 | DEVCB_NULL, // J5-14 |
| 613 | DEVCB_NULL, // J5-50 |
| 614 | |
| 615 | DEVCB_HANDLER(via3_pa_w), |
| 616 | DEVCB_HANDLER(via3_pb_w), |
| 617 | DEVCB_NULL, |
| 618 | DEVCB_NULL, |
| 619 | DEVCB_NULL, |
| 620 | DEVCB_NULL, |
| 621 | |
| 622 | DEVCB_LINE(via3_irq_w) |
| 623 | }; |
| 624 | |
| 625 | static WRITE8_DEVICE_HANDLER( via4_pa_w ) |
| 626 | { |
| 627 | /* |
| 628 | |
| 629 | bit description |
| 630 | |
| 631 | PA0 L0MS0 |
| 632 | PA1 L0MS1 |
| 633 | PA2 L0MS2 |
| 634 | PA3 L0MS3 |
| 635 | PA4 ST0A |
| 636 | PA5 ST0B |
| 637 | PA6 ST0C |
| 638 | PA7 ST0D |
| 639 | |
| 640 | */ |
| 641 | } |
| 642 | |
| 643 | static WRITE8_DEVICE_HANDLER( via4_pb_w ) |
| 644 | { |
| 645 | /* |
| 646 | |
| 647 | bit description |
| 648 | |
| 649 | PB0 L1MS0 |
| 650 | PB1 L1MS1 |
| 651 | PB2 L1MS2 |
| 652 | PB3 L1MS3 |
| 653 | PB4 ST1A |
| 654 | PB5 ST1B |
| 655 | PB6 ST1C |
| 656 | PB7 ST1D |
| 657 | |
| 658 | */ |
| 659 | } |
| 660 | |
| 661 | static WRITE_LINE_DEVICE_HANDLER( mode_w ) |
| 662 | { |
| 663 | } |
| 664 | |
| 665 | static WRITE_LINE_DEVICE_HANDLER( via4_irq_w ) |
| 666 | { |
| 667 | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data; |
| 668 | |
| 669 | driver_state->via4_irq = state; |
| 670 | |
| 671 | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq); |
| 672 | } |
| 673 | |
| 674 | static const via6522_interface via4_intf = |
| 675 | { |
| 676 | DEVCB_NULL, |
| 677 | DEVCB_NULL, |
| 678 | DEVCB_NULL, // DS0 |
| 679 | DEVCB_NULL, // DS1 |
| 680 | DEVCB_NULL, |
| 681 | DEVCB_NULL, |
| 682 | |
| 683 | DEVCB_HANDLER(via4_pa_w), |
| 684 | DEVCB_HANDLER(via4_pb_w), |
| 685 | DEVCB_NULL, |
| 686 | DEVCB_NULL, |
| 687 | DEVCB_LINE(mode_w), |
| 688 | DEVCB_NULL, |
| 689 | |
| 690 | DEVCB_LINE(via4_irq_w) |
| 691 | }; |
| 692 | |
| 693 | static READ8_DEVICE_HANDLER( via5_pa_r ) |
| 694 | { |
| 695 | /* |
| 696 | |
| 697 | bit description |
| 698 | |
| 699 | PA0 E0 |
| 700 | PA1 E1 |
| 701 | PA2 I1 |
| 702 | PA3 E2 |
| 703 | PA4 E4 |
| 704 | PA5 E5 |
| 705 | PA6 I7 |
| 706 | PA7 E6 |
| 707 | |
| 708 | */ |
| 709 | |
| 710 | return 0; |
| 711 | } |
| 712 | |
| 713 | static WRITE8_DEVICE_HANDLER( via5_pb_w ) |
| 714 | { |
| 715 | /* |
| 716 | |
| 717 | bit description |
| 718 | |
| 719 | PB0 WD0 |
| 720 | PB1 WD1 |
| 721 | PB2 WD2 |
| 722 | PB3 WD3 |
| 723 | PB4 WD4 |
| 724 | PB5 WD5 |
| 725 | PB6 WD6 |
| 726 | PB7 WD7 |
| 727 | |
| 728 | */ |
| 729 | } |
| 730 | |
| 731 | static WRITE_LINE_DEVICE_HANDLER( via5_irq_w ) |
| 732 | { |
| 733 | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data; |
| 734 | |
| 735 | driver_state->via5_irq = state; |
| 736 | |
| 737 | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq); |
| 738 | } |
| 739 | |
| 740 | static const via6522_interface via5_intf = |
| 741 | { |
| 742 | DEVCB_HANDLER(via5_pa_r), |
| 743 | DEVCB_NULL, |
| 744 | DEVCB_NULL, // BRDY |
| 745 | DEVCB_NULL, |
| 746 | DEVCB_NULL, // RDY0 |
| 747 | DEVCB_NULL, // RDY1 |
| 748 | |
| 749 | DEVCB_NULL, |
| 750 | DEVCB_HANDLER(via5_pb_w), |
| 751 | DEVCB_NULL, |
| 752 | DEVCB_NULL, |
| 753 | DEVCB_NULL, |
| 754 | DEVCB_NULL, |
| 755 | |
| 756 | DEVCB_LINE(via5_irq_w) |
| 757 | }; |
| 758 | |
| 759 | static READ8_DEVICE_HANDLER( via6_pa_r ) |
| 760 | { |
| 761 | /* |
| 762 | |
| 763 | bit description |
| 764 | |
| 765 | PA0 LED0A |
| 766 | PA1 TRK0D0 |
| 767 | PA2 LED1A |
| 768 | PA3 TRK0D1 |
| 769 | PA4 SIDE SELECT |
| 770 | PA5 DRIVE SELECT |
| 771 | PA6 WPS |
| 772 | PA7 SYNC |
| 773 | |
| 774 | */ |
| 775 | |
| 776 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 777 | |
| 778 | UINT8 data = 0; |
| 779 | |
| 780 | /* drive 0 track 0 sense */ |
| 781 | data |= floppy_tk00_r(state->floppy[0].image) << 1; |
| 782 | |
| 783 | /* drive 1 track 0 sense */ |
| 784 | data |= floppy_tk00_r(state->floppy[1].image) << 3; |
| 785 | |
| 786 | /* write protect sense */ |
| 787 | data |= floppy_wpt_r(state->floppy[state->drive].image) << 6; |
| 788 | |
| 789 | return data; |
| 790 | } |
| 791 | |
| 792 | static WRITE8_DEVICE_HANDLER( via6_pa_w ) |
| 793 | { |
| 794 | /* |
| 795 | |
| 796 | bit description |
| 797 | |
| 798 | PA0 LED0A |
| 799 | PA1 TRK0D0 |
| 800 | PA2 LED1A |
| 801 | PA3 TRK0D1 |
| 802 | PA4 SIDE SELECT |
| 803 | PA5 DRIVE SELECT |
| 804 | PA6 WPS |
| 805 | PA7 SYNC |
| 806 | |
| 807 | */ |
| 808 | |
| 809 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 810 | |
| 811 | /* side select */ |
| 812 | state->side = BIT(data, 4); |
| 813 | |
| 814 | /* drive select */ |
| 815 | state->drive = BIT(data, 5); |
| 816 | } |
| 817 | |
| 818 | static READ8_DEVICE_HANDLER( via6_pb_r ) |
| 819 | { |
| 820 | /* |
| 821 | |
| 822 | bit description |
| 823 | |
| 824 | PB0 RDY0 |
| 825 | PB1 RDY1 |
| 826 | PB2 SCRESET |
| 827 | PB3 _DS1 |
| 828 | PB4 _DS0 |
| 829 | PB5 SINGLE/_DOUBLE SIDED |
| 830 | PB6 stepper enable A |
| 831 | PB7 stepper enable B |
| 832 | |
| 833 | */ |
| 834 | |
| 835 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 836 | |
| 837 | UINT8 data = 0; |
| 838 | |
| 839 | /* drive 0 ready */ |
| 840 | data |= !(floppy_drive_get_flag_state(state->floppy[0].image, FLOPPY_DRIVE_READY) == FLOPPY_DRIVE_READY) << 4; |
| 841 | |
| 842 | /* drive 1 ready */ |
| 843 | data |= !(floppy_drive_get_flag_state(state->floppy[0].image, FLOPPY_DRIVE_READY) == FLOPPY_DRIVE_READY) << 3; |
| 844 | |
| 845 | /* single/double sided */ |
| 846 | data |= floppy_twosid_r(state->floppy[state->drive].image) << 5; |
| 847 | |
| 848 | return data; |
| 849 | } |
| 850 | |
| 851 | static WRITE8_DEVICE_HANDLER( via6_pb_w ) |
| 852 | { |
| 853 | /* |
| 854 | |
| 855 | bit description |
| 856 | |
| 857 | PB0 RDY0 |
| 858 | PB1 RDY1 |
| 859 | PB2 SCRESET |
| 860 | PB3 _DS1 |
| 861 | PB4 _DS0 |
| 862 | PB5 SINGLE/_DOUBLE SIDED |
| 863 | PB6 stepper enable A |
| 864 | PB7 stepper enable B |
| 865 | |
| 866 | */ |
| 867 | |
| 868 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 869 | |
| 870 | /* motor speed controller reset */ |
| 871 | cputag_set_input_line(device->machine, I8048_TAG, INPUT_LINE_RESET, BIT(data, 2)); |
| 872 | |
| 873 | /* stepper enable A */ |
| 874 | state->floppy[0].se = BIT(data, 6); |
| 875 | |
| 876 | /* stepper enable B */ |
| 877 | state->floppy[1].se = BIT(data, 7); |
| 878 | } |
| 879 | |
| 880 | static WRITE_LINE_DEVICE_HANDLER( drw_w ) |
| 881 | { |
| 882 | } |
| 883 | |
| 884 | static WRITE_LINE_DEVICE_HANDLER( erase_w ) |
| 885 | { |
| 886 | } |
| 887 | |
| 888 | static WRITE_LINE_DEVICE_HANDLER( via6_irq_w ) |
| 889 | { |
| 890 | victor9k_state *driver_state = (victor9k_state *)device->machine->driver_data; |
| 891 | |
| 892 | driver_state->via6_irq = state; |
| 893 | |
| 894 | pic8259_ir3_w(driver_state->pic, driver_state->via1_irq | driver_state->via2_irq | driver_state->via3_irq | driver_state->via4_irq | driver_state->via5_irq | driver_state->via6_irq); |
| 895 | } |
| 896 | |
| 897 | static const via6522_interface via6_intf = |
| 898 | { |
| 899 | DEVCB_HANDLER(via6_pa_r), |
| 900 | DEVCB_HANDLER(via6_pb_r), |
| 901 | DEVCB_NULL, // GCRERR |
| 902 | DEVCB_NULL, |
| 903 | DEVCB_NULL, |
| 904 | DEVCB_NULL, |
| 905 | |
| 906 | DEVCB_HANDLER(via6_pa_w), |
| 907 | DEVCB_HANDLER(via6_pb_w), |
| 908 | DEVCB_NULL, |
| 909 | DEVCB_NULL, |
| 910 | DEVCB_LINE(drw_w), |
| 911 | DEVCB_LINE(erase_w), |
| 912 | |
| 913 | DEVCB_LINE(via6_irq_w) |
| 914 | }; |
| 915 | |
| 916 | /* Floppy Configuration */ |
| 917 | |
| 918 | static const floppy_config victor9k_floppy_config = |
| 919 | { |
| 920 | DEVCB_NULL, |
| 921 | DEVCB_NULL, |
| 922 | DEVCB_NULL, |
| 923 | DEVCB_NULL, |
| 924 | DEVCB_NULL, |
| 925 | FLOPPY_DRIVE_DS_80, |
| 926 | FLOPPY_OPTIONS_NAME(default), |
| 927 | DO_NOT_KEEP_GEOMETRY |
| 928 | }; |
| 929 | |
| 930 | /* IEEE-488 Interface */ |
| 931 | |
| 932 | static IEEE488_DAISY( ieee488_daisy ) |
| 933 | { |
| 934 | { M6522_1_TAG, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_LINE(M6522_1_TAG, via_ca1_w), DEVCB_DEVICE_LINE(M6522_1_TAG, via_ca2_w) }, |
| 935 | { NULL } |
| 936 | }; |
| 937 | |
| 938 | /* Machine Initialization */ |
| 939 | |
| 940 | static IRQ_CALLBACK( victor9k_irq_callback ) |
| 941 | { |
| 942 | victor9k_state *state = (victor9k_state *)device->machine->driver_data; |
| 943 | |
| 944 | return pic8259_acknowledge(state->pic); |
| 945 | } |
| 946 | |
| 947 | static MACHINE_START( victor9k ) |
| 948 | { |
| 949 | victor9k_state *state = (victor9k_state *)machine->driver_data; |
| 950 | |
| 951 | /* set interrupt callback */ |
| 952 | cpu_set_irq_callback(machine->firstcpu, victor9k_irq_callback); |
| 953 | |
| 954 | /* find devices */ |
| 955 | state->ieee488 = devtag_get_device(machine, IEEE488_TAG); |
| 956 | state->pic = devtag_get_device(machine, I8259A_TAG); |
| 957 | state->ssda = devtag_get_device(machine, MC6852_TAG); |
| 958 | state->cvsd = devtag_get_device(machine, HC55516_TAG); |
| 959 | state->floppy[0].image = devtag_get_device(machine, FLOPPY_0); |
| 960 | state->floppy[1].image = devtag_get_device(machine, FLOPPY_1); |
| 961 | |
| 962 | /* memory banking */ |
| 963 | const address_space *program = cputag_get_address_space(machine, I8088_TAG, ADDRESS_SPACE_PROGRAM); |
| 964 | UINT8 *ram = messram_get_ptr(devtag_get_device(machine, "messram")); |
| 965 | int ram_size = messram_get_size(devtag_get_device(machine, "messram")); |
| 966 | |
| 967 | memory_install_ram(program, 0x00000, ram_size - 1, 0, 0, ram); |
| 968 | } |
| 969 | |
| 970 | /* Machine Driver */ |
| 971 | |
| 972 | static MACHINE_DRIVER_START( victor9k ) |
| 973 | MDRV_DRIVER_DATA(victor9k_state) |
| 974 | |
| 975 | /* basic machine hardware */ |
| 976 | MDRV_CPU_ADD(I8088_TAG, I8088, XTAL_30MHz/6) |
| 977 | MDRV_CPU_PROGRAM_MAP(victor9k_mem) |
| 978 | |
| 979 | MDRV_CPU_ADD(I8048_TAG, I8048, XTAL_30MHz/6) |
| 980 | MDRV_CPU_IO_MAP(floppy_io) |
| 981 | |
| 982 | // MDRV_CPU_ADD(I8022_TAG, I8022, 100000) |
| 983 | // MDRV_CPU_IO_MAP(keyboard_io) |
| 984 | |
| 985 | MDRV_MACHINE_START(victor9k) |
| 986 | |
| 987 | /* video hardware */ |
| 988 | MDRV_SCREEN_ADD(SCREEN_TAG, RASTER) |
| 989 | MDRV_SCREEN_REFRESH_RATE(50) |
| 990 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 991 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 992 | MDRV_SCREEN_SIZE(640, 480) |
| 993 | MDRV_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1) |
| 994 | |
| 995 | MDRV_PALETTE_LENGTH(2) |
| 996 | MDRV_PALETTE_INIT(monochrome_green) |
| 997 | |
| 998 | MDRV_VIDEO_START(victor9k) |
| 999 | MDRV_VIDEO_UPDATE(victor9k) |
| 1000 | |
| 1001 | MDRV_MC6845_ADD(HD46505S_TAG, H46505, 1000000, hd46505s_intf) |
| 1002 | |
| 1003 | /* sound hardware */ |
| 1004 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 1005 | MDRV_SOUND_ADD(HC55516_TAG, HC55516, 100000) |
| 1006 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 1007 | |
| 1008 | /* devices */ |
| 1009 | MDRV_IEEE488_ADD(IEEE488_TAG, ieee488_daisy) |
| 1010 | MDRV_PIC8259_ADD(I8259A_TAG, pic_intf) |
| 1011 | MDRV_PIT8253_ADD(I8253_TAG, pit_intf) |
| 1012 | MDRV_UPD7201_ADD(UPD7201_TAG, XTAL_30MHz/30, mpsc_intf) |
| 1013 | // MDRV_MC6852_ADD(MC6852_TAG, XTAL_30MHz/30, mc6852_intf) |
| 1014 | MDRV_VIA6522_ADD(M6522_1_TAG, XTAL_30MHz/30, via1_intf) |
| 1015 | MDRV_VIA6522_ADD(M6522_2_TAG, XTAL_30MHz/30, via2_intf) |
| 1016 | MDRV_VIA6522_ADD(M6522_3_TAG, XTAL_30MHz/30, via3_intf) |
| 1017 | MDRV_VIA6522_ADD(M6522_4_TAG, XTAL_30MHz/30, via4_intf) |
| 1018 | MDRV_VIA6522_ADD(M6522_5_TAG, XTAL_30MHz/30, via5_intf) |
| 1019 | MDRV_VIA6522_ADD(M6522_6_TAG, XTAL_30MHz/30, via6_intf) |
| 1020 | MDRV_FLOPPY_2_DRIVES_ADD(victor9k_floppy_config) |
| 1021 | |
| 1022 | /* internal ram */ |
| 1023 | MDRV_RAM_ADD("messram") |
| 1024 | MDRV_RAM_DEFAULT_SIZE("128K") |
| 1025 | MDRV_RAM_EXTRA_OPTIONS("256K,384K,512K,640K,768K,896K") |
| 1026 | MACHINE_DRIVER_END |
| 1027 | |
| 1028 | /* ROMs */ |
| 1029 | |
| 1030 | ROM_START( victor9k ) |
| 1031 | ROM_REGION( 0x2000, I8088_TAG, 0 ) |
| 1032 | ROM_DEFAULT_BIOS( "univ" ) |
| 1033 | ROM_SYSTEM_BIOS( 0, "old", "Older" ) |
| 1034 | ROMX_LOAD( "102320.7j", 0x0000, 0x1000, CRC(3d615fd7) SHA1(b22f7e5d66404185395d8effbf57efded0079a92), ROM_BIOS(1) ) |
| 1035 | ROMX_LOAD( "102322.8j", 0x1000, 0x1000, CRC(9209df0e) SHA1(3ee8e0c15186bbd5768b550ecc1fa3b6b1dbb928), ROM_BIOS(1) ) |
| 1036 | ROM_SYSTEM_BIOS( 1, "univ", "Universal" ) |
| 1037 | ROMX_LOAD( "v9000 univ. fe f3f7 13db.7j", 0x0000, 0x1000, CRC(25c7a59f) SHA1(8784e9aa7eb9439f81e18b8e223c94714e033911), ROM_BIOS(2) ) |
| 1038 | ROMX_LOAD( "v9000 univ. ff f3f7 39fe.8j", 0x1000, 0x1000, CRC(496c7467) SHA1(eccf428f62ef94ab85f4a43ba59ae6a066244a66), ROM_BIOS(2) ) |
| 1039 | |
| 1040 | ROM_REGION( 0x800, "gcr", 0 ) |
| 1041 | ROM_LOAD( "100836-001.4k", 0x000, 0x800, CRC(adc601bd) SHA1(6eeff3d2063ae2d97452101aa61e27ef83a467e5) ) |
| 1042 | |
| 1043 | ROM_REGION( 0x400, I8048_TAG, 0) |
| 1044 | ROM_LOAD( "36080.5d", 0x000, 0x400, CRC(9bf49f7d) SHA1(b3a11bb65105db66ae1985b6f482aab6ea1da38b) ) |
| 1045 | |
| 1046 | ROM_REGION( 0x800, I8022_TAG, 0) |
| 1047 | ROM_LOAD( "keyboard controller i8022", 0x000, 0x800, NO_DUMP ) |
| 1048 | ROM_END |
| 1049 | |
| 1050 | /* System Drivers */ |
| 1051 | |
| 1052 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 1053 | COMP( 1982, victor9k, 0, 0, victor9k, victor9k, 0, "Victor Business Products", "Victor 9000", GAME_NOT_WORKING ) |