trunk/src/mess/drivers/mz3500.c
| r22048 | r22049 | |
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | |
| 3 | | Template for skeleton drivers |
| 3 | MZ-3500 (c) 198? Sharp |
| 4 | 4 | |
| 5 | preliminary driver by Angelo Salese |
| 6 | |
| 5 | 7 | ***************************************************************************/ |
| 6 | 8 | |
| 7 | 9 | |
| 8 | 10 | #include "emu.h" |
| 9 | 11 | #include "cpu/z80/z80.h" |
| 10 | 12 | //#include "sound/ay8910.h" |
| 13 | #include "video/upd7220.h" |
| 11 | 14 | |
| 12 | 15 | #define MAIN_CLOCK XTAL_8MHz |
| 13 | 16 | |
| r22048 | r22049 | |
| 17 | 20 | mz3500_state(const machine_config &mconfig, device_type type, const char *tag) |
| 18 | 21 | : driver_device(mconfig, type, tag), |
| 19 | 22 | m_master(*this, "master"), |
| 20 | | m_slave(*this, "slave") |
| 23 | m_slave(*this, "slave"), |
| 24 | m_hgdc1(*this, "upd7220_chr"), |
| 25 | m_hgdc2(*this, "upd7220_gfx"), |
| 26 | m_video_ram(*this, "video_ram") |
| 21 | 27 | { } |
| 22 | 28 | |
| 23 | 29 | // devices |
| 24 | 30 | required_device<cpu_device> m_master; |
| 25 | 31 | required_device<cpu_device> m_slave; |
| 32 | required_device<upd7220_device> m_hgdc1; |
| 33 | required_device<upd7220_device> m_hgdc2; |
| 34 | required_shared_ptr<UINT8> m_video_ram; |
| 26 | 35 | UINT8 *m_ipl_rom; |
| 27 | 36 | UINT8 *m_basic_rom; |
| 28 | 37 | UINT8 *m_work_ram; |
| 29 | 38 | UINT8 *m_shared_ram; |
| 39 | UINT8 *m_char_rom; |
| 30 | 40 | |
| 31 | 41 | UINT8 m_ma,m_mo,m_ms,m_me2,m_me1; |
| 42 | UINT8 m_crtc[0x10]; |
| 32 | 43 | |
| 33 | 44 | DECLARE_READ8_MEMBER(mz3500_master_mem_r); |
| 34 | 45 | DECLARE_WRITE8_MEMBER(mz3500_master_mem_w); |
| r22048 | r22049 | |
| 40 | 51 | DECLARE_WRITE8_MEMBER(mz3500_shared_ram_w); |
| 41 | 52 | DECLARE_READ8_MEMBER(mz3500_io_r); |
| 42 | 53 | DECLARE_WRITE8_MEMBER(mz3500_io_w); |
| 54 | DECLARE_WRITE8_MEMBER(mz3500_crtc_w); |
| 43 | 55 | |
| 44 | 56 | // screen updates |
| 45 | | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 57 | UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 46 | 58 | |
| 47 | 59 | protected: |
| 48 | 60 | // driver_device overrides |
| r22048 | r22049 | |
| 57 | 69 | { |
| 58 | 70 | } |
| 59 | 71 | |
| 60 | | UINT32 mz3500_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| 72 | /* |
| 73 | CRTC regs |
| 74 | [0] |
| 75 | ---- -x-- "Choice of whether attribute or cursor be put on the frame that displayed on CRT2" (whatever that means ...) |
| 76 | ---- --x- CRT2 output |
| 77 | ---- ---x CRT1 output |
| 78 | [1] |
| 79 | ---- -GRB CRT1 color output |
| 80 | [2] |
| 81 | ---- -GRB CRT2 color output |
| 82 | [3] |
| 83 | ---- -GRB background color output |
| 84 | [4] |
| 85 | ---- --x- border color mode in effect |
| 86 | ---- ---x color mode |
| 87 | [5] |
| 88 | ---- --x- width setting (0: 40 chars, 1: 80 chars) |
| 89 | ---- ---x data size for graphics RAM (0: 8 bits, 1: 16 bits) |
| 90 | [6] |
| 91 | ---- -x-- "Connection of graphic GDC" |
| 92 | ---- --x- "Connection of the 96K bytes VRAM" |
| 93 | ---- ---x "Connection of a 400 raster CRT" |
| 94 | [7] |
| 95 | ---- ---x 0: 25 lines, 1: 20 lines display |
| 96 | [d] |
| 97 | (mirror of [5]?) |
| 98 | */ |
| 99 | |
| 100 | static UPD7220_DISPLAY_PIXELS( hgdc_display_pixels ) |
| 61 | 101 | { |
| 102 | // ... |
| 103 | } |
| 104 | |
| 105 | static UPD7220_DRAW_TEXT_LINE( hgdc_draw_text ) |
| 106 | { |
| 107 | mz3500_state *state = device->machine().driver_data<mz3500_state>(); |
| 108 | const rgb_t *palette = palette_entry_list_raw(bitmap.palette()); |
| 109 | int x; |
| 110 | int xi,yi; |
| 111 | int tile; |
| 112 | int attr; |
| 113 | UINT8 tile_data; |
| 114 | UINT8 width80; |
| 115 | UINT8 char_size; |
| 116 | UINT8 hires; |
| 117 | |
| 118 | // popmessage("%02x",state->m_crtc[6]); |
| 119 | |
| 120 | width80 = (state->m_crtc[5] & 2) >> 1; |
| 121 | hires = (state->m_crtc[6] & 1); |
| 122 | char_size = (hires) ? 16 : 8; |
| 123 | |
| 124 | for( x = 0; x < pitch; x++ ) |
| 125 | { |
| 126 | tile = (state->m_video_ram[((addr+x)*2) & 0x1fff] & 0xff); |
| 127 | attr = (state->m_video_ram[((addr+x)*2+1) & 0x3ffff] & 0x0f); |
| 128 | |
| 129 | //if(hires) |
| 130 | // tile <<= 1; |
| 131 | |
| 132 | for( yi = 0; yi < lr; yi++) |
| 133 | { |
| 134 | tile_data = state->m_char_rom[((tile*16+yi) & 0xfff) | (hires*0x1000)]; |
| 135 | |
| 136 | for( xi = 0; xi < 8; xi++) |
| 137 | { |
| 138 | int res_x,res_y; |
| 139 | int pen; |
| 140 | |
| 141 | /* TODO: color attribute needs double check */ |
| 142 | |
| 143 | if(yi >= char_size) |
| 144 | pen = -1; |
| 145 | else |
| 146 | { |
| 147 | if(state->m_crtc[4] & 1) |
| 148 | pen = (tile_data >> (7-xi)) & 1 ? (attr >> 1) : -1; |
| 149 | else |
| 150 | pen = (tile_data >> (7-xi)) & 1 ? 7 : -1; |
| 151 | } |
| 152 | |
| 153 | res_x = x * 8 + xi; |
| 154 | res_y = y * lr + yi; |
| 155 | |
| 156 | if(pen != -1) |
| 157 | { |
| 158 | if(!width80) |
| 159 | { |
| 160 | bitmap.pix32(res_y, res_x*2+0) = palette[pen]; |
| 161 | bitmap.pix32(res_y, res_x*2+1) = palette[pen]; |
| 162 | } |
| 163 | else |
| 164 | bitmap.pix32(res_y, res_x) = palette[pen]; |
| 165 | } |
| 166 | } |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | } |
| 171 | |
| 172 | UINT32 mz3500_state::screen_update( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect ) |
| 173 | { |
| 174 | bitmap.fill(machine().pens[(m_crtc[4] & 2) ? m_crtc[3] & 7 : 0], cliprect); |
| 175 | |
| 176 | /* graphics */ |
| 177 | m_hgdc2->screen_update(screen, bitmap, cliprect); |
| 178 | m_hgdc1->screen_update(screen, bitmap, cliprect); |
| 62 | 179 | return 0; |
| 63 | 180 | } |
| 64 | 181 | |
| 182 | |
| 183 | |
| 184 | static UPD7220_INTERFACE( hgdc_1_intf ) |
| 185 | { |
| 186 | "screen", |
| 187 | NULL, |
| 188 | hgdc_draw_text, |
| 189 | DEVCB_NULL, |
| 190 | DEVCB_DEVICE_LINE_MEMBER("upd7220_gfx", upd7220_device, ext_sync_w), |
| 191 | DEVCB_NULL |
| 192 | }; |
| 193 | |
| 194 | static UPD7220_INTERFACE( hgdc_2_intf ) |
| 195 | { |
| 196 | "screen", |
| 197 | hgdc_display_pixels, |
| 198 | NULL, |
| 199 | DEVCB_NULL, |
| 200 | DEVCB_NULL, |
| 201 | DEVCB_NULL |
| 202 | }; |
| 203 | |
| 65 | 204 | READ8_MEMBER(mz3500_state::mz3500_ipl_r) |
| 66 | 205 | { |
| 67 | 206 | return m_ipl_rom[offset]; |
| r22048 | r22049 | |
| 262 | 401 | } |
| 263 | 402 | } |
| 264 | 403 | |
| 404 | WRITE8_MEMBER(mz3500_state::mz3500_crtc_w) |
| 405 | { |
| 406 | if(offset & 8) |
| 407 | { |
| 408 | if(offset == 0xd) |
| 409 | m_crtc[offset & 7] = data; |
| 410 | else |
| 411 | printf("CRTC register access %02x\n",offset); // probably just a mirror, but who knows ... |
| 412 | } |
| 413 | else |
| 414 | m_crtc[offset] = data; |
| 415 | } |
| 416 | |
| 265 | 417 | static ADDRESS_MAP_START( mz3500_master_map, AS_PROGRAM, 8, mz3500_state ) |
| 266 | 418 | AM_RANGE(0x0000, 0xffff) AM_READWRITE(mz3500_master_mem_r,mz3500_master_mem_w) |
| 267 | 419 | ADDRESS_MAP_END |
| r22048 | r22049 | |
| 273 | 425 | // AM_RANGE(0xec, 0xef) irq signal from slave to master CPU |
| 274 | 426 | // AM_RANGE(0xf4, 0xf7) MFD upd765 |
| 275 | 427 | // AM_RANGE(0xf8, 0xfb) MFD I/O port |
| 428 | AM_RANGE(0xf8, 0xf8) AM_READNOP // TODO |
| 276 | 429 | AM_RANGE(0xfc, 0xff) AM_READWRITE(mz3500_io_r,mz3500_io_w) // memory mapper |
| 277 | 430 | ADDRESS_MAP_END |
| 278 | 431 | |
| r22048 | r22049 | |
| 289 | 442 | // AM_RANGE(0x20, 0x2f) pit8253 |
| 290 | 443 | // AM_RANGE(0x30, 0x3f) i8255 |
| 291 | 444 | // AM_RANGE(0x40, 0x4f) 8-bit input port |
| 292 | | // AM_RANGE(0x50, 0x5f) CRTC |
| 293 | | // AM_RANGE(0x60, 0x6f) upd7220 gfx |
| 294 | | // AM_RANGE(0x70, 0x7f) upd7220 chr |
| 445 | AM_RANGE(0x50, 0x5f) AM_RAM_WRITE(mz3500_crtc_w) |
| 446 | AM_RANGE(0x60, 0x61) AM_DEVREADWRITE("upd7220_gfx", upd7220_device, read, write) |
| 447 | AM_RANGE(0x70, 0x71) AM_DEVREADWRITE("upd7220_chr", upd7220_device, read, write) |
| 295 | 448 | ADDRESS_MAP_END |
| 296 | 449 | |
| 297 | 450 | static INPUT_PORTS_START( mz3500 ) |
| r22048 | r22049 | |
| 350 | 503 | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 351 | 504 | INPUT_PORTS_END |
| 352 | 505 | |
| 353 | | static const gfx_layout charlayout = |
| 506 | static const gfx_layout charlayout_8x8 = |
| 354 | 507 | { |
| 355 | 508 | 8,8, |
| 356 | | RGN_FRAC(1,1), |
| 509 | 0x100, |
| 357 | 510 | 1, |
| 358 | 511 | { RGN_FRAC(0,1) }, |
| 359 | 512 | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 360 | 513 | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, |
| 361 | | 8*8 |
| 514 | 8*16 |
| 362 | 515 | }; |
| 363 | 516 | |
| 517 | |
| 518 | static const gfx_layout charlayout_8x16 = |
| 519 | { |
| 520 | 8,16, |
| 521 | 0x100, |
| 522 | 1, |
| 523 | { RGN_FRAC(0,1) }, |
| 524 | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 525 | { STEP16(0,8) }, |
| 526 | 8*16 |
| 527 | }; |
| 528 | |
| 364 | 529 | static GFXDECODE_START( mz3500 ) |
| 365 | | GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 1 ) |
| 530 | GFXDECODE_ENTRY( "gfx1", 0x0000, charlayout_8x8, 0, 1 ) |
| 531 | GFXDECODE_ENTRY( "gfx1", 0x0008, charlayout_8x8, 0, 1 ) |
| 532 | GFXDECODE_ENTRY( "gfx1", 0x1000, charlayout_8x16, 0, 1 ) |
| 366 | 533 | GFXDECODE_END |
| 367 | 534 | |
| 368 | 535 | |
| r22048 | r22049 | |
| 370 | 537 | { |
| 371 | 538 | m_ipl_rom = memregion("ipl")->base(); |
| 372 | 539 | m_basic_rom = memregion("basic")->base(); |
| 540 | m_char_rom = memregion("gfx1")->base(); |
| 373 | 541 | m_work_ram = auto_alloc_array_clear(machine(), UINT8, 0x40000); |
| 374 | 542 | m_shared_ram = auto_alloc_array_clear(machine(), UINT8, 0x800); |
| 375 | 543 | } |
| r22048 | r22049 | |
| 382 | 550 | m_mo = 0; |
| 383 | 551 | m_me1 = 0; |
| 384 | 552 | m_me2 = 0; |
| 385 | | m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 553 | //m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 386 | 554 | } |
| 387 | 555 | |
| 388 | 556 | |
| 389 | 557 | void mz3500_state::palette_init() |
| 390 | 558 | { |
| 559 | int i; |
| 560 | |
| 561 | for(i=0;i<8;i++) |
| 562 | palette_set_color_rgb(machine(), i,pal1bit((i >> 1) & 1),pal1bit(i >> 2),pal1bit((i >> 0) & 1)); |
| 563 | |
| 391 | 564 | } |
| 392 | 565 | |
| 566 | static ADDRESS_MAP_START( upd7220_1_map, AS_0, 8, mz3500_state ) |
| 567 | ADDRESS_MAP_GLOBAL_MASK(0x1fff) |
| 568 | AM_RANGE(0x00000, 0x1fff) AM_RAM AM_SHARE("video_ram") |
| 569 | ADDRESS_MAP_END |
| 570 | |
| 571 | static ADDRESS_MAP_START( upd7220_2_map, AS_0, 8, mz3500_state ) |
| 572 | AM_RANGE(0x00000, 0x3ffff) AM_RAM // AM_SHARE("video_ram_2") |
| 573 | ADDRESS_MAP_END |
| 574 | |
| 575 | /* TODO: clocks */ |
| 393 | 576 | static MACHINE_CONFIG_START( mz3500, mz3500_state ) |
| 394 | 577 | |
| 395 | 578 | /* basic machine hardware */ |
| r22048 | r22049 | |
| 401 | 584 | MCFG_CPU_PROGRAM_MAP(mz3500_slave_map) |
| 402 | 585 | MCFG_CPU_IO_MAP(mz3500_slave_io) |
| 403 | 586 | |
| 587 | MCFG_UPD7220_ADD("upd7220_chr", MAIN_CLOCK/5, hgdc_1_intf, upd7220_1_map) |
| 588 | MCFG_UPD7220_ADD("upd7220_gfx", MAIN_CLOCK/5, hgdc_2_intf, upd7220_2_map) |
| 589 | |
| 404 | 590 | /* video hardware */ |
| 405 | 591 | MCFG_SCREEN_ADD("screen", RASTER) |
| 406 | 592 | MCFG_SCREEN_REFRESH_RATE(60) |