src/mess/drivers/mycom.c
| r9684 | r9685 | |
| 56 | 56 | #include "devices/flopdrv.h" |
| 57 | 57 | #include "formats/basicdsk.h" |
| 58 | 58 | |
| 59 | | static running_device *mc6845; |
| 60 | | static running_device *mycom_audio; |
| 61 | | static running_device *mycom_cassette; |
| 62 | | static running_device *mycom_fdc; |
| 63 | | static UINT8 *vram; |
| 64 | | static UINT8 *gfx_rom; |
| 65 | | static UINT16 vram_addr; |
| 66 | | static UINT8 keyb_press,keyb_press_flag; |
| 67 | | static UINT8 mycom_0a,sn_we; |
| 68 | | static UINT32 upper_sw; |
| 69 | | static UINT8 *RAM; |
| 70 | 59 | |
| 60 | class mycom_state : public driver_device |
| 61 | { |
| 62 | public: |
| 63 | mycom_state(running_machine &machine, const driver_device_config_base &config) |
| 64 | : driver_device(machine, config) { } |
| 65 | |
| 66 | running_device *mc6845; |
| 67 | running_device *audio; |
| 68 | running_device *cassette; |
| 69 | running_device *fdc; |
| 70 | UINT8 *vram; |
| 71 | UINT8 *gfx_rom; |
| 72 | UINT16 vram_addr; |
| 73 | UINT8 keyb_press; |
| 74 | UINT8 keyb_press_flag; |
| 75 | UINT8 _0a; |
| 76 | UINT8 sn_we; |
| 77 | UINT32 upper_sw; |
| 78 | UINT8 *RAM; |
| 79 | }; |
| 80 | |
| 81 | |
| 82 | |
| 71 | 83 | static VIDEO_START( mycom ) |
| 72 | 84 | { |
| 73 | | mc6845 = machine->device("crtc"); |
| 74 | | vram = memory_region(machine, "vram"); |
| 75 | | gfx_rom = memory_region(machine, "gfx"); |
| 85 | mycom_state *state = machine->driver_data<mycom_state>(); |
| 86 | state->mc6845 = machine->device("crtc"); |
| 87 | state->vram = memory_region(machine, "vram"); |
| 88 | state->gfx_rom = memory_region(machine, "gfx"); |
| 76 | 89 | } |
| 77 | 90 | |
| 78 | 91 | static VIDEO_UPDATE( mycom ) |
| 79 | 92 | { |
| 80 | | mc6845_update(mc6845, bitmap, cliprect); |
| 93 | mycom_state *state = screen->machine->driver_data<mycom_state>(); |
| 94 | mc6845_update(state->mc6845, bitmap, cliprect); |
| 81 | 95 | return 0; |
| 82 | 96 | } |
| 83 | 97 | |
| 84 | 98 | static MC6845_UPDATE_ROW( mycom_update_row ) |
| 85 | 99 | { |
| 100 | mycom_state *state = device->machine->driver_data<mycom_state>(); |
| 86 | 101 | UINT8 chr,gfx=0,z; |
| 87 | 102 | UINT16 mem,x; |
| 88 | 103 | UINT16 *p = BITMAP_ADDR16(bitmap, y, 0); |
| 89 | 104 | |
| 90 | | if (mycom_0a & 0x40) |
| 105 | if (state->_0a & 0x40) |
| 91 | 106 | { |
| 92 | 107 | for (x = 0; x < x_count; x++) // lores pixels |
| 93 | 108 | { |
| 94 | 109 | UINT8 dbit=1; |
| 95 | 110 | if (x == cursor_x) dbit=0; |
| 96 | 111 | mem = (ma + x) & 0x7ff; |
| 97 | | chr = vram[mem]; |
| 112 | chr = state->vram[mem]; |
| 98 | 113 | z = ra / 3; |
| 99 | 114 | *p++ = BIT( chr, z ) ? dbit: dbit^1; |
| 100 | 115 | *p++ = BIT( chr, z ) ? dbit: dbit^1; |
| r9684 | r9685 | |
| 118 | 133 | gfx = inv; // some blank spacing lines |
| 119 | 134 | else |
| 120 | 135 | { |
| 121 | | chr = vram[mem]; |
| 122 | | gfx = gfx_rom[(chr<<3) | ra] ^ inv; |
| 136 | chr = state->vram[mem]; |
| 137 | gfx = state->gfx_rom[(chr<<3) | ra] ^ inv; |
| 123 | 138 | } |
| 124 | 139 | |
| 125 | 140 | /* Display a scanline of a character */ |
| r9684 | r9685 | |
| 137 | 152 | |
| 138 | 153 | static WRITE8_HANDLER( mycom_00_w ) |
| 139 | 154 | { |
| 155 | mycom_state *state = space->machine->driver_data<mycom_state>(); |
| 140 | 156 | switch(data) |
| 141 | 157 | { |
| 142 | 158 | case 0x00: memory_set_bank(space->machine, "boot", 1); break; |
| 143 | 159 | case 0x01: memory_set_bank(space->machine, "boot", 0); break; |
| 144 | | case 0x02: upper_sw = 0x10000; break; |
| 145 | | case 0x03: upper_sw = 0x0c000; break; |
| 160 | case 0x02: state->upper_sw = 0x10000; break; |
| 161 | case 0x03: state->upper_sw = 0x0c000; break; |
| 146 | 162 | } |
| 147 | 163 | } |
| 148 | 164 | |
| 149 | 165 | static READ8_HANDLER( mycom_upper_r ) |
| 150 | 166 | { |
| 151 | | return RAM[offset | upper_sw]; |
| 167 | mycom_state *state = space->machine->driver_data<mycom_state>(); |
| 168 | return state->RAM[offset | state->upper_sw]; |
| 152 | 169 | } |
| 153 | 170 | |
| 154 | 171 | static WRITE8_HANDLER( mycom_upper_w ) |
| 155 | 172 | { |
| 156 | | RAM[offset | 0xc000] = data; |
| 173 | mycom_state *state = space->machine->driver_data<mycom_state>(); |
| 174 | state->RAM[offset | 0xc000] = data; |
| 157 | 175 | } |
| 158 | 176 | |
| 159 | 177 | static READ8_HANDLER( vram_data_r ) |
| 160 | 178 | { |
| 161 | | return vram[vram_addr]; |
| 179 | mycom_state *state = space->machine->driver_data<mycom_state>(); |
| 180 | return state->vram[state->vram_addr]; |
| 162 | 181 | } |
| 163 | 182 | |
| 164 | 183 | static WRITE8_HANDLER( vram_data_w ) |
| 165 | 184 | { |
| 166 | | vram[vram_addr] = data; |
| 185 | mycom_state *state = space->machine->driver_data<mycom_state>(); |
| 186 | state->vram[state->vram_addr] = data; |
| 167 | 187 | } |
| 168 | 188 | |
| 169 | 189 | static ADDRESS_MAP_START(mycom_map, ADDRESS_SPACE_PROGRAM, 8) |
| r9684 | r9685 | |
| 312 | 332 | |
| 313 | 333 | static WRITE8_DEVICE_HANDLER( mycom_04_w ) |
| 314 | 334 | { |
| 315 | | vram_addr = (vram_addr & 0x700) | data; |
| 335 | mycom_state *state = device->machine->driver_data<mycom_state>(); |
| 336 | state->vram_addr = (state->vram_addr & 0x700) | data; |
| 316 | 337 | |
| 317 | | sn_we = data; |
| 338 | state->sn_we = data; |
| 318 | 339 | /* doesn't work? */ |
| 319 | 340 | //printf(":%X ",data); |
| 320 | | //if(sn_we) |
| 321 | | //sn76496_w(mycom_audio, 0, data); |
| 341 | //if(state->sn_we) |
| 342 | //sn76496_w(state->audio, 0, data); |
| 322 | 343 | } |
| 323 | 344 | |
| 324 | 345 | static WRITE8_DEVICE_HANDLER( mycom_06_w ) |
| 325 | 346 | { |
| 326 | | vram_addr = (vram_addr & 0x0ff) | ((data & 0x007) << 8); |
| 347 | mycom_state *state = device->machine->driver_data<mycom_state>(); |
| 348 | state->vram_addr = (state->vram_addr & 0x0ff) | ((data & 0x007) << 8); |
| 327 | 349 | } |
| 328 | 350 | |
| 329 | 351 | static READ8_DEVICE_HANDLER( mycom_08_r ) |
| 330 | 352 | { |
| 353 | mycom_state *state = device->machine->driver_data<mycom_state>(); |
| 331 | 354 | /* |
| 332 | 355 | x--- ---- display flag |
| 333 | 356 | ---- --x- keyboard shift |
| r9684 | r9685 | |
| 335 | 358 | */ |
| 336 | 359 | UINT8 data = 0; |
| 337 | 360 | |
| 338 | | data = keyb_press_flag; //~keyb_press_flag & 1; |
| 361 | data = state->keyb_press_flag; //~state->keyb_press_flag & 1; |
| 339 | 362 | |
| 340 | | if (cassette_input(mycom_cassette) > 0.03) // not working |
| 363 | if (cassette_input(state->cassette) > 0.03) // not working |
| 341 | 364 | data+=4; |
| 342 | 365 | |
| 343 | 366 | return data; |
| r9684 | r9685 | |
| 356 | 379 | |
| 357 | 380 | static READ8_DEVICE_HANDLER( mycom_05_r ) |
| 358 | 381 | { |
| 359 | | return keyb_press; |
| 382 | mycom_state *state = device->machine->driver_data<mycom_state>(); |
| 383 | return state->keyb_press; |
| 360 | 384 | } |
| 361 | 385 | |
| 362 | 386 | static WRITE8_DEVICE_HANDLER( mycom_0a_w ) |
| 363 | 387 | { |
| 388 | mycom_state *state = device->machine->driver_data<mycom_state>(); |
| 364 | 389 | /* |
| 365 | 390 | x--- ---- width 80/40 (0 = 80, 1 = 40) |
| 366 | 391 | -x-- ---- video mode (0= tile, 1 = bitmap) |
| r9684 | r9685 | |
| 372 | 397 | ---- ---x printer strobe |
| 373 | 398 | */ |
| 374 | 399 | |
| 375 | | if ((mycom_0a & 8) != (data & 8)) |
| 376 | | cassette_change_state(mycom_cassette, |
| 400 | if ((state->_0a & 8) != (data & 8)) |
| 401 | cassette_change_state(state->cassette, |
| 377 | 402 | (data & 8) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); |
| 378 | 403 | |
| 379 | 404 | if (data & 8) // motor on |
| 380 | | cassette_output(mycom_cassette, (data & 4) ? -1.0 : +1.0); |
| 405 | cassette_output(state->cassette, (data & 4) ? -1.0 : +1.0); |
| 381 | 406 | |
| 382 | | if ((data & 0x80) != (mycom_0a & 0x80)) |
| 383 | | mc6845_set_clock(mc6845, (data & 0x80) ? 1008000 : 2016000); |
| 407 | if ((data & 0x80) != (state->_0a & 0x80)) |
| 408 | mc6845_set_clock(state->mc6845, (data & 0x80) ? 1008000 : 2016000); |
| 384 | 409 | |
| 385 | | mycom_0a = data; |
| 410 | state->_0a = data; |
| 386 | 411 | |
| 387 | 412 | /* Info about sound |
| 388 | 413 | - uses a SN76489N chip at an unknown clock |
| r9684 | r9685 | |
| 394 | 419 | |
| 395 | 420 | // no sound comes out |
| 396 | 421 | if ((data & 0x30)==0) |
| 397 | | sn76496_w(mycom_audio, 0, sn_we); |
| 422 | sn76496_w(state->audio, 0, state->sn_we); |
| 398 | 423 | } |
| 399 | 424 | |
| 400 | 425 | static I8255A_INTERFACE( ppi8255_intf_0 ) |
| r9684 | r9685 | |
| 441 | 466 | |
| 442 | 467 | static TIMER_CALLBACK( mycom_kbd ) |
| 443 | 468 | { |
| 469 | mycom_state *state = machine->driver_data<mycom_state>(); |
| 444 | 470 | UINT8 x, y, scancode = 0; |
| 445 | 471 | UINT16 pressed[9]; |
| 446 | 472 | char kbdrow[2]; |
| 447 | 473 | UINT8 modifiers = input_port_read(machine, "XX"); |
| 448 | 474 | UINT8 shift_pressed = (modifiers & 2) >> 1; |
| 449 | | keyb_press_flag = 0; |
| 475 | state->keyb_press_flag = 0; |
| 450 | 476 | |
| 451 | 477 | /* see what is pressed */ |
| 452 | 478 | for (x = 0; x < 9; x++) |
| r9684 | r9685 | |
| 466 | 492 | if (BIT(pressed[x], y)) |
| 467 | 493 | { |
| 468 | 494 | scancode = ((x + y * 9) << 1) + shift_pressed + 1; |
| 469 | | keyb_press_flag = 1; |
| 470 | | keyb_press = mycom_keyval[scancode]; |
| 495 | state->keyb_press_flag = 1; |
| 496 | state->keyb_press = mycom_keyval[scancode]; |
| 471 | 497 | } |
| 472 | 498 | } |
| 473 | 499 | } |
| 474 | 500 | } |
| 475 | 501 | |
| 476 | | if (keyb_press_flag) |
| 502 | if (state->keyb_press_flag) |
| 477 | 503 | { |
| 478 | | if (modifiers & 1) keyb_press &= 0xbf; |
| 479 | | if (modifiers & 4) keyb_press |= 0x80; |
| 504 | if (modifiers & 1) state->keyb_press &= 0xbf; |
| 505 | if (modifiers & 4) state->keyb_press |= 0x80; |
| 480 | 506 | } |
| 481 | 507 | } |
| 482 | 508 | |
| 483 | 509 | static MACHINE_START(mycom) |
| 484 | 510 | { |
| 485 | | mycom_audio = machine->device("sn1"); |
| 486 | | mycom_cassette = machine->device("cassette"); |
| 487 | | mycom_fdc = machine->device("fdc"); |
| 488 | | RAM = memory_region(machine, "maincpu"); |
| 511 | mycom_state *state = machine->driver_data<mycom_state>(); |
| 512 | state->audio = machine->device("sn1"); |
| 513 | state->cassette = machine->device("cassette"); |
| 514 | state->fdc = machine->device("fdc"); |
| 515 | state->RAM = memory_region(machine, "maincpu"); |
| 489 | 516 | timer_pulse(machine, ATTOTIME_IN_HZ(20), NULL, 0, mycom_kbd); |
| 490 | 517 | } |
| 491 | 518 | |
| 492 | 519 | static MACHINE_RESET(mycom) |
| 493 | 520 | { |
| 521 | mycom_state *state = machine->driver_data<mycom_state>(); |
| 494 | 522 | memory_set_bank(machine, "boot", 1); |
| 495 | | upper_sw = 0x10000; |
| 496 | | mycom_0a = 0; |
| 523 | state->upper_sw = 0x10000; |
| 524 | state->_0a = 0; |
| 497 | 525 | } |
| 498 | 526 | |
| 499 | 527 | static DRIVER_INIT( mycom ) |
| r9684 | r9685 | |
| 502 | 530 | memory_configure_bank(machine, "boot", 0, 2, &RAM[0x0000], 0x10000); |
| 503 | 531 | } |
| 504 | 532 | |
| 505 | | static MACHINE_CONFIG_START( mycom, driver_device ) |
| 533 | static MACHINE_CONFIG_START( mycom, mycom_state ) |
| 506 | 534 | /* basic machine hardware */ |
| 507 | 535 | MDRV_CPU_ADD("maincpu",Z80, XTAL_10MHz / 4) |
| 508 | 536 | MDRV_CPU_PROGRAM_MAP(mycom_map) |
src/mess/drivers/tm990189.c
| r9684 | r9685 | |
| 47 | 47 | #include "sound/wave.h" |
| 48 | 48 | #include "machine/serial.h" |
| 49 | 49 | |
| 50 | | static int load_state; |
| 51 | | static int ic_state; |
| 52 | 50 | |
| 53 | | static int digitsel; |
| 54 | | static int segment; |
| 51 | class tm990189_state : public driver_device |
| 52 | { |
| 53 | public: |
| 54 | tm990189_state(running_machine &machine, const driver_device_config_base &config) |
| 55 | : driver_device(machine, config) { } |
| 55 | 56 | |
| 56 | | static emu_timer *displayena_timer; |
| 57 | int load_state; |
| 58 | int ic_state; |
| 59 | int digitsel; |
| 60 | int segment; |
| 61 | emu_timer *displayena_timer; |
| 62 | UINT8 segment_state[10]; |
| 63 | UINT8 old_segment_state[10]; |
| 64 | UINT8 LED_state; |
| 65 | emu_timer *joy1x_timer; |
| 66 | emu_timer *joy1y_timer; |
| 67 | emu_timer *joy2x_timer; |
| 68 | emu_timer *joy2y_timer; |
| 69 | int LED_display_window_left; |
| 70 | int LED_display_window_top; |
| 71 | int LED_display_window_width; |
| 72 | int LED_display_window_height; |
| 73 | device_image_interface *rs232_fp; |
| 74 | UINT8 rs232_rts; |
| 75 | emu_timer *rs232_input_timer; |
| 76 | }; |
| 77 | |
| 78 | |
| 79 | |
| 80 | |
| 57 | 81 | #define displayena_duration ATTOTIME_IN_USEC(4500) /* Can anyone confirm this? 74LS123 connected to C=0.1uF and R=100kOhm */ |
| 58 | | static UINT8 segment_state[10]; |
| 59 | | static UINT8 old_segment_state[10]; |
| 60 | | static UINT8 LED_state; |
| 61 | 82 | |
| 62 | | static emu_timer *joy1x_timer; |
| 63 | | static emu_timer *joy1y_timer; |
| 64 | | static emu_timer *joy2x_timer; |
| 65 | | static emu_timer *joy2y_timer; |
| 66 | 83 | |
| 67 | 84 | enum |
| 68 | 85 | { |
| r9684 | r9685 | |
| 74 | 91 | 0xFF,0x00,0x00 /* red for LEDs */ |
| 75 | 92 | }; |
| 76 | 93 | |
| 77 | | static int LED_display_window_left; |
| 78 | | static int LED_display_window_top; |
| 79 | | static int LED_display_window_width; |
| 80 | | static int LED_display_window_height; |
| 81 | 94 | |
| 82 | 95 | static void hold_load(running_machine *machine); |
| 83 | 96 | |
| 84 | 97 | |
| 85 | | static device_image_interface *rs232_fp; |
| 86 | | static UINT8 rs232_rts; |
| 87 | | static emu_timer *rs232_input_timer; |
| 88 | 98 | |
| 89 | 99 | static MACHINE_RESET( tm990_189 ) |
| 90 | 100 | { |
| r9684 | r9685 | |
| 93 | 103 | |
| 94 | 104 | static MACHINE_START( tm990_189 ) |
| 95 | 105 | { |
| 96 | | displayena_timer = timer_alloc(machine, NULL, NULL); |
| 106 | tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 107 | state->displayena_timer = timer_alloc(machine, NULL, NULL); |
| 97 | 108 | } |
| 98 | 109 | static const TMS9928a_interface tms9918_interface = |
| 99 | 110 | { |
| r9684 | r9685 | |
| 105 | 116 | |
| 106 | 117 | static MACHINE_START( tm990_189_v ) |
| 107 | 118 | { |
| 119 | tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 108 | 120 | TMS9928A_configure(&tms9918_interface); |
| 109 | 121 | |
| 110 | | displayena_timer = timer_alloc(machine, NULL, NULL); |
| 122 | state->displayena_timer = timer_alloc(machine, NULL, NULL); |
| 111 | 123 | |
| 112 | | joy1x_timer = timer_alloc(machine, NULL, NULL); |
| 113 | | joy1y_timer = timer_alloc(machine, NULL, NULL); |
| 114 | | joy2x_timer = timer_alloc(machine, NULL, NULL); |
| 115 | | joy2y_timer = timer_alloc(machine, NULL, NULL); |
| 124 | state->joy1x_timer = timer_alloc(machine, NULL, NULL); |
| 125 | state->joy1y_timer = timer_alloc(machine, NULL, NULL); |
| 126 | state->joy2x_timer = timer_alloc(machine, NULL, NULL); |
| 127 | state->joy2y_timer = timer_alloc(machine, NULL, NULL); |
| 116 | 128 | } |
| 117 | 129 | |
| 118 | 130 | static MACHINE_RESET( tm990_189_v ) |
| r9684 | r9685 | |
| 141 | 153 | |
| 142 | 154 | static VIDEO_EOF( tm990_189 ) |
| 143 | 155 | { |
| 156 | tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 144 | 157 | int i; |
| 145 | 158 | |
| 146 | 159 | for (i=0; i<10; i++) |
| 147 | | segment_state[i] = 0; |
| 160 | state->segment_state[i] = 0; |
| 148 | 161 | } |
| 149 | 162 | |
| 150 | | INLINE void draw_digit(void) |
| 163 | INLINE void draw_digit(tm990189_state *state) |
| 151 | 164 | { |
| 152 | | segment_state[digitsel] |= ~segment; |
| 165 | state->segment_state[state->digitsel] |= ~state->segment; |
| 153 | 166 | } |
| 154 | 167 | |
| 155 | | static void update_common(bitmap_t *bitmap, |
| 168 | static void update_common(running_machine *machine, bitmap_t *bitmap, |
| 156 | 169 | int display_x, int display_y, |
| 157 | 170 | int LED14_x, int LED14_y, |
| 158 | 171 | int LED56_x, int LED56_y, |
| 159 | 172 | int LED7_x, int LED7_y, |
| 160 | 173 | pen_t fore_color, pen_t back_color) |
| 161 | 174 | { |
| 175 | tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 162 | 176 | int i, j; |
| 163 | 177 | static const struct{ int x, y; int w, h; } bounds[8] = |
| 164 | 178 | { |
| r9684 | r9685 | |
| 174 | 188 | |
| 175 | 189 | for (i=0; i<10; i++) |
| 176 | 190 | { |
| 177 | | old_segment_state[i] |= segment_state[i]; |
| 191 | state->old_segment_state[i] |= state->segment_state[i]; |
| 178 | 192 | |
| 179 | 193 | for (j=0; j<8; j++) |
| 180 | 194 | plot_box(bitmap, display_x + i*16 + bounds[j].x, display_y + bounds[j].y, |
| 181 | 195 | bounds[j].w, bounds[j].h, |
| 182 | | (old_segment_state[i] & (1 << j)) ? fore_color : back_color); |
| 196 | (state->old_segment_state[i] & (1 << j)) ? fore_color : back_color); |
| 183 | 197 | |
| 184 | | old_segment_state[i] = segment_state[i]; |
| 198 | state->old_segment_state[i] = state->segment_state[i]; |
| 185 | 199 | } |
| 186 | 200 | |
| 187 | 201 | for (i=0; i<4; i++) |
| 188 | 202 | { |
| 189 | 203 | plot_box(bitmap, LED14_x + 48+4 - i*16, LED14_y + 4, 8, 8, |
| 190 | | (LED_state & (1 << i)) ? fore_color : back_color); |
| 204 | (state->LED_state & (1 << i)) ? fore_color : back_color); |
| 191 | 205 | } |
| 192 | 206 | |
| 193 | 207 | plot_box(bitmap, LED7_x+4, LED7_y+4, 8, 8, |
| 194 | | (LED_state & 0x10) ? fore_color : back_color); |
| 208 | (state->LED_state & 0x10) ? fore_color : back_color); |
| 195 | 209 | |
| 196 | 210 | plot_box(bitmap, LED56_x+16+4, LED56_y+4, 8, 8, |
| 197 | | (LED_state & 0x20) ? fore_color : back_color); |
| 211 | (state->LED_state & 0x20) ? fore_color : back_color); |
| 198 | 212 | |
| 199 | 213 | plot_box(bitmap, LED56_x+4, LED56_y+4, 8, 8, |
| 200 | | (LED_state & 0x40) ? fore_color : back_color); |
| 214 | (state->LED_state & 0x40) ? fore_color : back_color); |
| 201 | 215 | } |
| 202 | 216 | |
| 203 | 217 | static VIDEO_UPDATE( tm990_189 ) |
| 204 | 218 | { |
| 205 | | update_common(bitmap, 580, 150, 110, 508, 387, 456, 507, 478, 1, 0); |
| 219 | update_common(screen->machine, bitmap, 580, 150, 110, 508, 387, 456, 507, 478, 1, 0); |
| 206 | 220 | return 0; |
| 207 | 221 | } |
| 208 | 222 | |
| 209 | 223 | static VIDEO_START( tm990_189_v ) |
| 210 | 224 | { |
| 225 | tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 211 | 226 | screen_device *screen = screen_first(*machine); |
| 212 | 227 | const rectangle &visarea = screen->visible_area(); |
| 213 | 228 | |
| 214 | 229 | /* NPW 27-Feb-2006 - ewwww gross!!! maybe this can be fixed when |
| 215 | 230 | * multimonitor support is added?*/ |
| 216 | | LED_display_window_left = visarea.min_x; |
| 217 | | LED_display_window_top = visarea.max_y - 32; |
| 218 | | LED_display_window_width = visarea.max_x - visarea.min_x; |
| 219 | | LED_display_window_height = 32; |
| 231 | state->LED_display_window_left = visarea.min_x; |
| 232 | state->LED_display_window_top = visarea.max_y - 32; |
| 233 | state->LED_display_window_width = visarea.max_x - visarea.min_x; |
| 234 | state->LED_display_window_height = 32; |
| 220 | 235 | } |
| 221 | 236 | |
| 222 | 237 | static VIDEO_UPDATE( tm990_189_v ) |
| 223 | 238 | { |
| 239 | tm990189_state *state = screen->machine->driver_data<tm990189_state>(); |
| 224 | 240 | VIDEO_UPDATE_CALL(tms9928a); |
| 225 | 241 | |
| 226 | | plot_box(bitmap, LED_display_window_left, LED_display_window_top, LED_display_window_width, LED_display_window_height, screen->machine->pens[1]); |
| 227 | | update_common(bitmap, |
| 228 | | LED_display_window_left, LED_display_window_top, |
| 229 | | LED_display_window_left, LED_display_window_top+16, |
| 230 | | LED_display_window_left+80, LED_display_window_top+16, |
| 231 | | LED_display_window_left+128, LED_display_window_top+16, |
| 242 | plot_box(bitmap, state->LED_display_window_left, state->LED_display_window_top, state->LED_display_window_width, state->LED_display_window_height, screen->machine->pens[1]); |
| 243 | update_common(screen->machine, bitmap, |
| 244 | state->LED_display_window_left, state->LED_display_window_top, |
| 245 | state->LED_display_window_left, state->LED_display_window_top+16, |
| 246 | state->LED_display_window_left+80, state->LED_display_window_top+16, |
| 247 | state->LED_display_window_left+128, state->LED_display_window_top+16, |
| 232 | 248 | 6, 1); |
| 233 | 249 | return 0; |
| 234 | 250 | } |
| r9684 | r9685 | |
| 239 | 255 | |
| 240 | 256 | static void field_interrupts(running_machine *machine) |
| 241 | 257 | { |
| 242 | | if (load_state) |
| 258 | tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 259 | if (state->load_state) |
| 243 | 260 | cputag_set_input_line_and_vector(machine, "maincpu", 0, ASSERT_LINE, 2); |
| 244 | 261 | else |
| 245 | | cputag_set_input_line_and_vector(machine, "maincpu", 0, ASSERT_LINE, ic_state); |
| 262 | cputag_set_input_line_and_vector(machine, "maincpu", 0, ASSERT_LINE, state->ic_state); |
| 246 | 263 | } |
| 247 | 264 | |
| 248 | 265 | /* |
| r9684 | r9685 | |
| 251 | 268 | |
| 252 | 269 | static TIMER_CALLBACK(clear_load) |
| 253 | 270 | { |
| 254 | | load_state = FALSE; |
| 271 | tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 272 | state->load_state = FALSE; |
| 255 | 273 | field_interrupts(machine); |
| 256 | 274 | } |
| 257 | 275 | |
| 258 | 276 | static void hold_load(running_machine *machine) |
| 259 | 277 | { |
| 260 | | load_state = TRUE; |
| 278 | tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 279 | state->load_state = TRUE; |
| 261 | 280 | field_interrupts(machine); |
| 262 | 281 | timer_set(machine, ATTOTIME_IN_MSEC(100), NULL, 0, clear_load); |
| 263 | 282 | } |
| r9684 | r9685 | |
| 268 | 287 | |
| 269 | 288 | static TMS9901_INT_CALLBACK ( usr9901_interrupt_callback ) |
| 270 | 289 | { |
| 271 | | ic_state = ic & 7; |
| 290 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 291 | state->ic_state = ic & 7; |
| 272 | 292 | |
| 273 | | if (!load_state) |
| 293 | if (!state->load_state) |
| 274 | 294 | field_interrupts(device->machine); |
| 275 | 295 | } |
| 276 | 296 | |
| 277 | 297 | static WRITE8_DEVICE_HANDLER( usr9901_led_w ) |
| 278 | 298 | { |
| 299 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 279 | 300 | if (data) |
| 280 | | LED_state |= (1 << offset); |
| 301 | state->LED_state |= (1 << offset); |
| 281 | 302 | else |
| 282 | | LED_state &= ~(1 << offset); |
| 303 | state->LED_state &= ~(1 << offset); |
| 283 | 304 | } |
| 284 | 305 | |
| 285 | 306 | static TMS9901_INT_CALLBACK( sys9901_interrupt_callback ) |
| r9684 | r9685 | |
| 291 | 312 | |
| 292 | 313 | static READ8_DEVICE_HANDLER( sys9901_r0 ) |
| 293 | 314 | { |
| 315 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 294 | 316 | int reply = 0x00; |
| 295 | 317 | static const char *const keynames[] = { "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", "LINE6", "LINE7", "LINE8" }; |
| 296 | 318 | |
| 297 | 319 | /* keyboard read */ |
| 298 | | if (digitsel < 9) |
| 299 | | reply |= input_port_read(device->machine, keynames[digitsel]) << 1; |
| 320 | if (state->digitsel < 9) |
| 321 | reply |= input_port_read(device->machine, keynames[state->digitsel]) << 1; |
| 300 | 322 | |
| 301 | 323 | /* tape input */ |
| 302 | 324 | if (cassette_input(device->machine->device("cassette")) > 0.0) |
| r9684 | r9685 | |
| 307 | 329 | |
| 308 | 330 | static WRITE8_DEVICE_HANDLER( sys9901_digitsel_w ) |
| 309 | 331 | { |
| 332 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 310 | 333 | if (data) |
| 311 | | digitsel |= 1 << offset; |
| 334 | state->digitsel |= 1 << offset; |
| 312 | 335 | else |
| 313 | | digitsel &= ~ (1 << offset); |
| 336 | state->digitsel &= ~ (1 << offset); |
| 314 | 337 | } |
| 315 | 338 | |
| 316 | 339 | static WRITE8_DEVICE_HANDLER( sys9901_segment_w ) |
| 317 | 340 | { |
| 341 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 318 | 342 | if (data) |
| 319 | | segment |= 1 << (offset-4); |
| 343 | state->segment |= 1 << (offset-4); |
| 320 | 344 | else |
| 321 | 345 | { |
| 322 | | segment &= ~ (1 << (offset-4)); |
| 323 | | if ((attotime_compare(timer_timeleft(displayena_timer), attotime_zero) > 0) && (digitsel < 10)) |
| 324 | | draw_digit(); |
| 346 | state->segment &= ~ (1 << (offset-4)); |
| 347 | if ((attotime_compare(timer_timeleft(state->displayena_timer), attotime_zero) > 0) && (state->digitsel < 10)) |
| 348 | draw_digit(state); |
| 325 | 349 | } |
| 326 | 350 | } |
| 327 | 351 | |
| 328 | 352 | static WRITE8_DEVICE_HANDLER( sys9901_dsplytrgr_w ) |
| 329 | 353 | { |
| 330 | | if ((!data) && (digitsel < 10)) |
| 354 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 355 | if ((!data) && (state->digitsel < 10)) |
| 331 | 356 | { |
| 332 | | timer_reset(displayena_timer, displayena_duration); |
| 333 | | draw_digit(); |
| 357 | timer_reset(state->displayena_timer, displayena_duration); |
| 358 | draw_digit(state); |
| 334 | 359 | } |
| 335 | 360 | } |
| 336 | 361 | |
| 337 | 362 | static WRITE8_DEVICE_HANDLER( sys9901_shiftlight_w ) |
| 338 | 363 | { |
| 364 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 339 | 365 | if (data) |
| 340 | | LED_state |= 0x10; |
| 366 | state->LED_state |= 0x10; |
| 341 | 367 | else |
| 342 | | LED_state &= ~0x10; |
| 368 | state->LED_state &= ~0x10; |
| 343 | 369 | } |
| 344 | 370 | |
| 345 | 371 | static WRITE8_DEVICE_HANDLER( sys9901_spkrdrive_w ) |
| r9684 | r9685 | |
| 359 | 385 | |
| 360 | 386 | static TIMER_CALLBACK(rs232_input_callback) |
| 361 | 387 | { |
| 388 | //tm990189_state *state = machine->driver_data<tm990189_state>(); |
| 362 | 389 | UINT8 buf; |
| 363 | 390 | device_image_interface *image = (device_image_interface *)(ptr); |
| 364 | | if (/*rs232_rts &&*/ /*(mame_ftell(rs232_fp) < mame_fsize(rs232_fp))*/1) |
| 391 | if (/*state->rs232_rts &&*/ /*(mame_ftell(state->rs232_fp) < mame_fsize(state->rs232_fp))*/1) |
| 365 | 392 | { |
| 366 | 393 | if (image->fread(&buf, 1) == 1) |
| 367 | 394 | tms9902_push_data(machine->device("tms9902"), buf); |
| r9684 | r9685 | |
| 373 | 400 | */ |
| 374 | 401 | static DEVICE_IMAGE_LOAD( tm990_189_rs232 ) |
| 375 | 402 | { |
| 403 | tm990189_state *state = image.device().machine->driver_data<tm990189_state>(); |
| 376 | 404 | tms9902_set_dsr(image.device().machine->device("tms9902"), 1); |
| 377 | | rs232_input_timer = timer_alloc(image.device().machine, rs232_input_callback, (void*)image); |
| 378 | | timer_adjust_periodic(rs232_input_timer, attotime_zero, 0, ATTOTIME_IN_MSEC(10)); |
| 405 | state->rs232_input_timer = timer_alloc(image.device().machine, rs232_input_callback, (void*)image); |
| 406 | timer_adjust_periodic(state->rs232_input_timer, attotime_zero, 0, ATTOTIME_IN_MSEC(10)); |
| 379 | 407 | |
| 380 | 408 | return IMAGE_INIT_PASS; |
| 381 | 409 | } |
| r9684 | r9685 | |
| 385 | 413 | */ |
| 386 | 414 | static DEVICE_IMAGE_UNLOAD( tm990_189_rs232 ) |
| 387 | 415 | { |
| 416 | tm990189_state *state = image.device().machine->driver_data<tm990189_state>(); |
| 388 | 417 | tms9902_set_dsr(image.device().machine->device("tms9902"), 0); |
| 389 | 418 | |
| 390 | | timer_reset(rs232_input_timer, attotime_never); /* FIXME - timers should only be allocated once */ |
| 419 | timer_reset(state->rs232_input_timer, attotime_never); /* FIXME - timers should only be allocated once */ |
| 391 | 420 | } |
| 392 | 421 | |
| 393 | 422 | DEVICE_GET_INFO( tm990_189_rs232 ) |
| r9684 | r9685 | |
| 414 | 443 | |
| 415 | 444 | static TMS9902_RST_CALLBACK( rts_callback ) |
| 416 | 445 | { |
| 417 | | rs232_rts = RTS; |
| 446 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 447 | state->rs232_rts = RTS; |
| 418 | 448 | tms9902_set_cts(device, RTS); |
| 419 | 449 | } |
| 420 | 450 | |
| 421 | 451 | static TMS9902_XMIT_CALLBACK( xmit_callback ) |
| 422 | 452 | { |
| 453 | tm990189_state *state = device->machine->driver_data<tm990189_state>(); |
| 423 | 454 | UINT8 buf = data; |
| 424 | 455 | |
| 425 | | if (rs232_fp) |
| 426 | | rs232_fp->fwrite(&buf, 1); |
| 456 | if (state->rs232_fp) |
| 457 | state->rs232_fp->fwrite(&buf, 1); |
| 427 | 458 | } |
| 428 | 459 | |
| 429 | 460 | /* |
| r9684 | r9685 | |
| 432 | 463 | |
| 433 | 464 | static WRITE8_HANDLER(ext_instr_decode) |
| 434 | 465 | { |
| 466 | tm990189_state *state = space->machine->driver_data<tm990189_state>(); |
| 435 | 467 | int ext_op_ID; |
| 436 | 468 | |
| 437 | 469 | ext_op_ID = ((offset+0x800) >> 11) & 0x3; |
| r9684 | r9685 | |
| 446 | 478 | break; |
| 447 | 479 | |
| 448 | 480 | case 5: /* CKON: set DECKCONTROL */ |
| 449 | | LED_state |= 0x20; |
| 481 | state->LED_state |= 0x20; |
| 450 | 482 | { |
| 451 | 483 | running_device *img = space->machine->device("cassette"); |
| 452 | 484 | cassette_change_state(img, CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); |
| r9684 | r9685 | |
| 454 | 486 | break; |
| 455 | 487 | |
| 456 | 488 | case 6: /* CKOF: clear DECKCONTROL */ |
| 457 | | LED_state &= ~0x20; |
| 489 | state->LED_state &= ~0x20; |
| 458 | 490 | { |
| 459 | 491 | running_device *img = space->machine->device("cassette"); |
| 460 | 492 | cassette_change_state(img, CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); |
| r9684 | r9685 | |
| 469 | 501 | |
| 470 | 502 | static void idle_callback(running_device *device, int state) |
| 471 | 503 | { |
| 504 | tm990189_state *drvstate = device->machine->driver_data<tm990189_state>(); |
| 472 | 505 | if (state) |
| 473 | | LED_state |= 0x40; |
| 506 | drvstate->LED_state |= 0x40; |
| 474 | 507 | else |
| 475 | | LED_state &= ~0x40; |
| 508 | drvstate->LED_state &= ~0x40; |
| 476 | 509 | } |
| 477 | 510 | |
| 478 | 511 | /* |
| r9684 | r9685 | |
| 524 | 557 | |
| 525 | 558 | static READ8_HANDLER(video_joy_r) |
| 526 | 559 | { |
| 560 | tm990189_state *state = space->machine->driver_data<tm990189_state>(); |
| 527 | 561 | int reply = input_port_read(space->machine, "BUTTONS"); |
| 528 | 562 | |
| 529 | 563 | |
| 530 | | if (attotime_compare(timer_timeleft(joy1x_timer), attotime_zero) < 0) |
| 564 | if (attotime_compare(timer_timeleft(state->joy1x_timer), attotime_zero) < 0) |
| 531 | 565 | reply |= 0x01; |
| 532 | 566 | |
| 533 | | if (attotime_compare(timer_timeleft(joy1y_timer), attotime_zero) < 0) |
| 567 | if (attotime_compare(timer_timeleft(state->joy1y_timer), attotime_zero) < 0) |
| 534 | 568 | reply |= 0x02; |
| 535 | 569 | |
| 536 | | if (attotime_compare(timer_timeleft(joy2x_timer), attotime_zero) < 0) |
| 570 | if (attotime_compare(timer_timeleft(state->joy2x_timer), attotime_zero) < 0) |
| 537 | 571 | reply |= 0x08; |
| 538 | 572 | |
| 539 | | if (attotime_compare(timer_timeleft(joy2y_timer), attotime_zero) < 0) |
| 573 | if (attotime_compare(timer_timeleft(state->joy2y_timer), attotime_zero) < 0) |
| 540 | 574 | reply |= 0x10; |
| 541 | 575 | |
| 542 | 576 | return reply; |
| r9684 | r9685 | |
| 544 | 578 | |
| 545 | 579 | static WRITE8_HANDLER(video_joy_w) |
| 546 | 580 | { |
| 547 | | timer_reset(joy1x_timer, ATTOTIME_IN_USEC(input_port_read(space->machine, "JOY1_X")*28+28)); |
| 548 | | timer_reset(joy1y_timer, ATTOTIME_IN_USEC(input_port_read(space->machine, "JOY1_Y")*28+28)); |
| 549 | | timer_reset(joy2x_timer, ATTOTIME_IN_USEC(input_port_read(space->machine, "JOY2_X")*28+28)); |
| 550 | | timer_reset(joy2y_timer, ATTOTIME_IN_USEC(input_port_read(space->machine, "JOY2_Y")*28+28)); |
| 581 | tm990189_state *state = space->machine->driver_data<tm990189_state>(); |
| 582 | timer_reset(state->joy1x_timer, ATTOTIME_IN_USEC(input_port_read(space->machine, "JOY1_X")*28+28)); |
| 583 | timer_reset(state->joy1y_timer, ATTOTIME_IN_USEC(input_port_read(space->machine, "JOY1_Y")*28+28)); |
| 584 | timer_reset(state->joy2x_timer, ATTOTIME_IN_USEC(input_port_read(space->machine, "JOY2_X")*28+28)); |
| 585 | timer_reset(state->joy2y_timer, ATTOTIME_IN_USEC(input_port_read(space->machine, "JOY2_Y")*28+28)); |
| 551 | 586 | } |
| 552 | 587 | |
| 553 | 588 | /* user tms9901 setup */ |
| r9684 | r9685 | |
| 754 | 789 | idle_callback |
| 755 | 790 | }; |
| 756 | 791 | |
| 757 | | static MACHINE_CONFIG_START( tm990_189, driver_device ) |
| 792 | static MACHINE_CONFIG_START( tm990_189, tm990189_state ) |
| 758 | 793 | /* basic machine hardware */ |
| 759 | 794 | /* TMS9980 CPU @ 2.0 MHz */ |
| 760 | 795 | MDRV_CPU_ADD("maincpu", TMS9980, 2000000) |
| r9684 | r9685 | |
| 805 | 840 | #define TOP_BORDER_60HZ 27 |
| 806 | 841 | #define BOTTOM_BORDER_60HZ 24 |
| 807 | 842 | |
| 808 | | static MACHINE_CONFIG_START( tm990_189_v, driver_device ) |
| 843 | static MACHINE_CONFIG_START( tm990_189_v, tm990189_state ) |
| 809 | 844 | /* basic machine hardware */ |
| 810 | 845 | /* TMS9980 CPU @ 2.0 MHz */ |
| 811 | 846 | MDRV_CPU_ADD("maincpu", TMS9980, 2000000) |
src/mess/drivers/ssem.c
| r9684 | r9685 | |
| 9 | 9 | #include "devices/cartslot.h" |
| 10 | 10 | #include <stdarg.h> |
| 11 | 11 | |
| 12 | | static UINT8 *store; |
| 13 | | static UINT8 store_line = 0; |
| 14 | 12 | |
| 13 | class ssem_state : public driver_device |
| 14 | { |
| 15 | public: |
| 16 | ssem_state(running_machine &machine, const driver_device_config_base &config) |
| 17 | : driver_device(machine, config) { } |
| 18 | |
| 19 | UINT8 *store; |
| 20 | UINT8 store_line; |
| 21 | }; |
| 22 | |
| 23 | |
| 24 | |
| 15 | 25 | /****************************************************\ |
| 16 | 26 | * General helper functions * |
| 17 | 27 | \****************************************************/ |
| r9684 | r9685 | |
| 42 | 52 | \****************************************************/ |
| 43 | 53 | |
| 44 | 54 | static ADDRESS_MAP_START( ssem_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 45 | | AM_RANGE(0x00, 0x7f) AM_RAM AM_BASE(&store)// Primary store |
| 55 | AM_RANGE(0x00, 0x7f) AM_RAM AM_BASE_MEMBER(ssem_state, store)// Primary store |
| 46 | 56 | ADDRESS_MAP_END |
| 47 | 57 | |
| 48 | 58 | /****************************************************\ |
| r9684 | r9685 | |
| 69 | 79 | |
| 70 | 80 | static INPUT_CHANGED( panel_check ) |
| 71 | 81 | { |
| 82 | ssem_state *state = field->port->machine->driver_data<ssem_state>(); |
| 72 | 83 | UINT8 edit0_state = input_port_read(field->port->machine, "EDIT0"); |
| 73 | 84 | UINT8 edit1_state = input_port_read(field->port->machine, "EDIT1"); |
| 74 | 85 | UINT8 edit2_state = input_port_read(field->port->machine, "EDIT2"); |
| r9684 | r9685 | |
| 79 | 90 | switch( (int)(FPTR)param ) |
| 80 | 91 | { |
| 81 | 92 | case PANEL_BIT0: |
| 82 | | if(edit0_state & 0x01) store[(store_line << 2) | 0] ^= 0x80; |
| 93 | if(edit0_state & 0x01) state->store[(state->store_line << 2) | 0] ^= 0x80; |
| 83 | 94 | break; |
| 84 | 95 | case PANEL_BIT1: |
| 85 | | if(edit0_state & 0x02) store[(store_line << 2) | 0] ^= 0x40; |
| 96 | if(edit0_state & 0x02) state->store[(state->store_line << 2) | 0] ^= 0x40; |
| 86 | 97 | break; |
| 87 | 98 | case PANEL_BIT2: |
| 88 | | if(edit0_state & 0x04) store[(store_line << 2) | 0] ^= 0x20; |
| 99 | if(edit0_state & 0x04) state->store[(state->store_line << 2) | 0] ^= 0x20; |
| 89 | 100 | break; |
| 90 | 101 | case PANEL_BIT3: |
| 91 | | if(edit0_state & 0x08) store[(store_line << 2) | 0] ^= 0x10; |
| 102 | if(edit0_state & 0x08) state->store[(state->store_line << 2) | 0] ^= 0x10; |
| 92 | 103 | break; |
| 93 | 104 | case PANEL_BIT4: |
| 94 | | if(edit0_state & 0x10) store[(store_line << 2) | 0] ^= 0x08; |
| 105 | if(edit0_state & 0x10) state->store[(state->store_line << 2) | 0] ^= 0x08; |
| 95 | 106 | break; |
| 96 | 107 | case PANEL_BIT5: |
| 97 | | if(edit0_state & 0x20) store[(store_line << 2) | 0] ^= 0x04; |
| 108 | if(edit0_state & 0x20) state->store[(state->store_line << 2) | 0] ^= 0x04; |
| 98 | 109 | break; |
| 99 | 110 | case PANEL_BIT6: |
| 100 | | if(edit0_state & 0x40) store[(store_line << 2) | 0] ^= 0x02; |
| 111 | if(edit0_state & 0x40) state->store[(state->store_line << 2) | 0] ^= 0x02; |
| 101 | 112 | break; |
| 102 | 113 | case PANEL_BIT7: |
| 103 | | if(edit0_state & 0x80) store[(store_line << 2) | 0] ^= 0x01; |
| 114 | if(edit0_state & 0x80) state->store[(state->store_line << 2) | 0] ^= 0x01; |
| 104 | 115 | break; |
| 105 | 116 | case PANEL_BIT8: |
| 106 | | if(edit1_state & 0x01) store[(store_line << 2) | 1] ^= 0x80; |
| 117 | if(edit1_state & 0x01) state->store[(state->store_line << 2) | 1] ^= 0x80; |
| 107 | 118 | break; |
| 108 | 119 | case PANEL_BIT9: |
| 109 | | if(edit1_state & 0x02) store[(store_line << 2) | 1] ^= 0x40; |
| 120 | if(edit1_state & 0x02) state->store[(state->store_line << 2) | 1] ^= 0x40; |
| 110 | 121 | break; |
| 111 | 122 | case PANEL_BIT10: |
| 112 | | if(edit1_state & 0x04) store[(store_line << 2) | 1] ^= 0x20; |
| 123 | if(edit1_state & 0x04) state->store[(state->store_line << 2) | 1] ^= 0x20; |
| 113 | 124 | break; |
| 114 | 125 | case PANEL_BIT11: |
| 115 | | if(edit1_state & 0x08) store[(store_line << 2) | 1] ^= 0x10; |
| 126 | if(edit1_state & 0x08) state->store[(state->store_line << 2) | 1] ^= 0x10; |
| 116 | 127 | break; |
| 117 | 128 | case PANEL_BIT12: |
| 118 | | if(edit1_state & 0x10) store[(store_line << 2) | 1] ^= 0x08; |
| 129 | if(edit1_state & 0x10) state->store[(state->store_line << 2) | 1] ^= 0x08; |
| 119 | 130 | break; |
| 120 | 131 | case PANEL_BIT13: |
| 121 | | if(edit1_state & 0x20) store[(store_line << 2) | 1] ^= 0x04; |
| 132 | if(edit1_state & 0x20) state->store[(state->store_line << 2) | 1] ^= 0x04; |
| 122 | 133 | break; |
| 123 | 134 | case PANEL_BIT14: |
| 124 | | if(edit1_state & 0x40) store[(store_line << 2) | 1] ^= 0x02; |
| 135 | if(edit1_state & 0x40) state->store[(state->store_line << 2) | 1] ^= 0x02; |
| 125 | 136 | break; |
| 126 | 137 | case PANEL_BIT15: |
| 127 | | if(edit1_state & 0x80) store[(store_line << 2) | 1] ^= 0x01; |
| 138 | if(edit1_state & 0x80) state->store[(state->store_line << 2) | 1] ^= 0x01; |
| 128 | 139 | break; |
| 129 | 140 | case PANEL_BIT16: |
| 130 | | if(edit2_state & 0x01) store[(store_line << 2) | 2] ^= 0x80; |
| 141 | if(edit2_state & 0x01) state->store[(state->store_line << 2) | 2] ^= 0x80; |
| 131 | 142 | break; |
| 132 | 143 | case PANEL_BIT17: |
| 133 | | if(edit2_state & 0x02) store[(store_line << 2) | 2] ^= 0x40; |
| 144 | if(edit2_state & 0x02) state->store[(state->store_line << 2) | 2] ^= 0x40; |
| 134 | 145 | break; |
| 135 | 146 | case PANEL_BIT18: |
| 136 | | if(edit2_state & 0x04) store[(store_line << 2) | 2] ^= 0x20; |
| 147 | if(edit2_state & 0x04) state->store[(state->store_line << 2) | 2] ^= 0x20; |
| 137 | 148 | break; |
| 138 | 149 | case PANEL_BIT19: |
| 139 | | if(edit2_state & 0x08) store[(store_line << 2) | 2] ^= 0x10; |
| 150 | if(edit2_state & 0x08) state->store[(state->store_line << 2) | 2] ^= 0x10; |
| 140 | 151 | break; |
| 141 | 152 | case PANEL_BIT20: |
| 142 | | if(edit2_state & 0x10) store[(store_line << 2) | 2] ^= 0x08; |
| 153 | if(edit2_state & 0x10) state->store[(state->store_line << 2) | 2] ^= 0x08; |
| 143 | 154 | break; |
| 144 | 155 | case PANEL_BIT21: |
| 145 | | if(edit2_state & 0x20) store[(store_line << 2) | 2] ^= 0x04; |
| 156 | if(edit2_state & 0x20) state->store[(state->store_line << 2) | 2] ^= 0x04; |
| 146 | 157 | break; |
| 147 | 158 | case PANEL_BIT22: |
| 148 | | if(edit2_state & 0x40) store[(store_line << 2) | 2] ^= 0x02; |
| 159 | if(edit2_state & 0x40) state->store[(state->store_line << 2) | 2] ^= 0x02; |
| 149 | 160 | break; |
| 150 | 161 | case PANEL_BIT23: |
| 151 | | if(edit2_state & 0x80) store[(store_line << 2) | 2] ^= 0x01; |
| 162 | if(edit2_state & 0x80) state->store[(state->store_line << 2) | 2] ^= 0x01; |
| 152 | 163 | break; |
| 153 | 164 | case PANEL_BIT24: |
| 154 | | if(edit3_state & 0x01) store[(store_line << 2) | 3] ^= 0x80; |
| 165 | if(edit3_state & 0x01) state->store[(state->store_line << 2) | 3] ^= 0x80; |
| 155 | 166 | break; |
| 156 | 167 | case PANEL_BIT25: |
| 157 | | if(edit3_state & 0x02) store[(store_line << 2) | 3] ^= 0x40; |
| 168 | if(edit3_state & 0x02) state->store[(state->store_line << 2) | 3] ^= 0x40; |
| 158 | 169 | break; |
| 159 | 170 | case PANEL_BIT26: |
| 160 | | if(edit3_state & 0x04) store[(store_line << 2) | 3] ^= 0x20; |
| 171 | if(edit3_state & 0x04) state->store[(state->store_line << 2) | 3] ^= 0x20; |
| 161 | 172 | break; |
| 162 | 173 | case PANEL_BIT27: |
| 163 | | if(edit3_state & 0x08) store[(store_line << 2) | 3] ^= 0x10; |
| 174 | if(edit3_state & 0x08) state->store[(state->store_line << 2) | 3] ^= 0x10; |
| 164 | 175 | break; |
| 165 | 176 | case PANEL_BIT28: |
| 166 | | if(edit3_state & 0x10) store[(store_line << 2) | 3] ^= 0x08; |
| 177 | if(edit3_state & 0x10) state->store[(state->store_line << 2) | 3] ^= 0x08; |
| 167 | 178 | break; |
| 168 | 179 | case PANEL_BIT29: |
| 169 | | if(edit3_state & 0x20) store[(store_line << 2) | 3] ^= 0x04; |
| 180 | if(edit3_state & 0x20) state->store[(state->store_line << 2) | 3] ^= 0x04; |
| 170 | 181 | break; |
| 171 | 182 | case PANEL_BIT30: |
| 172 | | if(edit3_state & 0x40) store[(store_line << 2) | 3] ^= 0x02; |
| 183 | if(edit3_state & 0x40) state->store[(state->store_line << 2) | 3] ^= 0x02; |
| 173 | 184 | break; |
| 174 | 185 | case PANEL_BIT31: |
| 175 | | if(edit3_state & 0x80) store[(store_line << 2) | 3] ^= 0x01; |
| 186 | if(edit3_state & 0x80) state->store[(state->store_line << 2) | 3] ^= 0x01; |
| 176 | 187 | break; |
| 177 | 188 | case PANEL_LNUP: |
| 178 | 189 | if(misc_state & 0x01) |
| 179 | 190 | { |
| 180 | | store_line--; |
| 191 | state->store_line--; |
| 181 | 192 | } |
| 182 | 193 | break; |
| 183 | 194 | case PANEL_LNDN: |
| 184 | 195 | if(misc_state & 0x02) |
| 185 | 196 | { |
| 186 | | store_line++; |
| 197 | state->store_line++; |
| 187 | 198 | } |
| 188 | 199 | break; |
| 189 | 200 | case PANEL_HALT: |
| r9684 | r9685 | |
| 430 | 441 | |
| 431 | 442 | static VIDEO_UPDATE( ssem ) |
| 432 | 443 | { |
| 444 | ssem_state *state = screen->machine->driver_data<ssem_state>(); |
| 433 | 445 | UINT32 line = 0; |
| 434 | 446 | running_device *ssem_cpu = screen->machine->device("maincpu"); |
| 435 | 447 | UINT32 accum = cpu_get_reg(ssem_cpu, SSEM_A); |
| r9684 | r9685 | |
| 438 | 450 | |
| 439 | 451 | for(line = 0; line < 32; line++) |
| 440 | 452 | { |
| 441 | | word = (store[(line << 2) | 0] << 24) | |
| 442 | | (store[(line << 2) | 1] << 16) | |
| 443 | | (store[(line << 2) | 2] << 8) | |
| 444 | | (store[(line << 2) | 3] << 0); |
| 453 | word = (state->store[(line << 2) | 0] << 24) | |
| 454 | (state->store[(line << 2) | 1] << 16) | |
| 455 | (state->store[(line << 2) | 2] << 8) | |
| 456 | (state->store[(line << 2) | 3] << 0); |
| 445 | 457 | for(bit = 0; bit < 32; bit++) |
| 446 | 458 | { |
| 447 | 459 | if(word & (1 << (31 - bit))) |
| 448 | 460 | { |
| 449 | | glyph_print(screen->machine, bitmap, bit << 3, line << 3, "%c", line == store_line ? 4 : 2); |
| 461 | glyph_print(screen->machine, bitmap, bit << 3, line << 3, "%c", line == state->store_line ? 4 : 2); |
| 450 | 462 | } |
| 451 | 463 | else |
| 452 | 464 | { |
| 453 | | glyph_print(screen->machine, bitmap, bit << 3, line << 3, "%c", line == store_line ? 3 : 1); |
| 465 | glyph_print(screen->machine, bitmap, bit << 3, line << 3, "%c", line == state->store_line ? 3 : 1); |
| 454 | 466 | } |
| 455 | 467 | } |
| 456 | 468 | } |
| r9684 | r9685 | |
| 467 | 479 | } |
| 468 | 480 | } |
| 469 | 481 | |
| 470 | | word = reverse((store[(store_line << 2) | 0] << 24) | |
| 471 | | (store[(store_line << 2) | 1] << 16) | |
| 472 | | (store[(store_line << 2) | 2] << 8) | |
| 473 | | (store[(store_line << 2) | 3] << 0)); |
| 474 | | glyph_print(screen->machine, bitmap, 0, 272, "LINE:%02d VALUE:%08x HALT:%d", store_line, word, cpu_get_reg(ssem_cpu, SSEM_HALT)); |
| 482 | word = reverse((state->store[(state->store_line << 2) | 0] << 24) | |
| 483 | (state->store[(state->store_line << 2) | 1] << 16) | |
| 484 | (state->store[(state->store_line << 2) | 2] << 8) | |
| 485 | (state->store[(state->store_line << 2) | 3] << 0)); |
| 486 | glyph_print(screen->machine, bitmap, 0, 272, "LINE:%02d VALUE:%08x HALT:%d", state->store_line, word, cpu_get_reg(ssem_cpu, SSEM_HALT)); |
| 475 | 487 | return 0; |
| 476 | 488 | } |
| 477 | 489 | |
| r9684 | r9685 | |
| 500 | 512 | |
| 501 | 513 | static DEVICE_IMAGE_LOAD(ssem_store) |
| 502 | 514 | { |
| 515 | ssem_state *state = image.device().machine->driver_data<ssem_state>(); |
| 503 | 516 | const char* image_name = image.filename(); |
| 504 | 517 | char image_ext[5] = { 0 }; |
| 505 | 518 | char image_line[100] = { 0 }; |
| r9684 | r9685 | |
| 540 | 553 | } |
| 541 | 554 | } |
| 542 | 555 | |
| 543 | | store[(line << 2) + 0] = (word >> 24) & 0x000000ff; |
| 544 | | store[(line << 2) + 1] = (word >> 16) & 0x000000ff; |
| 545 | | store[(line << 2) + 2] = (word >> 8) & 0x000000ff; |
| 546 | | store[(line << 2) + 3] = (word >> 0) & 0x000000ff; |
| 556 | state->store[(line << 2) + 0] = (word >> 24) & 0x000000ff; |
| 557 | state->store[(line << 2) + 1] = (word >> 16) & 0x000000ff; |
| 558 | state->store[(line << 2) + 2] = (word >> 8) & 0x000000ff; |
| 559 | state->store[(line << 2) + 3] = (word >> 0) & 0x000000ff; |
| 547 | 560 | } |
| 548 | 561 | else if(strcmp(image_ext, ".asm") == 0) |
| 549 | 562 | { |
| r9684 | r9685 | |
| 594 | 607 | word = 0x00070000 | unsigned_value; |
| 595 | 608 | } |
| 596 | 609 | |
| 597 | | store[(line << 2) + 0] = (word >> 24) & 0x000000ff; |
| 598 | | store[(line << 2) + 1] = (word >> 16) & 0x000000ff; |
| 599 | | store[(line << 2) + 2] = (word >> 8) & 0x000000ff; |
| 600 | | store[(line << 2) + 3] = (word >> 0) & 0x000000ff; |
| 610 | state->store[(line << 2) + 0] = (word >> 24) & 0x000000ff; |
| 611 | state->store[(line << 2) + 1] = (word >> 16) & 0x000000ff; |
| 612 | state->store[(line << 2) + 2] = (word >> 8) & 0x000000ff; |
| 613 | state->store[(line << 2) + 3] = (word >> 0) & 0x000000ff; |
| 601 | 614 | } |
| 602 | 615 | } |
| 603 | 616 | } |
| r9684 | r9685 | |
| 611 | 624 | |
| 612 | 625 | static MACHINE_RESET( ssem ) |
| 613 | 626 | { |
| 614 | | store_line = 0; |
| 627 | ssem_state *state = machine->driver_data<ssem_state>(); |
| 628 | state->store_line = 0; |
| 615 | 629 | } |
| 616 | 630 | |
| 617 | | static MACHINE_CONFIG_START( ssem, driver_device ) |
| 631 | static MACHINE_CONFIG_START( ssem, ssem_state ) |
| 618 | 632 | /* basic machine hardware */ |
| 619 | 633 | MDRV_CPU_ADD("maincpu", SSEM, 700) |
| 620 | 634 | MDRV_CPU_PROGRAM_MAP(ssem_map) |
src/mess/drivers/pockstat.c
| r9684 | r9685 | |
| 34 | 34 | #include "devices/cartslot.h" |
| 35 | 35 | #include "sound/dac.h" |
| 36 | 36 | |
| 37 | #define MAX_PS_TIMERS 3 |
| 38 | |
| 39 | typedef struct |
| 40 | { |
| 41 | UINT32 control; |
| 42 | UINT32 stat; |
| 43 | UINT32 valid; |
| 44 | UINT32 wait1; |
| 45 | UINT32 wait2; |
| 46 | UINT32 entry[16]; |
| 47 | UINT32 serial; |
| 48 | } ps_ftlb_regs_t; |
| 49 | |
| 50 | typedef struct |
| 51 | { |
| 52 | UINT32 hold; |
| 53 | UINT32 status; |
| 54 | UINT32 enable; |
| 55 | UINT32 mask; |
| 56 | } ps_intc_regs_t; |
| 57 | |
| 58 | typedef struct |
| 59 | { |
| 60 | UINT32 period; |
| 61 | UINT32 count; |
| 62 | UINT32 control; |
| 63 | emu_timer *timer; |
| 64 | } ps_timer_t; |
| 65 | |
| 66 | typedef struct |
| 67 | { |
| 68 | ps_timer_t timer[MAX_PS_TIMERS]; |
| 69 | } ps_timer_regs_t; |
| 70 | |
| 71 | typedef struct |
| 72 | { |
| 73 | UINT32 mode; |
| 74 | UINT32 control; |
| 75 | } ps_clock_regs_t; |
| 76 | |
| 77 | #define PS_CLOCK_STEADY 0x10 |
| 78 | |
| 79 | typedef struct |
| 80 | { |
| 81 | UINT32 mode; |
| 82 | UINT32 control; |
| 83 | UINT32 time; |
| 84 | UINT32 date; |
| 85 | emu_timer *timer; |
| 86 | } ps_rtc_regs_t; |
| 87 | |
| 88 | |
| 89 | |
| 90 | class pockstat_state : public driver_device |
| 91 | { |
| 92 | public: |
| 93 | pockstat_state(running_machine &machine, const driver_device_config_base &config) |
| 94 | : driver_device(machine, config) { } |
| 95 | |
| 96 | UINT32 *lcd_buffer; |
| 97 | ps_ftlb_regs_t ftlb_regs; |
| 98 | ps_intc_regs_t intc_regs; |
| 99 | ps_timer_regs_t timer_regs; |
| 100 | ps_clock_regs_t clock_regs; |
| 101 | ps_rtc_regs_t rtc_regs; |
| 102 | UINT32 lcd_control; |
| 103 | INT32 ps_flash_write_enable_count; |
| 104 | INT32 ps_flash_write_count; |
| 105 | }; |
| 106 | |
| 107 | |
| 37 | 108 | #define DEFAULT_CLOCK 2000000 |
| 38 | 109 | |
| 39 | 110 | static const int CPU_FREQ[16] = |
| r9684 | r9685 | |
| 77 | 148 | #define verboselog(x,y,z,...) |
| 78 | 149 | #endif |
| 79 | 150 | |
| 80 | | static UINT32 *lcd_buffer; |
| 81 | 151 | |
| 82 | 152 | // Flash TLB |
| 83 | 153 | static READ32_HANDLER( ps_ftlb_r ); |
| r9684 | r9685 | |
| 104 | 174 | static READ32_HANDLER( ps_rtc_r ); |
| 105 | 175 | static WRITE32_HANDLER( ps_rtc_w ); |
| 106 | 176 | |
| 107 | | typedef struct |
| 108 | | { |
| 109 | | UINT32 control; |
| 110 | | UINT32 stat; |
| 111 | | UINT32 valid; |
| 112 | | UINT32 wait1; |
| 113 | | UINT32 wait2; |
| 114 | | UINT32 entry[16]; |
| 115 | | UINT32 serial; |
| 116 | | } ps_ftlb_regs_t; |
| 117 | | |
| 118 | | typedef struct |
| 119 | | { |
| 120 | | UINT32 hold; |
| 121 | | UINT32 status; |
| 122 | | UINT32 enable; |
| 123 | | UINT32 mask; |
| 124 | | } ps_intc_regs_t; |
| 125 | | |
| 126 | 177 | #define PS_INT_BTN_ACTION 0x00000001 // "Action button" |
| 127 | 178 | #define PS_INT_BTN_RIGHT 0x00000002 // "Right button" |
| 128 | 179 | #define PS_INT_BTN_LEFT 0x00000004 // "Left button" |
| r9684 | r9685 | |
| 141 | 192 | #define PS_INT_FIQ_MASK 0x00002040 |
| 142 | 193 | #define PS_INT_STATUS_MASK 0x0000021f |
| 143 | 194 | |
| 144 | | #define MAX_PS_TIMERS 3 |
| 145 | | |
| 146 | | typedef struct |
| 147 | | { |
| 148 | | UINT32 period; |
| 149 | | UINT32 count; |
| 150 | | UINT32 control; |
| 151 | | emu_timer *timer; |
| 152 | | } ps_timer_t; |
| 153 | | |
| 154 | | typedef struct |
| 155 | | { |
| 156 | | ps_timer_t timer[MAX_PS_TIMERS]; |
| 157 | | } ps_timer_regs_t; |
| 158 | | |
| 159 | | typedef struct |
| 160 | | { |
| 161 | | UINT32 mode; |
| 162 | | UINT32 control; |
| 163 | | } ps_clock_regs_t; |
| 164 | | |
| 165 | | #define PS_CLOCK_STEADY 0x10 |
| 166 | | |
| 167 | | typedef struct |
| 168 | | { |
| 169 | | UINT32 mode; |
| 170 | | UINT32 control; |
| 171 | | UINT32 time; |
| 172 | | UINT32 date; |
| 173 | | emu_timer *timer; |
| 174 | | } ps_rtc_regs_t; |
| 175 | | |
| 176 | | static ps_ftlb_regs_t ftlb_regs; |
| 177 | | static ps_intc_regs_t intc_regs; |
| 178 | | static ps_timer_regs_t timer_regs; |
| 179 | | static ps_clock_regs_t clock_regs; |
| 180 | | static ps_rtc_regs_t rtc_regs; |
| 181 | | |
| 182 | 195 | static READ32_HANDLER( ps_ftlb_r ) |
| 183 | 196 | { |
| 197 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 184 | 198 | switch(offset) |
| 185 | 199 | { |
| 186 | 200 | case 0x0000/4: |
| 187 | | verboselog(space->machine, 0, "ps_ftlb_r: FlashROM TLB Control = %08x & %08x\n", ftlb_regs.control, mem_mask ); |
| 188 | | return ftlb_regs.control | 1; // ??? |
| 201 | verboselog(space->machine, 0, "ps_ftlb_r: FlashROM TLB Control = %08x & %08x\n", state->ftlb_regs.control, mem_mask ); |
| 202 | return state->ftlb_regs.control | 1; // ??? |
| 189 | 203 | case 0x0004/4: |
| 190 | | verboselog(space->machine, 0, "ps_ftlb_r: Unknown (F_STAT) = %08x & %08x\n", ftlb_regs.stat, mem_mask ); |
| 191 | | return ftlb_regs.stat; |
| 204 | verboselog(space->machine, 0, "ps_ftlb_r: Unknown (F_STAT) = %08x & %08x\n", state->ftlb_regs.stat, mem_mask ); |
| 205 | return state->ftlb_regs.stat; |
| 192 | 206 | case 0x0008/4: |
| 193 | | verboselog(space->machine, 0, "ps_ftlb_r: FlashROM TLB Valid Tag = %08x & %08x\n", ftlb_regs.valid, mem_mask ); |
| 194 | | return ftlb_regs.valid; |
| 207 | verboselog(space->machine, 0, "ps_ftlb_r: FlashROM TLB Valid Tag = %08x & %08x\n", state->ftlb_regs.valid, mem_mask ); |
| 208 | return state->ftlb_regs.valid; |
| 195 | 209 | case 0x000c/4: |
| 196 | | verboselog(space->machine, 0, "ps_ftlb_r: Unknown (F_WAIT1) = %08x & %08x\n", ftlb_regs.wait1, mem_mask ); |
| 197 | | return ftlb_regs.wait1; |
| 210 | verboselog(space->machine, 0, "ps_ftlb_r: Unknown (F_WAIT1) = %08x & %08x\n", state->ftlb_regs.wait1, mem_mask ); |
| 211 | return state->ftlb_regs.wait1; |
| 198 | 212 | case 0x0010/4: |
| 199 | | verboselog(space->machine, 0, "ps_ftlb_r: Unknown (F_WAIT2) = %08x & %08x\n", ftlb_regs.wait2 | 0x04, mem_mask ); |
| 200 | | return ftlb_regs.wait2 | 0x04; |
| 213 | verboselog(space->machine, 0, "ps_ftlb_r: Unknown (F_WAIT2) = %08x & %08x\n", state->ftlb_regs.wait2 | 0x04, mem_mask ); |
| 214 | return state->ftlb_regs.wait2 | 0x04; |
| 201 | 215 | case 0x0100/4: |
| 202 | 216 | case 0x0104/4: |
| 203 | 217 | case 0x0108/4: |
| r9684 | r9685 | |
| 214 | 228 | case 0x0134/4: |
| 215 | 229 | case 0x0138/4: |
| 216 | 230 | case 0x013c/4: |
| 217 | | verboselog(space->machine, 0, "ps_ftlb_r: FlashROM TLB Entry %d = %08x & %08x\n", offset - 0x100/4, ftlb_regs.entry[offset - 0x100/4], mem_mask ); |
| 218 | | return ftlb_regs.entry[offset - 0x100/4]; |
| 231 | verboselog(space->machine, 0, "ps_ftlb_r: FlashROM TLB Entry %d = %08x & %08x\n", offset - 0x100/4, state->ftlb_regs.entry[offset - 0x100/4], mem_mask ); |
| 232 | return state->ftlb_regs.entry[offset - 0x100/4]; |
| 219 | 233 | case 0x0300/4: |
| 220 | | verboselog(space->machine, 0, "ps_ftlb_r: Unknown (F_SN) = %08x & %08x\n", ftlb_regs.serial, mem_mask ); |
| 221 | | return ftlb_regs.serial; |
| 234 | verboselog(space->machine, 0, "ps_ftlb_r: Unknown (F_SN) = %08x & %08x\n", state->ftlb_regs.serial, mem_mask ); |
| 235 | return state->ftlb_regs.serial; |
| 222 | 236 | default: |
| 223 | 237 | verboselog(space->machine, 0, "ps_ftlb_r: Unknown Register %08x & %08x\n", 0x06000000 + (offset << 2), mem_mask ); |
| 224 | 238 | break; |
| r9684 | r9685 | |
| 228 | 242 | |
| 229 | 243 | static WRITE32_HANDLER( ps_ftlb_w ) |
| 230 | 244 | { |
| 245 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 231 | 246 | switch(offset) |
| 232 | 247 | { |
| 233 | 248 | case 0x0000/4: |
| 234 | 249 | verboselog(space->machine, 0, "ps_ftlb_w: FlashROM TLB Control = %08x & %08x\n", data, mem_mask ); |
| 235 | | COMBINE_DATA(&ftlb_regs.control); |
| 250 | COMBINE_DATA(&state->ftlb_regs.control); |
| 236 | 251 | break; |
| 237 | 252 | case 0x0004/4: |
| 238 | 253 | verboselog(space->machine, 0, "ps_ftlb_w: Unknown (F_STAT) = %08x & %08x\n", data, mem_mask ); |
| 239 | | COMBINE_DATA(&ftlb_regs.stat); |
| 254 | COMBINE_DATA(&state->ftlb_regs.stat); |
| 240 | 255 | break; |
| 241 | 256 | case 0x0008/4: |
| 242 | 257 | verboselog(space->machine, 0, "ps_ftlb_w: FlashROM TLB Valid Tag = %08x & %08x\n", data, mem_mask ); |
| 243 | | COMBINE_DATA(&ftlb_regs.valid); |
| 258 | COMBINE_DATA(&state->ftlb_regs.valid); |
| 244 | 259 | break; |
| 245 | 260 | case 0x000c/4: |
| 246 | 261 | verboselog(space->machine, 0, "ps_ftlb_w: Unknown (F_WAIT1) = %08x & %08x\n", data, mem_mask ); |
| 247 | | COMBINE_DATA(&ftlb_regs.wait1); |
| 262 | COMBINE_DATA(&state->ftlb_regs.wait1); |
| 248 | 263 | break; |
| 249 | 264 | case 0x0010/4: |
| 250 | 265 | verboselog(space->machine, 0, "ps_ftlb_w: Unknown (F_WAIT2) = %08x & %08x\n", data, mem_mask ); |
| 251 | | COMBINE_DATA(&ftlb_regs.wait2); |
| 266 | COMBINE_DATA(&state->ftlb_regs.wait2); |
| 252 | 267 | break; |
| 253 | 268 | case 0x0100/4: |
| 254 | 269 | case 0x0104/4: |
| r9684 | r9685 | |
| 267 | 282 | case 0x0138/4: |
| 268 | 283 | case 0x013c/4: |
| 269 | 284 | verboselog(space->machine, 0, "ps_ftlb_w: FlashROM TLB Entry %d = %08x & %08x\n", offset - 0x100/4, data, mem_mask ); |
| 270 | | COMBINE_DATA(&ftlb_regs.entry[offset - 0x100/4]); |
| 285 | COMBINE_DATA(&state->ftlb_regs.entry[offset - 0x100/4]); |
| 271 | 286 | break; |
| 272 | 287 | case 0x0300/4: |
| 273 | 288 | verboselog(space->machine, 0, "ps_ftlb_w: Unknown (F_SN) = %08x & %08x\n", data, mem_mask ); |
| 274 | | COMBINE_DATA(&ftlb_regs.serial); |
| 289 | COMBINE_DATA(&state->ftlb_regs.serial); |
| 275 | 290 | break; |
| 276 | 291 | default: |
| 277 | 292 | verboselog(space->machine, 0, "ps_ftlb_w: Unknown Register %08x = %08x & %08x\n", 0x06000000 + (offset << 2), data, mem_mask ); |
| r9684 | r9685 | |
| 281 | 296 | |
| 282 | 297 | static UINT32 ps_intc_get_interrupt_line(running_machine *machine, UINT32 line) |
| 283 | 298 | { |
| 284 | | return intc_regs.status & line; |
| 299 | pockstat_state *state = machine->driver_data<pockstat_state>(); |
| 300 | return state->intc_regs.status & line; |
| 285 | 301 | } |
| 286 | 302 | |
| 287 | 303 | static void ps_intc_set_interrupt_line(running_machine *machine, UINT32 line, int state) |
| 288 | 304 | { |
| 289 | | //printf( "%08x %d %08x %08x %08x\n", line, state, intc_regs.hold, intc_regs.status, intc_regs.enable ); |
| 305 | pockstat_state *drvstate = machine->driver_data<pockstat_state>(); |
| 306 | //printf( "%08x %d %08x %08x %08x\n", line, state, drvstate->intc_regs.hold, drvstate->intc_regs.status, drvstate->intc_regs.enable ); |
| 290 | 307 | if(line) |
| 291 | 308 | { |
| 292 | 309 | if(state) |
| 293 | 310 | { |
| 294 | | intc_regs.status |= line & PS_INT_STATUS_MASK; |
| 295 | | intc_regs.hold |= line &~ PS_INT_STATUS_MASK; |
| 296 | | //printf( " Setting %08x, status = %08x, hold = %08x\n", line, intc_regs.status, intc_regs.hold ); |
| 311 | drvstate->intc_regs.status |= line & PS_INT_STATUS_MASK; |
| 312 | drvstate->intc_regs.hold |= line &~ PS_INT_STATUS_MASK; |
| 313 | //printf( " Setting %08x, status = %08x, hold = %08x\n", line, drvstate->intc_regs.status, drvstate->intc_regs.hold ); |
| 297 | 314 | } |
| 298 | 315 | else |
| 299 | 316 | { |
| 300 | | intc_regs.status &= ~line; |
| 301 | | intc_regs.hold &= ~line; |
| 302 | | //printf( "Clearing %08x, status = %08x, hold = %08x\n", line, intc_regs.status, intc_regs.hold ); |
| 317 | drvstate->intc_regs.status &= ~line; |
| 318 | drvstate->intc_regs.hold &= ~line; |
| 319 | //printf( "Clearing %08x, status = %08x, hold = %08x\n", line, drvstate->intc_regs.status, drvstate->intc_regs.hold ); |
| 303 | 320 | } |
| 304 | 321 | } |
| 305 | | if(intc_regs.hold & intc_regs.enable & PS_INT_IRQ_MASK) |
| 322 | if(drvstate->intc_regs.hold & drvstate->intc_regs.enable & PS_INT_IRQ_MASK) |
| 306 | 323 | { |
| 307 | 324 | cpu_set_input_line(machine->device("maincpu"), ARM7_IRQ_LINE, ASSERT_LINE); |
| 308 | 325 | } |
| r9684 | r9685 | |
| 310 | 327 | { |
| 311 | 328 | cpu_set_input_line(machine->device("maincpu"), ARM7_IRQ_LINE, CLEAR_LINE); |
| 312 | 329 | } |
| 313 | | if(intc_regs.hold & intc_regs.enable & PS_INT_FIQ_MASK) |
| 330 | if(drvstate->intc_regs.hold & drvstate->intc_regs.enable & PS_INT_FIQ_MASK) |
| 314 | 331 | { |
| 315 | 332 | cpu_set_input_line(machine->device("maincpu"), ARM7_FIRQ_LINE, ASSERT_LINE); |
| 316 | 333 | } |
| r9684 | r9685 | |
| 322 | 339 | |
| 323 | 340 | static READ32_HANDLER( ps_intc_r ) |
| 324 | 341 | { |
| 342 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 325 | 343 | switch(offset) |
| 326 | 344 | { |
| 327 | 345 | case 0x0000/4: |
| 328 | | verboselog(space->machine, 0, "ps_intc_r: Held Interrupt = %08x & %08x\n", intc_regs.hold, mem_mask ); |
| 329 | | return intc_regs.hold; |
| 346 | verboselog(space->machine, 0, "ps_intc_r: Held Interrupt = %08x & %08x\n", state->intc_regs.hold, mem_mask ); |
| 347 | return state->intc_regs.hold; |
| 330 | 348 | case 0x0004/4: |
| 331 | | verboselog(space->machine, 0, "ps_intc_r: Interrupt Status = %08x & %08x\n", intc_regs.status, mem_mask ); |
| 332 | | return intc_regs.status; |
| 349 | verboselog(space->machine, 0, "ps_intc_r: Interrupt Status = %08x & %08x\n", state->intc_regs.status, mem_mask ); |
| 350 | return state->intc_regs.status; |
| 333 | 351 | case 0x0008/4: |
| 334 | | verboselog(space->machine, 0, "ps_intc_r: Interrupt Enable = %08x & %08x\n", intc_regs.enable, mem_mask ); |
| 335 | | return intc_regs.enable; |
| 352 | verboselog(space->machine, 0, "ps_intc_r: Interrupt Enable = %08x & %08x\n", state->intc_regs.enable, mem_mask ); |
| 353 | return state->intc_regs.enable; |
| 336 | 354 | case 0x000c/4: |
| 337 | 355 | verboselog(space->machine, 0, "ps_intc_r: Interrupt Mask (Invalid Read) = %08x & %08x\n", 0, mem_mask ); |
| 338 | 356 | return 0; |
| r9684 | r9685 | |
| 348 | 366 | |
| 349 | 367 | static WRITE32_HANDLER( ps_intc_w ) |
| 350 | 368 | { |
| 369 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 351 | 370 | switch(offset) |
| 352 | 371 | { |
| 353 | 372 | case 0x0000/4: |
| r9684 | r9685 | |
| 358 | 377 | break; |
| 359 | 378 | case 0x0008/4: |
| 360 | 379 | verboselog(space->machine, 0, "ps_intc_w: Interrupt Enable = %08x & %08x\n", data, mem_mask ); |
| 361 | | intc_regs.enable |= data; |
| 362 | | //COMBINE_DATA(&intc_regs.enable); |
| 363 | | //intc_regs.status &= intc_regs.enable; |
| 364 | | //intc_regs.hold &= intc_regs.enable; |
| 380 | state->intc_regs.enable |= data; |
| 381 | //COMBINE_DATA(&state->intc_regs.enable); |
| 382 | //state->intc_regs.status &= state->intc_regs.enable; |
| 383 | //state->intc_regs.hold &= state->intc_regs.enable; |
| 365 | 384 | ps_intc_set_interrupt_line(space->machine, 0, 0); |
| 366 | 385 | break; |
| 367 | 386 | case 0x000c/4: |
| 368 | 387 | verboselog(space->machine, 0, "ps_intc_w: Interrupt Mask = %08x & %08x\n", data, mem_mask ); |
| 369 | | intc_regs.enable &= ~data; |
| 370 | | COMBINE_DATA(&intc_regs.mask); |
| 371 | | //intc_regs.status &= intc_regs.enable; |
| 372 | | //intc_regs.hold &= intc_regs.enable; |
| 388 | state->intc_regs.enable &= ~data; |
| 389 | COMBINE_DATA(&state->intc_regs.mask); |
| 390 | //state->intc_regs.status &= state->intc_regs.enable; |
| 391 | //state->intc_regs.hold &= state->intc_regs.enable; |
| 373 | 392 | ps_intc_set_interrupt_line(space->machine, 0, 0); |
| 374 | 393 | break; |
| 375 | 394 | case 0x0010/4: |
| 376 | 395 | verboselog(space->machine, 0, "ps_intc_w: Interrupt Acknowledge = %08x & %08x\n", data, mem_mask ); |
| 377 | | intc_regs.hold &= ~data; |
| 378 | | intc_regs.status &= ~data; |
| 396 | state->intc_regs.hold &= ~data; |
| 397 | state->intc_regs.status &= ~data; |
| 379 | 398 | ps_intc_set_interrupt_line(space->machine, 0, 0); |
| 380 | | //COMBINE_DATA(&intc_regs.acknowledge); |
| 399 | //COMBINE_DATA(&state->intc_regs.acknowledge); |
| 381 | 400 | break; |
| 382 | 401 | default: |
| 383 | 402 | verboselog(space->machine, 0, "ps_intc_w: Unknown Register %08x = %08x & %08x\n", 0x0a000000 + (offset << 2), data, mem_mask ); |
| r9684 | r9685 | |
| 387 | 406 | |
| 388 | 407 | static TIMER_CALLBACK( timer_tick ) |
| 389 | 408 | { |
| 409 | pockstat_state *state = machine->driver_data<pockstat_state>(); |
| 390 | 410 | ps_intc_set_interrupt_line(machine, param == 2 ? PS_INT_TIMER2 : (param == 1 ? PS_INT_TIMER1 : PS_INT_TIMER0), 1); |
| 391 | 411 | //printf( "Timer %d is calling back\n", param ); |
| 392 | | timer_regs.timer[param].count = timer_regs.timer[param].period; |
| 412 | state->timer_regs.timer[param].count = state->timer_regs.timer[param].period; |
| 393 | 413 | ps_timer_start(machine, param); |
| 394 | 414 | } |
| 395 | 415 | |
| 396 | 416 | static void ps_timer_start(running_machine *machine, int index) |
| 397 | 417 | { |
| 418 | pockstat_state *state = machine->driver_data<pockstat_state>(); |
| 398 | 419 | int divisor = 1; |
| 399 | 420 | attotime period; |
| 400 | | switch(timer_regs.timer[index].control & 3) |
| 421 | switch(state->timer_regs.timer[index].control & 3) |
| 401 | 422 | { |
| 402 | 423 | case 0: |
| 403 | 424 | case 3: |
| r9684 | r9685 | |
| 410 | 431 | divisor = 256; |
| 411 | 432 | break; |
| 412 | 433 | } |
| 413 | | period = attotime_mul(ATTOTIME_IN_HZ(CPU_FREQ[clock_regs.mode & 0x0f] / 2), divisor); |
| 414 | | period = attotime_mul(period, timer_regs.timer[index].count); |
| 415 | | timer_adjust_oneshot(timer_regs.timer[index].timer, period, index); |
| 434 | period = attotime_mul(ATTOTIME_IN_HZ(CPU_FREQ[state->clock_regs.mode & 0x0f] / 2), divisor); |
| 435 | period = attotime_mul(period, state->timer_regs.timer[index].count); |
| 436 | timer_adjust_oneshot(state->timer_regs.timer[index].timer, period, index); |
| 416 | 437 | } |
| 417 | 438 | |
| 418 | 439 | static READ32_HANDLER( ps_timer_r ) |
| 419 | 440 | { |
| 441 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 420 | 442 | switch(offset) |
| 421 | 443 | { |
| 422 | 444 | case 0x0000/4: |
| 423 | 445 | case 0x0010/4: |
| 424 | 446 | case 0x0020/4: |
| 425 | | verboselog(space->machine, 0, "ps_timer_r: Timer %d Period = %08x & %08x\n", offset / (0x10/4), timer_regs.timer[offset / (0x10/4)].period, mem_mask ); |
| 426 | | return timer_regs.timer[offset / (0x10/4)].period; |
| 447 | verboselog(space->machine, 0, "ps_timer_r: Timer %d Period = %08x & %08x\n", offset / (0x10/4), state->timer_regs.timer[offset / (0x10/4)].period, mem_mask ); |
| 448 | return state->timer_regs.timer[offset / (0x10/4)].period; |
| 427 | 449 | case 0x0004/4: |
| 428 | 450 | case 0x0014/4: |
| 429 | 451 | case 0x0024/4: |
| 430 | | verboselog(space->machine, 0, "ps_timer_r: Timer %d Count = %08x & %08x\n", offset / (0x10/4), timer_regs.timer[offset / (0x10/4)].count, mem_mask ); |
| 431 | | if(timer_regs.timer[offset / (0x10/4)].control & 4) |
| 452 | verboselog(space->machine, 0, "ps_timer_r: Timer %d Count = %08x & %08x\n", offset / (0x10/4), state->timer_regs.timer[offset / (0x10/4)].count, mem_mask ); |
| 453 | if(state->timer_regs.timer[offset / (0x10/4)].control & 4) |
| 432 | 454 | { |
| 433 | | timer_regs.timer[offset / (0x10/4)].count--; |
| 434 | | if(timer_regs.timer[offset / (0x10/4)].count > timer_regs.timer[offset / (0x10/4)].period) |
| 455 | state->timer_regs.timer[offset / (0x10/4)].count--; |
| 456 | if(state->timer_regs.timer[offset / (0x10/4)].count > state->timer_regs.timer[offset / (0x10/4)].period) |
| 435 | 457 | { |
| 436 | | timer_regs.timer[offset / (0x10/4)].count = timer_regs.timer[offset / (0x10/4)].period; |
| 458 | state->timer_regs.timer[offset / (0x10/4)].count = state->timer_regs.timer[offset / (0x10/4)].period; |
| 437 | 459 | } |
| 438 | | return --timer_regs.timer[offset / (0x10/4)].count; |
| 460 | return --state->timer_regs.timer[offset / (0x10/4)].count; |
| 439 | 461 | } |
| 440 | | return timer_regs.timer[offset / (0x10/4)].count; |
| 462 | return state->timer_regs.timer[offset / (0x10/4)].count; |
| 441 | 463 | case 0x0008/4: |
| 442 | 464 | case 0x0018/4: |
| 443 | 465 | case 0x0028/4: |
| 444 | | verboselog(space->machine, 0, "ps_timer_r: Timer %d Control = %08x & %08x\n", offset / (0x10/4), timer_regs.timer[offset / (0x10/4)].control, mem_mask ); |
| 445 | | return timer_regs.timer[offset / (0x10/4)].control; |
| 466 | verboselog(space->machine, 0, "ps_timer_r: Timer %d Control = %08x & %08x\n", offset / (0x10/4), state->timer_regs.timer[offset / (0x10/4)].control, mem_mask ); |
| 467 | return state->timer_regs.timer[offset / (0x10/4)].control; |
| 446 | 468 | default: |
| 447 | 469 | verboselog(space->machine, 0, "ps_timer_r: Unknown Register %08x & %08x\n", 0x0a800000 + (offset << 2), mem_mask ); |
| 448 | 470 | break; |
| r9684 | r9685 | |
| 452 | 474 | |
| 453 | 475 | static WRITE32_HANDLER( ps_timer_w ) |
| 454 | 476 | { |
| 477 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 455 | 478 | switch(offset) |
| 456 | 479 | { |
| 457 | 480 | case 0x0000/4: |
| 458 | 481 | case 0x0010/4: |
| 459 | 482 | case 0x0020/4: |
| 460 | 483 | verboselog(space->machine, 0, "ps_timer_w: Timer %d Period = %08x & %08x\n", offset / (0x10/4), data, mem_mask ); |
| 461 | | COMBINE_DATA(&timer_regs.timer[offset / (0x10/4)].period); |
| 484 | COMBINE_DATA(&state->timer_regs.timer[offset / (0x10/4)].period); |
| 462 | 485 | break; |
| 463 | 486 | case 0x0004/4: |
| 464 | 487 | case 0x0014/4: |
| 465 | 488 | case 0x0024/4: |
| 466 | 489 | verboselog(space->machine, 0, "ps_timer_w: Timer %d Count = %08x & %08x\n", offset / (0x10/4), data, mem_mask ); |
| 467 | | COMBINE_DATA(&timer_regs.timer[offset / (0x10/4)].count); |
| 490 | COMBINE_DATA(&state->timer_regs.timer[offset / (0x10/4)].count); |
| 468 | 491 | break; |
| 469 | 492 | case 0x0008/4: |
| 470 | 493 | case 0x0018/4: |
| 471 | 494 | case 0x0028/4: |
| 472 | 495 | verboselog(space->machine, 0, "ps_timer_w: Timer %d Control = %08x & %08x\n", offset / (0x10/4), data, mem_mask ); |
| 473 | | COMBINE_DATA(&timer_regs.timer[offset / (0x10/4)].control); |
| 474 | | if(timer_regs.timer[offset / (0x10/4)].control & 4) |
| 496 | COMBINE_DATA(&state->timer_regs.timer[offset / (0x10/4)].control); |
| 497 | if(state->timer_regs.timer[offset / (0x10/4)].control & 4) |
| 475 | 498 | { |
| 476 | 499 | ps_timer_start(space->machine, offset / (0x10/4)); |
| 477 | 500 | } |
| 478 | 501 | else |
| 479 | 502 | { |
| 480 | | timer_adjust_oneshot(timer_regs.timer[offset / (0x10/4)].timer, attotime_never, offset / (0x10/4)); |
| 503 | timer_adjust_oneshot(state->timer_regs.timer[offset / (0x10/4)].timer, attotime_never, offset / (0x10/4)); |
| 481 | 504 | } |
| 482 | 505 | break; |
| 483 | 506 | default: |
| r9684 | r9685 | |
| 488 | 511 | |
| 489 | 512 | static READ32_HANDLER( ps_clock_r ) |
| 490 | 513 | { |
| 514 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 491 | 515 | switch(offset) |
| 492 | 516 | { |
| 493 | 517 | case 0x0000/4: |
| 494 | | verboselog(space->machine, 0, "ps_clock_r: Clock Mode = %08x & %08x\n", clock_regs.mode | 0x10, mem_mask ); |
| 495 | | return clock_regs.mode | PS_CLOCK_STEADY; |
| 518 | verboselog(space->machine, 0, "ps_clock_r: Clock Mode = %08x & %08x\n", state->clock_regs.mode | 0x10, mem_mask ); |
| 519 | return state->clock_regs.mode | PS_CLOCK_STEADY; |
| 496 | 520 | case 0x0004/4: |
| 497 | | verboselog(space->machine, 0, "ps_clock_r: Clock Control = %08x & %08x\n", clock_regs.control, mem_mask ); |
| 498 | | return clock_regs.control; |
| 521 | verboselog(space->machine, 0, "ps_clock_r: Clock Control = %08x & %08x\n", state->clock_regs.control, mem_mask ); |
| 522 | return state->clock_regs.control; |
| 499 | 523 | default: |
| 500 | 524 | verboselog(space->machine, 0, "ps_clock_r: Unknown Register %08x & %08x\n", 0x0b000000 + (offset << 2), mem_mask ); |
| 501 | 525 | break; |
| r9684 | r9685 | |
| 505 | 529 | |
| 506 | 530 | static WRITE32_HANDLER( ps_clock_w ) |
| 507 | 531 | { |
| 532 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 508 | 533 | switch(offset) |
| 509 | 534 | { |
| 510 | 535 | case 0x0000/4: |
| 511 | 536 | verboselog(space->machine, 0, "ps_clock_w: Clock Mode = %08x & %08x\n", data, mem_mask ); |
| 512 | | COMBINE_DATA(&clock_regs.mode); |
| 513 | | cputag_set_clock(space->machine, "maincpu", CPU_FREQ[clock_regs.mode & 0x0f]); |
| 537 | COMBINE_DATA(&state->clock_regs.mode); |
| 538 | cputag_set_clock(space->machine, "maincpu", CPU_FREQ[state->clock_regs.mode & 0x0f]); |
| 514 | 539 | break; |
| 515 | 540 | case 0x0004/4: |
| 516 | 541 | verboselog(space->machine, 0, "ps_clock_w: Clock Control = %08x & %08x\n", data, mem_mask ); |
| 517 | | COMBINE_DATA(&clock_regs.control); |
| 542 | COMBINE_DATA(&state->clock_regs.control); |
| 518 | 543 | break; |
| 519 | 544 | default: |
| 520 | 545 | verboselog(space->machine, 0, "ps_clock_w: Unknown Register %08x = %08x & %08x\n", 0x0b000000 + (offset << 2), data, mem_mask ); |
| r9684 | r9685 | |
| 524 | 549 | |
| 525 | 550 | static TIMER_CALLBACK( rtc_tick ) |
| 526 | 551 | { |
| 552 | pockstat_state *state = machine->driver_data<pockstat_state>(); |
| 527 | 553 | //printf( "RTC is calling back\n" ); |
| 528 | 554 | ps_intc_set_interrupt_line(machine, PS_INT_RTC, ps_intc_get_interrupt_line(machine, PS_INT_RTC) ? 0 : 1); |
| 529 | | if(!(rtc_regs.mode & 1)) |
| 555 | if(!(state->rtc_regs.mode & 1)) |
| 530 | 556 | { |
| 531 | | rtc_regs.time++; |
| 532 | | if((rtc_regs.time & 0x0000000f) == 0x0000000a) |
| 557 | state->rtc_regs.time++; |
| 558 | if((state->rtc_regs.time & 0x0000000f) == 0x0000000a) |
| 533 | 559 | { |
| 534 | | rtc_regs.time &= 0xfffffff0; |
| 535 | | rtc_regs.time += 0x00000010; |
| 536 | | if((rtc_regs.time & 0x000000ff) == 0x00000060) |
| 560 | state->rtc_regs.time &= 0xfffffff0; |
| 561 | state->rtc_regs.time += 0x00000010; |
| 562 | if((state->rtc_regs.time & 0x000000ff) == 0x00000060) |
| 537 | 563 | { |
| 538 | | rtc_regs.time &= 0xffffff00; |
| 539 | | rtc_regs.time += 0x00000100; |
| 540 | | if((rtc_regs.time & 0x00000f00) == 0x00000a00) |
| 564 | state->rtc_regs.time &= 0xffffff00; |
| 565 | state->rtc_regs.time += 0x00000100; |
| 566 | if((state->rtc_regs.time & 0x00000f00) == 0x00000a00) |
| 541 | 567 | { |
| 542 | | rtc_regs.time &= 0xfffff0ff; |
| 543 | | rtc_regs.time += 0x00001000; |
| 544 | | if((rtc_regs.time & 0x0000ff00) == 0x00006000) |
| 568 | state->rtc_regs.time &= 0xfffff0ff; |
| 569 | state->rtc_regs.time += 0x00001000; |
| 570 | if((state->rtc_regs.time & 0x0000ff00) == 0x00006000) |
| 545 | 571 | { |
| 546 | | rtc_regs.time &= 0xffff00ff; |
| 547 | | rtc_regs.time += 0x00010000; |
| 548 | | if((rtc_regs.time & 0x00ff0000) == 0x00240000) |
| 572 | state->rtc_regs.time &= 0xffff00ff; |
| 573 | state->rtc_regs.time += 0x00010000; |
| 574 | if((state->rtc_regs.time & 0x00ff0000) == 0x00240000) |
| 549 | 575 | { |
| 550 | | rtc_regs.time &= 0xff00ffff; |
| 551 | | rtc_regs.time += 0x01000000; |
| 552 | | if((rtc_regs.time & 0x0f000000) == 0x08000000) |
| 576 | state->rtc_regs.time &= 0xff00ffff; |
| 577 | state->rtc_regs.time += 0x01000000; |
| 578 | if((state->rtc_regs.time & 0x0f000000) == 0x08000000) |
| 553 | 579 | { |
| 554 | | rtc_regs.time &= 0xf0ffffff; |
| 555 | | rtc_regs.time |= 0x01000000; |
| 580 | state->rtc_regs.time &= 0xf0ffffff; |
| 581 | state->rtc_regs.time |= 0x01000000; |
| 556 | 582 | } |
| 557 | 583 | } |
| 558 | | else if((rtc_regs.time & 0x000f0000) == 0x000a0000) |
| 584 | else if((state->rtc_regs.time & 0x000f0000) == 0x000a0000) |
| 559 | 585 | { |
| 560 | | rtc_regs.time &= 0xfff0ffff; |
| 561 | | rtc_regs.time += 0x00100000; |
| 586 | state->rtc_regs.time &= 0xfff0ffff; |
| 587 | state->rtc_regs.time += 0x00100000; |
| 562 | 588 | } |
| 563 | 589 | } |
| 564 | 590 | } |
| 565 | 591 | } |
| 566 | 592 | } |
| 567 | 593 | } |
| 568 | | timer_adjust_oneshot(rtc_regs.timer, ATTOTIME_IN_HZ(1), 0); |
| 594 | timer_adjust_oneshot(state->rtc_regs.timer, ATTOTIME_IN_HZ(1), 0); |
| 569 | 595 | } |
| 570 | 596 | |
| 571 | 597 | static READ32_HANDLER( ps_rtc_r ) |
| 572 | 598 | { |
| 599 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 573 | 600 | switch(offset) |
| 574 | 601 | { |
| 575 | 602 | case 0x0000/4: |
| 576 | | verboselog(space->machine, 0, "ps_rtc_r: RTC Mode = %08x & %08x\n", rtc_regs.mode, mem_mask ); |
| 577 | | return rtc_regs.mode; |
| 603 | verboselog(space->machine, 0, "ps_rtc_r: RTC Mode = %08x & %08x\n", state->rtc_regs.mode, mem_mask ); |
| 604 | return state->rtc_regs.mode; |
| 578 | 605 | case 0x0004/4: |
| 579 | | verboselog(space->machine, 0, "ps_rtc_r: RTC Control = %08x & %08x\n", rtc_regs.control, mem_mask ); |
| 580 | | return rtc_regs.control; |
| 606 | verboselog(space->machine, 0, "ps_rtc_r: RTC Control = %08x & %08x\n", state->rtc_regs.control, mem_mask ); |
| 607 | return state->rtc_regs.control; |
| 581 | 608 | case 0x0008/4: |
| 582 | | verboselog(space->machine, 0, "ps_rtc_r: RTC Time = %08x & %08x\n", rtc_regs.time, mem_mask ); |
| 583 | | return rtc_regs.time; |
| 609 | verboselog(space->machine, 0, "ps_rtc_r: RTC Time = %08x & %08x\n", state->rtc_regs.time, mem_mask ); |
| 610 | return state->rtc_regs.time; |
| 584 | 611 | case 0x000c/4: |
| 585 | | verboselog(space->machine, 0, "ps_rtc_r: RTC Date = %08x & %08x\n", rtc_regs.date, mem_mask ); |
| 586 | | return rtc_regs.date; |
| 612 | verboselog(space->machine, 0, "ps_rtc_r: RTC Date = %08x & %08x\n", state->rtc_regs.date, mem_mask ); |
| 613 | return state->rtc_regs.date; |
| 587 | 614 | default: |
| 588 | 615 | verboselog(space->machine, 0, "ps_rtc_r: Unknown Register %08x & %08x\n", 0x0b800000 + (offset << 2), mem_mask ); |
| 589 | 616 | break; |
| r9684 | r9685 | |
| 593 | 620 | |
| 594 | 621 | static WRITE32_HANDLER( ps_rtc_w ) |
| 595 | 622 | { |
| 623 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 596 | 624 | switch(offset) |
| 597 | 625 | { |
| 598 | 626 | case 0x0000/4: |
| 599 | 627 | verboselog(space->machine, 0, "ps_rtc_w: RTC Mode = %08x & %08x\n", data, mem_mask ); |
| 600 | | COMBINE_DATA(&rtc_regs.mode); |
| 628 | COMBINE_DATA(&state->rtc_regs.mode); |
| 601 | 629 | break; |
| 602 | 630 | case 0x0004/4: |
| 603 | 631 | verboselog(space->machine, 0, "ps_rtc_w: RTC Control = %08x & %08x\n", data, mem_mask ); |
| 604 | | if(rtc_regs.control == 1 && data == 1) |
| 632 | if(state->rtc_regs.control == 1 && data == 1) |
| 605 | 633 | { |
| 606 | | switch(rtc_regs.mode >> 1) |
| 634 | switch(state->rtc_regs.mode >> 1) |
| 607 | 635 | { |
| 608 | 636 | case 0: // Seconds |
| 609 | | rtc_regs.time += 0x00000001; |
| 610 | | if((rtc_regs.time & 0x0000000f) == 0x0000000a) |
| 637 | state->rtc_regs.time += 0x00000001; |
| 638 | if((state->rtc_regs.time & 0x0000000f) == 0x0000000a) |
| 611 | 639 | { |
| 612 | | rtc_regs.time &= 0xfffffff0; |
| 613 | | rtc_regs.time += 0x00000010; |
| 614 | | if((rtc_regs.time & 0x000000ff) == 0x00000060) |
| 640 | state->rtc_regs.time &= 0xfffffff0; |
| 641 | state->rtc_regs.time += 0x00000010; |
| 642 | if((state->rtc_regs.time & 0x000000ff) == 0x00000060) |
| 615 | 643 | { |
| 616 | | rtc_regs.time &= 0xffffff00; |
| 644 | state->rtc_regs.time &= 0xffffff00; |
| 617 | 645 | } |
| 618 | 646 | } |
| 619 | 647 | break; |
| 620 | 648 | case 1: // Minutes |
| 621 | | rtc_regs.time += 0x00000100; |
| 622 | | if((rtc_regs.time & 0x00000f00) == 0x00000a00) |
| 649 | state->rtc_regs.time += 0x00000100; |
| 650 | if((state->rtc_regs.time & 0x00000f00) == 0x00000a00) |
| 623 | 651 | { |
| 624 | | rtc_regs.time &= 0xfffff0ff; |
| 625 | | rtc_regs.time += 0x00001000; |
| 626 | | if((rtc_regs.time & 0x0000ff00) == 0x00006000) |
| 652 | state->rtc_regs.time &= 0xfffff0ff; |
| 653 | state->rtc_regs.time += 0x00001000; |
| 654 | if((state->rtc_regs.time & 0x0000ff00) == 0x00006000) |
| 627 | 655 | { |
| 628 | | rtc_regs.time &= 0xffff00ff; |
| 656 | state->rtc_regs.time &= 0xffff00ff; |
| 629 | 657 | } |
| 630 | 658 | } |
| 631 | 659 | break; |
| 632 | 660 | case 2: // Hours |
| 633 | | rtc_regs.time += 0x00010000; |
| 634 | | if((rtc_regs.time & 0x00ff0000) == 0x00240000) |
| 661 | state->rtc_regs.time += 0x00010000; |
| 662 | if((state->rtc_regs.time & 0x00ff0000) == 0x00240000) |
| 635 | 663 | { |
| 636 | | rtc_regs.time &= 0xff00ffff; |
| 664 | state->rtc_regs.time &= 0xff00ffff; |
| 637 | 665 | } |
| 638 | | else if((rtc_regs.time & 0x000f0000) == 0x000a0000) |
| 666 | else if((state->rtc_regs.time & 0x000f0000) == 0x000a0000) |
| 639 | 667 | { |
| 640 | | rtc_regs.time &= 0xfff0ffff; |
| 641 | | rtc_regs.time += 0x00100000; |
| 668 | state->rtc_regs.time &= 0xfff0ffff; |
| 669 | state->rtc_regs.time += 0x00100000; |
| 642 | 670 | } |
| 643 | 671 | break; |
| 644 | 672 | case 3: // Day of the week |
| 645 | | rtc_regs.time += 0x01000000; |
| 646 | | if((rtc_regs.time & 0x0f000000) == 0x08000000) |
| 673 | state->rtc_regs.time += 0x01000000; |
| 674 | if((state->rtc_regs.time & 0x0f000000) == 0x08000000) |
| 647 | 675 | { |
| 648 | | rtc_regs.time &= 0xf0ffffff; |
| 649 | | rtc_regs.time |= 0x01000000; |
| 676 | state->rtc_regs.time &= 0xf0ffffff; |
| 677 | state->rtc_regs.time |= 0x01000000; |
| 650 | 678 | } |
| 651 | 679 | break; |
| 652 | 680 | case 4: // Day |
| 653 | | rtc_regs.date += 0x00000001; |
| 654 | | if((rtc_regs.date & 0x000000ff) == 0x00000032) |
| 681 | state->rtc_regs.date += 0x00000001; |
| 682 | if((state->rtc_regs.date & 0x000000ff) == 0x00000032) |
| 655 | 683 | { |
| 656 | | rtc_regs.date &= 0xffffff00; |
| 684 | state->rtc_regs.date &= 0xffffff00; |
| 657 | 685 | } |
| 658 | | else if((rtc_regs.date & 0x0000000f) == 0x0000000a) |
| 686 | else if((state->rtc_regs.date & 0x0000000f) == 0x0000000a) |
| 659 | 687 | { |
| 660 | | rtc_regs.date &= 0xfffffff0; |
| 661 | | rtc_regs.date += 0x00000010; |
| 688 | state->rtc_regs.date &= 0xfffffff0; |
| 689 | state->rtc_regs.date += 0x00000010; |
| 662 | 690 | } |
| 663 | 691 | break; |
| 664 | 692 | case 5: // Month |
| 665 | | rtc_regs.date += 0x00000100; |
| 666 | | if((rtc_regs.date & 0x0000ff00) == 0x00001300) |
| 693 | state->rtc_regs.date += 0x00000100; |
| 694 | if((state->rtc_regs.date & 0x0000ff00) == 0x00001300) |
| 667 | 695 | { |
| 668 | | rtc_regs.date &= 0xffffff00; |
| 669 | | rtc_regs.date |= 0x00000001; |
| 696 | state->rtc_regs.date &= 0xffffff00; |
| 697 | state->rtc_regs.date |= 0x00000001; |
| 670 | 698 | } |
| 671 | | else if((rtc_regs.date & 0x00000f00) == 0x00000a00) |
| 699 | else if((state->rtc_regs.date & 0x00000f00) == 0x00000a00) |
| 672 | 700 | { |
| 673 | | rtc_regs.date &= 0xfffff0ff; |
| 674 | | rtc_regs.date += 0x00001000; |
| 701 | state->rtc_regs.date &= 0xfffff0ff; |
| 702 | state->rtc_regs.date += 0x00001000; |
| 675 | 703 | } |
| 676 | 704 | break; |
| 677 | 705 | case 6: // Year (LSB) |
| 678 | | rtc_regs.date += 0x00010000; |
| 679 | | if((rtc_regs.date & 0x000f0000) == 0x000a0000) |
| 706 | state->rtc_regs.date += 0x00010000; |
| 707 | if((state->rtc_regs.date & 0x000f0000) == 0x000a0000) |
| 680 | 708 | { |
| 681 | | rtc_regs.date &= 0xfff0ffff; |
| 682 | | rtc_regs.date += 0x00100000; |
| 683 | | if((rtc_regs.date & 0x00f00000) == 0x00a00000) |
| 709 | state->rtc_regs.date &= 0xfff0ffff; |
| 710 | state->rtc_regs.date += 0x00100000; |
| 711 | if((state->rtc_regs.date & 0x00f00000) == 0x00a00000) |
| 684 | 712 | { |
| 685 | | rtc_regs.date &= 0xff00ffff; |
| 713 | state->rtc_regs.date &= 0xff00ffff; |
| 686 | 714 | } |
| 687 | 715 | } |
| 688 | 716 | break; |
| 689 | 717 | case 7: // Year (MSB) |
| 690 | 718 | break; |
| 691 | 719 | } |
| 692 | | rtc_regs.control = 0; |
| 720 | state->rtc_regs.control = 0; |
| 693 | 721 | } |
| 694 | | else if(rtc_regs.control == 0) |
| 722 | else if(state->rtc_regs.control == 0) |
| 695 | 723 | { |
| 696 | | COMBINE_DATA(&rtc_regs.control); |
| 724 | COMBINE_DATA(&state->rtc_regs.control); |
| 697 | 725 | } |
| 698 | 726 | break; |
| 699 | 727 | default: |
| r9684 | r9685 | |
| 702 | 730 | } |
| 703 | 731 | } |
| 704 | 732 | |
| 705 | | static UINT32 lcd_control; |
| 706 | 733 | |
| 707 | 734 | static READ32_HANDLER( ps_lcd_r ) |
| 708 | 735 | { |
| 736 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 709 | 737 | switch(offset) |
| 710 | 738 | { |
| 711 | 739 | case 0x0000/4: |
| 712 | | verboselog(space->machine, 0, "ps_lcd_r: LCD Control = %08x & %08x\n", lcd_control | 0x100, mem_mask ); |
| 713 | | return lcd_control; |
| 740 | verboselog(space->machine, 0, "ps_lcd_r: LCD Control = %08x & %08x\n", state->lcd_control | 0x100, mem_mask ); |
| 741 | return state->lcd_control; |
| 714 | 742 | default: |
| 715 | 743 | verboselog(space->machine, 0, "ps_lcd_r: Unknown Register %08x & %08x\n", 0x0d000000 + (offset << 2), mem_mask ); |
| 716 | 744 | break; |
| r9684 | r9685 | |
| 720 | 748 | |
| 721 | 749 | static WRITE32_HANDLER( ps_lcd_w ) |
| 722 | 750 | { |
| 751 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 723 | 752 | switch(offset) |
| 724 | 753 | { |
| 725 | 754 | case 0x0000/4: |
| 726 | 755 | verboselog(space->machine, 0, "ps_lcd_w: LCD Control = %08x & %08x\n", data, mem_mask ); |
| 727 | | COMBINE_DATA(&lcd_control); |
| 756 | COMBINE_DATA(&state->lcd_control); |
| 728 | 757 | break; |
| 729 | 758 | default: |
| 730 | 759 | verboselog(space->machine, 0, "ps_lcd_w: Unknown Register %08x = %08x & %08x\n", 0x0d000000 + (offset << 2), data, mem_mask ); |
| r9684 | r9685 | |
| 745 | 774 | |
| 746 | 775 | static READ32_HANDLER(ps_rombank_r) |
| 747 | 776 | { |
| 777 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 748 | 778 | INT32 bank = (offset >> 11) & 0x0f; |
| 749 | 779 | int index = 0; |
| 750 | 780 | for(index = 0; index < 32; index++) |
| 751 | 781 | { |
| 752 | | if(ftlb_regs.valid & (1 << index)) |
| 782 | if(state->ftlb_regs.valid & (1 << index)) |
| 753 | 783 | { |
| 754 | | if(ftlb_regs.entry[index] == bank) |
| 784 | if(state->ftlb_regs.entry[index] == bank) |
| 755 | 785 | { |
| 756 | 786 | //printf( "Address %08x is assigned to %08x in entry %d\n", 0x02000000 + (offset << 2), index * 0x2000 + ((offset << 2) & 0x1fff), index ); |
| 757 | 787 | return ((UINT32*)memory_region(space->machine, "flash"))[index * (0x2000/4) + (offset & (0x1fff/4))]; |
| r9684 | r9685 | |
| 761 | 791 | return ((UINT32*)memory_region(space->machine, "flash"))[offset & 0x7fff]; |
| 762 | 792 | } |
| 763 | 793 | |
| 764 | | static INT32 ps_flash_write_enable_count; |
| 765 | | static INT32 ps_flash_write_count; |
| 766 | 794 | |
| 767 | 795 | // Horrible hack, probably wrong |
| 768 | 796 | static WRITE32_HANDLER(ps_flash_w) |
| 769 | 797 | { |
| 798 | pockstat_state *state = space->machine->driver_data<pockstat_state>(); |
| 770 | 799 | if(offset == (0x55a8/4)) |
| 771 | 800 | { |
| 772 | | ps_flash_write_enable_count++; |
| 801 | state->ps_flash_write_enable_count++; |
| 773 | 802 | return; |
| 774 | 803 | } |
| 775 | 804 | if(offset == (0x2a54/4)) |
| 776 | 805 | { |
| 777 | | ps_flash_write_enable_count++; |
| 806 | state->ps_flash_write_enable_count++; |
| 778 | 807 | return; |
| 779 | 808 | } |
| 780 | | if(ps_flash_write_enable_count == 3) |
| 809 | if(state->ps_flash_write_enable_count == 3) |
| 781 | 810 | { |
| 782 | | ps_flash_write_enable_count = 0; |
| 783 | | ps_flash_write_count = 0x40; |
| 811 | state->ps_flash_write_enable_count = 0; |
| 812 | state->ps_flash_write_count = 0x40; |
| 784 | 813 | return; |
| 785 | 814 | } |
| 786 | | if(ps_flash_write_count) |
| 815 | if(state->ps_flash_write_count) |
| 787 | 816 | { |
| 788 | | ps_flash_write_count--; |
| 817 | state->ps_flash_write_count--; |
| 789 | 818 | COMBINE_DATA(&((UINT32*)memory_region(space->machine, "flash"))[offset]); |
| 790 | 819 | } |
| 791 | 820 | } |
| r9684 | r9685 | |
| 817 | 846 | AM_RANGE(0x0b000000, 0x0b000007) AM_READWRITE(ps_clock_r, ps_clock_w) |
| 818 | 847 | AM_RANGE(0x0b800000, 0x0b80000f) AM_READWRITE(ps_rtc_r, ps_rtc_w) |
| 819 | 848 | AM_RANGE(0x0d000000, 0x0d000003) AM_READWRITE(ps_lcd_r, ps_lcd_w) |
| 820 | | AM_RANGE(0x0d000100, 0x0d00017f) AM_RAM AM_BASE(&lcd_buffer) |
| 849 | AM_RANGE(0x0d000100, 0x0d00017f) AM_RAM AM_BASE_MEMBER(pockstat_state, lcd_buffer) |
| 821 | 850 | AM_RANGE(0x0d80000c, 0x0d80000f) AM_READWRITE(ps_audio_r, ps_audio_w) |
| 822 | 851 | AM_RANGE(0x0d800014, 0x0d800017) AM_WRITE(ps_dac_w) |
| 823 | 852 | ADDRESS_MAP_END |
| r9684 | r9685 | |
| 835 | 864 | |
| 836 | 865 | static MACHINE_START( pockstat ) |
| 837 | 866 | { |
| 867 | pockstat_state *state = machine->driver_data<pockstat_state>(); |
| 838 | 868 | int index = 0; |
| 839 | 869 | for(index = 0; index < 3; index++) |
| 840 | 870 | { |
| 841 | | timer_regs.timer[index].timer = timer_alloc(machine, timer_tick, 0); |
| 842 | | timer_adjust_oneshot(timer_regs.timer[index].timer, attotime_never, index); |
| 871 | state->timer_regs.timer[index].timer = timer_alloc(machine, timer_tick, 0); |
| 872 | timer_adjust_oneshot(state->timer_regs.timer[index].timer, attotime_never, index); |
| 843 | 873 | } |
| 844 | 874 | |
| 845 | | rtc_regs.time = 0x01000000; |
| 846 | | rtc_regs.date = 0x19990101; |
| 875 | state->rtc_regs.time = 0x01000000; |
| 876 | state->rtc_regs.date = 0x19990101; |
| 847 | 877 | |
| 848 | | rtc_regs.timer = timer_alloc(machine, rtc_tick, 0); |
| 849 | | timer_adjust_oneshot(rtc_regs.timer, ATTOTIME_IN_HZ(1), index); |
| 878 | state->rtc_regs.timer = timer_alloc(machine, rtc_tick, 0); |
| 879 | timer_adjust_oneshot(state->rtc_regs.timer, ATTOTIME_IN_HZ(1), index); |
| 850 | 880 | |
| 851 | | state_save_register_global(machine, ftlb_regs.control); |
| 852 | | state_save_register_global(machine, ftlb_regs.stat); |
| 853 | | state_save_register_global(machine, ftlb_regs.valid); |
| 854 | | state_save_register_global(machine, ftlb_regs.wait1); |
| 855 | | state_save_register_global(machine, ftlb_regs.wait2); |
| 856 | | state_save_register_global_array(machine, ftlb_regs.entry); |
| 881 | state_save_register_global(machine, state->ftlb_regs.control); |
| 882 | state_save_register_global(machine, state->ftlb_regs.stat); |
| 883 | state_save_register_global(machine, state->ftlb_regs.valid); |
| 884 | state_save_register_global(machine, state->ftlb_regs.wait1); |
| 885 | state_save_register_global(machine, state->ftlb_regs.wait2); |
| 886 | state_save_register_global_array(machine, state->ftlb_regs.entry); |
| 857 | 887 | |
| 858 | | state_save_register_global(machine, intc_regs.hold); |
| 859 | | state_save_register_global(machine, intc_regs.status); |
| 860 | | state_save_register_global(machine, intc_regs.enable); |
| 861 | | state_save_register_global(machine, intc_regs.mask); |
| 888 | state_save_register_global(machine, state->intc_regs.hold); |
| 889 | state_save_register_global(machine, state->intc_regs.status); |
| 890 | state_save_register_global(machine, state->intc_regs.enable); |
| 891 | state_save_register_global(machine, state->intc_regs.mask); |
| 862 | 892 | |
| 863 | | state_save_register_global(machine, timer_regs.timer[0].period); |
| 864 | | state_save_register_global(machine, timer_regs.timer[0].count); |
| 865 | | state_save_register_global(machine, timer_regs.timer[0].control); |
| 866 | | state_save_register_global(machine, timer_regs.timer[1].period); |
| 867 | | state_save_register_global(machine, timer_regs.timer[1].count); |
| 868 | | state_save_register_global(machine, timer_regs.timer[1].control); |
| 869 | | state_save_register_global(machine, timer_regs.timer[2].period); |
| 870 | | state_save_register_global(machine, timer_regs.timer[2].count); |
| 871 | | state_save_register_global(machine, timer_regs.timer[2].control); |
| 893 | state_save_register_global(machine, state->timer_regs.timer[0].period); |
| 894 | state_save_register_global(machine, state->timer_regs.timer[0].count); |
| 895 | state_save_register_global(machine, state->timer_regs.timer[0].control); |
| 896 | state_save_register_global(machine, state->timer_regs.timer[1].period); |
| 897 | state_save_register_global(machine, state->timer_regs.timer[1].count); |
| 898 | state_save_register_global(machine, state->timer_regs.timer[1].control); |
| 899 | state_save_register_global(machine, state->timer_regs.timer[2].period); |
| 900 | state_save_register_global(machine, state->timer_regs.timer[2].count); |
| 901 | state_save_register_global(machine, state->timer_regs.timer[2].control); |
| 872 | 902 | |
| 873 | | state_save_register_global(machine, clock_regs.mode); |
| 874 | | state_save_register_global(machine, clock_regs.control); |
| 903 | state_save_register_global(machine, state->clock_regs.mode); |
| 904 | state_save_register_global(machine, state->clock_regs.control); |
| 875 | 905 | |
| 876 | | state_save_register_global(machine, rtc_regs.mode); |
| 877 | | state_save_register_global(machine, rtc_regs.control); |
| 878 | | state_save_register_global(machine, rtc_regs.time); |
| 879 | | state_save_register_global(machine, rtc_regs.date); |
| 906 | state_save_register_global(machine, state->rtc_regs.mode); |
| 907 | state_save_register_global(machine, state->rtc_regs.control); |
| 908 | state_save_register_global(machine, state->rtc_regs.time); |
| 909 | state_save_register_global(machine, state->rtc_regs.date); |
| 880 | 910 | |
| 881 | | state_save_register_global(machine, ps_flash_write_enable_count); |
| 882 | | state_save_register_global(machine, ps_flash_write_count); |
| 911 | state_save_register_global(machine, state->ps_flash_write_enable_count); |
| 912 | state_save_register_global(machine, state->ps_flash_write_count); |
| 883 | 913 | } |
| 884 | 914 | |
| 885 | 915 | static MACHINE_RESET( pockstat ) |
| 886 | 916 | { |
| 917 | pockstat_state *state = machine->driver_data<pockstat_state>(); |
| 887 | 918 | cpu_set_reg(machine->device("maincpu"), STATE_GENPC, 0x4000000); |
| 888 | 919 | |
| 889 | | ps_flash_write_enable_count = 0; |
| 890 | | ps_flash_write_count = 0; |
| 920 | state->ps_flash_write_enable_count = 0; |
| 921 | state->ps_flash_write_count = 0; |
| 891 | 922 | } |
| 892 | 923 | |
| 893 | 924 | static VIDEO_UPDATE( pockstat ) |
| 894 | 925 | { |
| 926 | pockstat_state *state = screen->machine->driver_data<pockstat_state>(); |
| 895 | 927 | int x = 0; |
| 896 | 928 | int y = 0; |
| 897 | 929 | for(y = 0; y < 32; y++) |
| r9684 | r9685 | |
| 899 | 931 | UINT32 *scanline = BITMAP_ADDR32(bitmap, y, 0); |
| 900 | 932 | for(x = 0; x < 32; x++) |
| 901 | 933 | { |
| 902 | | if(lcd_control != 0) // Hack |
| 934 | if(state->lcd_control != 0) // Hack |
| 903 | 935 | { |
| 904 | | if(lcd_buffer[y] & (1 << x)) |
| 936 | if(state->lcd_buffer[y] & (1 << x)) |
| 905 | 937 | { |
| 906 | 938 | scanline[x] = 0x00000000; |
| 907 | 939 | } |
| r9684 | r9685 | |
| 945 | 977 | return IMAGE_INIT_PASS; |
| 946 | 978 | } |
| 947 | 979 | |
| 948 | | static MACHINE_CONFIG_START( pockstat, driver_device ) |
| 980 | static MACHINE_CONFIG_START( pockstat, pockstat_state ) |
| 949 | 981 | /* basic machine hardware */ |
| 950 | 982 | MDRV_CPU_ADD("maincpu", ARM7, DEFAULT_CLOCK) |
| 951 | 983 | MDRV_CPU_PROGRAM_MAP(pockstat_mem) |
src/mess/drivers/scv.c
| r9684 | r9685 | |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | |
| 41 | | static UINT8 *scv_vram; |
| 42 | 41 | |
| 43 | 42 | |
| 44 | 43 | static ADDRESS_MAP_START( scv_mem, ADDRESS_SPACE_PROGRAM, 8 ) |
| 45 | 44 | AM_RANGE( 0x0000, 0x0fff ) AM_ROM /* BIOS */ |
| 46 | 45 | |
| 47 | | AM_RANGE( 0x2000, 0x3403 ) AM_RAM AM_BASE( &scv_vram ) /* VRAM + 4 registers */ |
| 46 | AM_RANGE( 0x2000, 0x3403 ) AM_RAM AM_BASE_MEMBER(scv_state, vram ) /* VRAM + 4 registers */ |
| 48 | 47 | |
| 49 | 48 | AM_RANGE( 0x3600, 0x3600 ) AM_DEVWRITE( "upd1771c", upd1771_w ) |
| 50 | 49 | |
| r9684 | r9685 | |
| 449 | 448 | } |
| 450 | 449 | |
| 451 | 450 | |
| 452 | | INLINE void draw_sprite( bitmap_t *bitmap, UINT8 x, UINT8 y, UINT8 tile_idx, UINT8 col, UINT8 left, UINT8 right, UINT8 top, UINT8 bottom, UINT8 clip_y ) |
| 451 | INLINE void draw_sprite( scv_state *state, bitmap_t *bitmap, UINT8 x, UINT8 y, UINT8 tile_idx, UINT8 col, UINT8 left, UINT8 right, UINT8 top, UINT8 bottom, UINT8 clip_y ) |
| 453 | 452 | { |
| 454 | 453 | int j; |
| 455 | 454 | |
| 456 | 455 | y += clip_y * 2; |
| 457 | 456 | for ( j = clip_y * 4; j < 32; j += 4 ) |
| 458 | 457 | { |
| 459 | | UINT8 pat0 = scv_vram[ tile_idx * 32 + j + 0 ]; |
| 460 | | UINT8 pat1 = scv_vram[ tile_idx * 32 + j + 1 ]; |
| 461 | | UINT8 pat2 = scv_vram[ tile_idx * 32 + j + 2 ]; |
| 462 | | UINT8 pat3 = scv_vram[ tile_idx * 32 + j + 3 ]; |
| 458 | UINT8 pat0 = state->vram[ tile_idx * 32 + j + 0 ]; |
| 459 | UINT8 pat1 = state->vram[ tile_idx * 32 + j + 1 ]; |
| 460 | UINT8 pat2 = state->vram[ tile_idx * 32 + j + 2 ]; |
| 461 | UINT8 pat3 = state->vram[ tile_idx * 32 + j + 3 ]; |
| 463 | 462 | |
| 464 | 463 | if ( ( top && j < 16 ) || ( bottom && j >= 16 ) ) |
| 465 | 464 | { |
| r9684 | r9685 | |
| 561 | 560 | |
| 562 | 561 | static VIDEO_UPDATE( scv ) |
| 563 | 562 | { |
| 563 | scv_state *state = screen->machine->driver_data<scv_state>(); |
| 564 | 564 | int x, y; |
| 565 | | UINT8 fg = scv_vram[0x1403] >> 4; |
| 566 | | UINT8 bg = scv_vram[0x1403] & 0x0f; |
| 567 | | UINT8 gr_fg = scv_vram[0x1401] >> 4; |
| 568 | | UINT8 gr_bg = scv_vram[0x1401] & 0x0f; |
| 569 | | int clip_x = ( scv_vram[0x1402] & 0x0f ) * 2; |
| 570 | | int clip_y = scv_vram[0x1402] >> 4; |
| 565 | UINT8 fg = state->vram[0x1403] >> 4; |
| 566 | UINT8 bg = state->vram[0x1403] & 0x0f; |
| 567 | UINT8 gr_fg = state->vram[0x1401] >> 4; |
| 568 | UINT8 gr_bg = state->vram[0x1401] & 0x0f; |
| 569 | int clip_x = ( state->vram[0x1402] & 0x0f ) * 2; |
| 570 | int clip_y = state->vram[0x1402] >> 4; |
| 571 | 571 | |
| 572 | 572 | /* Clear the screen */ |
| 573 | 573 | bitmap_fill( bitmap, cliprect, gr_bg ); |
| r9684 | r9685 | |
| 578 | 578 | int text_y = 0; |
| 579 | 579 | |
| 580 | 580 | if ( y < clip_y ) |
| 581 | | text_y = ( scv_vram[0x1400] & 0x80 ) ? 0 : 1; |
| 581 | text_y = ( state->vram[0x1400] & 0x80 ) ? 0 : 1; |
| 582 | 582 | else |
| 583 | | text_y = ( scv_vram[0x1400] & 0x80 ) ? 1 : 0; |
| 583 | text_y = ( state->vram[0x1400] & 0x80 ) ? 1 : 0; |
| 584 | 584 | |
| 585 | 585 | for ( x = 0; x < 32; x++ ) |
| 586 | 586 | { |
| 587 | 587 | int text_x = 0; |
| 588 | | UINT8 d = scv_vram[ 0x1000 + y * 32 + x ]; |
| 588 | UINT8 d = state->vram[ 0x1000 + y * 32 + x ]; |
| 589 | 589 | |
| 590 | 590 | if ( x < clip_x ) |
| 591 | | text_x = ( scv_vram[0x1400] & 0x40 ) ? 0 : 1; |
| 591 | text_x = ( state->vram[0x1400] & 0x40 ) ? 0 : 1; |
| 592 | 592 | else |
| 593 | | text_x = ( scv_vram[0x1400] & 0x40 ) ? 1 : 0; |
| 593 | text_x = ( state->vram[0x1400] & 0x40 ) ? 1 : 0; |
| 594 | 594 | |
| 595 | 595 | if ( text_x && text_y ) |
| 596 | 596 | { |
| r9684 | r9685 | |
| 600 | 600 | } |
| 601 | 601 | else |
| 602 | 602 | { |
| 603 | | switch ( scv_vram[0x1400] & 0x03 ) |
| 603 | switch ( state->vram[0x1400] & 0x03 ) |
| 604 | 604 | { |
| 605 | 605 | case 0x01: /* Semi graphics mode */ |
| 606 | 606 | draw_semi_graph( bitmap, x * 8 , y * 16 , d & 0x80, gr_fg ); |
| r9684 | r9685 | |
| 624 | 624 | } |
| 625 | 625 | |
| 626 | 626 | /* Draw sprites if enabled */ |
| 627 | | if ( scv_vram[0x1400] & 0x10 ) |
| 627 | if ( state->vram[0x1400] & 0x10 ) |
| 628 | 628 | { |
| 629 | 629 | int i; |
| 630 | 630 | |
| 631 | 631 | for ( i = 0; i < 128; i++ ) |
| 632 | 632 | { |
| 633 | | UINT8 spr_y = scv_vram[ 0x1200 + i * 4 ] & 0xfe; |
| 634 | | UINT8 y_32 = scv_vram[ 0x1200 + i * 4 ] & 0x01; /* Xx32 sprite */ |
| 635 | | UINT8 clip = scv_vram[ 0x1201 + i * 4 ] >> 4; |
| 636 | | UINT8 col = scv_vram[ 0x1201 + i * 4 ] & 0x0f; |
| 637 | | UINT8 spr_x = scv_vram[ 0x1202 + i * 4 ] & 0xfe; |
| 638 | | UINT8 x_32 = scv_vram[ 0x1202 + i * 4 ] & 0x01; /* 32xX sprite */ |
| 639 | | UINT8 tile_idx = scv_vram[ 0x1203 + i * 4 ] & 0x7f; |
| 640 | | UINT8 half = scv_vram[ 0x1203 + i * 4] & 0x80; |
| 633 | UINT8 spr_y = state->vram[ 0x1200 + i * 4 ] & 0xfe; |
| 634 | UINT8 y_32 = state->vram[ 0x1200 + i * 4 ] & 0x01; /* Xx32 sprite */ |
| 635 | UINT8 clip = state->vram[ 0x1201 + i * 4 ] >> 4; |
| 636 | UINT8 col = state->vram[ 0x1201 + i * 4 ] & 0x0f; |
| 637 | UINT8 spr_x = state->vram[ 0x1202 + i * 4 ] & 0xfe; |
| 638 | UINT8 x_32 = state->vram[ 0x1202 + i * 4 ] & 0x01; /* 32xX sprite */ |
| 639 | UINT8 tile_idx = state->vram[ 0x1203 + i * 4 ] & 0x7f; |
| 640 | UINT8 half = state->vram[ 0x1203 + i * 4] & 0x80; |
| 641 | 641 | UINT8 left = 1; |
| 642 | 642 | UINT8 right = 1; |
| 643 | 643 | UINT8 top = 1; |
| r9684 | r9685 | |
| 681 | 681 | } |
| 682 | 682 | |
| 683 | 683 | /* Check if 2 color sprites are enabled */ |
| 684 | | if ( ( scv_vram[0x1400] & 0x20 ) && ( i & 0x20 ) ) |
| 684 | if ( ( state->vram[0x1400] & 0x20 ) && ( i & 0x20 ) ) |
| 685 | 685 | { |
| 686 | 686 | /* 2 color sprite handling */ |
| 687 | | draw_sprite( bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip ); |
| 687 | draw_sprite( state, bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip ); |
| 688 | 688 | if ( x_32 || y_32 ) |
| 689 | 689 | { |
| 690 | 690 | static const UINT8 spr_2col_lut0[16] = { 0, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 1, 1 }; |
| 691 | 691 | static const UINT8 spr_2col_lut1[16] = { 0, 1, 8, 11, 2, 3, 10, 9, 4, 5, 12, 13, 6, 7, 14, 15 }; |
| 692 | 692 | |
| 693 | | draw_sprite( bitmap, spr_x, spr_y, tile_idx + 8 * x_32 + y_32, ( i & 0x40 ) ? spr_2col_lut1[col] : spr_2col_lut0[col], left, right, top, bottom, clip ); |
| 693 | draw_sprite( state, bitmap, spr_x, spr_y, tile_idx + 8 * x_32 + y_32, ( i & 0x40 ) ? spr_2col_lut1[col] : spr_2col_lut0[col], left, right, top, bottom, clip ); |
| 694 | 694 | } |
| 695 | 695 | } |
| 696 | 696 | else |
| 697 | 697 | { |
| 698 | 698 | /* regular sprite handling */ |
| 699 | | draw_sprite( bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip ); |
| 699 | draw_sprite( state, bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip ); |
| 700 | 700 | if ( x_32 ) |
| 701 | 701 | { |
| 702 | | draw_sprite( bitmap, spr_x + 16, spr_y, tile_idx + 8, col, 1, 1, top, bottom, clip ); |
| 702 | draw_sprite( state, bitmap, spr_x + 16, spr_y, tile_idx + 8, col, 1, 1, top, bottom, clip ); |
| 703 | 703 | } |
| 704 | 704 | if ( y_32 ) |
| 705 | 705 | { |
| 706 | 706 | clip &= 0x07; |
| 707 | | draw_sprite( bitmap, spr_x, spr_y + 16, tile_idx + 1, col, left, right, 1, 1, clip ); |
| 707 | draw_sprite( state, bitmap, spr_x, spr_y + 16, tile_idx + 1, col, left, right, 1, 1, clip ); |
| 708 | 708 | if ( x_32 ) |
| 709 | 709 | { |
| 710 | | draw_sprite( bitmap, spr_x + 16, spr_y + 16, tile_idx + 9, col, 1, 1, 1, 1, clip ); |
| 710 | draw_sprite( state, bitmap, spr_x + 16, spr_y + 16, tile_idx + 9, col, 1, 1, 1, 1, clip ); |
| 711 | 711 | } |
| 712 | 712 | } |
| 713 | 713 | } |